/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef ISOPING_H
#define ISOPING_H

#include <map>
#include <netinet/in.h>
#include <openssl/evp.h>
#include <queue>
#include <random>
#include <stdint.h>
#include <string.h>
#include <sys/socket.h>

// Number of bytes required to store the cookie, which is a SHA-256 hash.
#define COOKIE_SIZE 32
// Number of bytes used to store the random cookie secret.
#define COOKIE_SECRET_SIZE 16

enum {
  PACKET_TYPE_ACK = 0,
  PACKET_TYPE_HANDSHAKE,
};

// Layout of the UDP packets exchanged between client and server.
// All integers are in network byte order.
// Packets have exactly the same structure in both directions.
struct Packet {
  uint32_t magic;     // magic number to reject bogus packets
  uint32_t id;        // sequential packet id number
  uint32_t txtime;    // transmitter's monotonic time when pkt was sent
  uint32_t clockdiff; // estimate of (transmitter's clk) - (receiver's clk)
  uint32_t usec_per_pkt; // microseconds of delay between packets
  uint32_t num_lost;  // number of pkts transmitter expected to get but didn't
  uint8_t packet_type; // 0 for acks, 1 for handshake packet
  uint8_t first_ack;  // starting index in acks[] circular buffer
  union {
    // Data used for handshake packets.
    struct {
      uint32_t version; // max version of the isoping protocol supported
      uint32_t cookie_epoch; // which cookie we're using
      unsigned char cookie[COOKIE_SIZE]; // actual cookie value
    } handshake;
    // Data used for ack packets.
    struct {
      // txtime==0 for empty elements in this array.
      uint32_t id;      // id field from a received packet
      uint32_t rxtime;  // receiver's monotonic time when pkt arrived
    } acks[64];
  } data;
};


// Data we track per session.
struct Session {
  Session(uint64_t first_send, uint32_t usec_per_pkt,
          const struct sockaddr_storage &remoteaddr, size_t remoteaddr_len);
  int32_t usec_per_pkt;
  int32_t usec_per_print;

  // The peer's address.
  struct sockaddr_storage remoteaddr;
  socklen_t remoteaddr_len;

  enum {
    NEW_SESSION = 0,     // No packets exchanged yet.
    HANDSHAKE_REQUESTED, // Client has sent initial packet to server, i.e. SYN.
    COOKIE_GENERATED,    // Server has replied with cookie, i.e. SYN|ACK.
    ESTABLISHED          // Client has echoed cookie back, i.e. ACK.
  } handshake_state;
  int handshake_retry_count;
  static const int handshake_timeout_usec = 1000000;

  // WARNING: lots of math below relies on well-defined uint32/int32
  // arithmetic overflow behaviour, plus the fact that when we subtract
  // two successive timestamps (for example) they will be less than 2^31
  // microseconds apart.  It would be safer to just use 64-bit values
  // everywhere, but that would cut the number of acks-per-packet in half,
  // which would be unfortunate.
  uint32_t next_tx_id;       // id field for next transmit
  uint32_t next_rx_id;       // expected id field for next receive
  uint32_t next_rxack_id;    // expected ack.id field in next received ack
  uint32_t start_rtxtime;    // remote's txtime at startup
  uint64_t start_rxtime;     // local rxtime at startup
  uint32_t last_rxtime;      // local rxtime of last received packet
  int32_t min_cycle_rxdiff;  // smallest packet delay seen this cycle
  uint32_t next_cycle;       // time when next cycle begins
  uint64_t next_send;        // time when we'll send next pkt
  uint32_t num_lost;         // number of rx packets not received
  int next_txack_index;      // next array item to fill in tx.acks
  struct Packet tx, rx;      // transmit and received packet buffers
  char last_ackinfo[128];    // human readable format of latest ack
  uint32_t last_print;       // time of last packet printout
  // Packet statistics counters for transmit and receive directions.
  long long lat_tx, lat_tx_min, lat_tx_max,
      lat_tx_count, lat_tx_sum, lat_tx_var_sum;
  long long lat_rx, lat_rx_min, lat_rx_max,
      lat_rx_count, lat_rx_sum, lat_rx_var_sum;
};

// Comparator for use with sockaddr_in and sockaddr_in6 values.  Sorts by
// address family first, then on the IPv4/6 address, then the port number.
struct CompareSockaddr {
  bool operator()(const struct sockaddr_storage &lhs,
                  const struct sockaddr_storage &rhs);
};

typedef std::map<struct sockaddr_storage, Session, CompareSockaddr>
    SessionMap;

// Compares the next_send values of each referenced Session, sorting the earlier
// timestamps first.
struct CompareNextSend {
  bool operator()(const SessionMap::iterator &lhs,
                  const SessionMap::iterator &rhs);
};

class Sessions {
 public:
  Sessions();
  ~Sessions();

  // Rotates the cookie secrets if they haven't been changed in a while.
  virtual void MaybeRotateCookieSecrets(uint64_t now, int is_server);

  // Rotate the cookie secrets using the given epoch directly.  Only for use in
  // unit tests.
  void RotateCookieSecrets(uint32_t new_epoch);

  // Calculates a handshake cookie based on the provided client IP address and
  // the relevant parameters in p, using the current cookie secret, and places
  // the result in p.
  bool CalculateCookie(Packet *p, struct sockaddr_storage *remoteaddr,
                       size_t remoteaddr_len);

  // Returns true if the packet contains a handshake packet with a valid cookie.
  virtual bool ValidateCookie(Packet *p, struct sockaddr_storage *addr,
                              socklen_t addr_len);

  SessionMap::iterator NewSession(uint64_t first_send,
                                  uint32_t usec_per_pkt,
                                  struct sockaddr_storage *addr,
                                  socklen_t addr_len);

  uint64_t next_send_time() {
    if (next_sends.size() == 0) {
      return 0;
    }
    return next_sends.top()->second.next_send;
  }

  // All active sessions, indexed by remote address/port.
  SessionMap session_map;
  // A queue of upcoming send times, ordered most recent first, referencing
  // entries in the session map.
  std::priority_queue<SessionMap::iterator, std::vector<SessionMap::iterator>,
      CompareNextSend> next_sends;

 protected:
  void NewRandomCookieSecret();
  bool CalculateCookieWithSecret(Packet *p, struct sockaddr_storage *remoteaddr,
                                 size_t remoteaddr_len, unsigned char *secret,
                                 size_t secret_len);

  // Fields required for calculating and verifying cookies.
  EVP_MD_CTX digest_context;
  const EVP_MD *md;
  std::mt19937_64 rng;
  uint32_t cookie_epoch;
  uint32_t last_secret_update_time;
  unsigned char cookie_secret[COOKIE_SECRET_SIZE];
  uint32_t prev_cookie_epoch;
  unsigned char prev_cookie_secret[COOKIE_SECRET_SIZE];
};

// Process an incoming packet from the socket.
void handle_packet(struct Sessions *s, struct Session *session, Packet *rx,
                   int sock, struct sockaddr_storage *rxaddr,
                   socklen_t rxaddr_len, uint64_t now, int is_server);

// Process an established Session's incoming ack packet, from s->rx.
void handle_ack_packet(struct Session *s, uint64_t now);

// Server-only: processes a handshake packet from a new client in rx. Replies
// with a cookie if no cookie provided, or validates the provided cookie and
// establishes a new Session.
void handle_new_client_handshake_packet(Sessions *s, Packet *rx, int sock,
                                       struct sockaddr_storage *remoteaddr,
                                       size_t remoteaddr_len, uint64_t now);

// Client-only: processes a handshake packet received from the server.
// Configures the Session to echo the provided cookie back to the server.
void handle_server_handshake_packet(Sessions *s, Packet *rx, uint64_t now);

// Sets all the elements of s->tx to be ready to be sent to the other side.
void prepare_tx_packet(struct Session *s);

// Sends a packet to all waiting sessions where the appropriate amount of time
// has passed.
int send_waiting_packets(Sessions *s, int sock, uint64_t now, int is_server);

// Sends a packet from the given session to the given socket immediately.
int send_packet(struct Session *s, int sock, int is_server);

// Reads a packet from sock and stores it in s->rx.  Assumes a packet is
// currently readable.
int read_incoming_packet(Sessions *s, int sock, uint64_t now, int is_server);

// Sets the global packets_per_sec value.  Used for test purposes only.
void set_packets_per_sec(double new_pps);

// Parses arguments and runs the main loop.  Distinct from main() for unit test
// and fuzz test purposes.  extrasock is an additional socket to read from, used
// for tests.  Set to -1 if unused.
int isoping_main(int argc, char **argv, Sessions *sessions, int extrasock);

#endif
