/*
 * Copyright 2014 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.
 */

/*
 *
 * Like ping, but sends packets isochronously (equally spaced in time) in
 * each direction.  By being clever, we can use the known timing of each
 * packet to determine, on a noisy network, which direction is dropping or
 * delaying packets and by how much.
 *
 * Also unlike ping, this requires a server (ie. another copy of this
 * program) to be running on the remote end.
 */
#include "isoping.h"

#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <memory.h>
#include <netdb.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#ifndef CLOCK_MONOTONIC_RAW
#define CLOCK_MONOTONIC_RAW 4
#endif

#define MAGIC 0x424c4950
#define SERVER_PORT 4948
#define DEFAULT_PACKETS_PER_SEC 10.0
#define DEFAULT_TTL 2

// A 'cycle' is the amount of time we can assume our calibration between
// the local and remote monotonic clocks is reasonably valid.  It seems
// some of our devices have *very* fast clock skew (> 1 msec/minute) so
// this unfortunately has to be much shorter than I'd like.  This may
// reflect actual bugs in our ntpd and/or the kernel's adjtime()
// implementation.  In particular, we shouldn't have to do this kind of
// periodic correction, because that's what adjtime() *is*.  But the results
// are way off without this.
#define USEC_PER_CYCLE (10*1000*1000)

#define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0]))
#define DIFF(x, y) ((int32_t)((uint32_t)(x) - (uint32_t)(y)))
#define DIV(x, y) ((y) ? ((double)(x)/(y)) : 0)
#define _STR(n) #n
#define STR(n) _STR(n)
#ifdef DEBUG
#define DLOG(args...) fprintf(stderr, args)
#else
#define DLOG(args...)
#endif

// Global flag values.
int quiet = 0;
int ttl = DEFAULT_TTL;
int want_timestamps = 0;
double packets_per_sec = DEFAULT_PACKETS_PER_SEC;
double prints_per_sec = -1.0;

int want_to_die;


static void sighandler(int sig) {
  want_to_die = 1;
}

// Render the given sockaddr as a string.  (Uses a static internal buffer
// which is overwritten each time.)
static const char *sockaddr_to_str(struct sockaddr *sa) {
  static char addrbuf[128];
  void *aptr;

  switch (sa->sa_family) {
  case AF_INET:
    aptr = &((struct sockaddr_in *)sa)->sin_addr;
    break;
  case AF_INET6:
    aptr = &((struct sockaddr_in6 *)sa)->sin6_addr;
    break;
  default:
    return "unknown";
  }

  if (!inet_ntop(sa->sa_family, aptr, addrbuf, sizeof(addrbuf))) {
    perror("inet_ntop");
    exit(98);
  }
  return addrbuf;
}

static void debug_print_hex(unsigned char *data, size_t data_len) {
  for (size_t i = 0; i < data_len; i++) {
    DLOG("%02x", data[i]);
    if (i % 8 == 7) {
      DLOG(" ");
    }
  }
  DLOG("\n");
}

Session::Session(uint32_t first_send, uint32_t usec_per_pkt,
                 const struct sockaddr_storage &raddr, size_t raddr_len)
    : usec_per_pkt(usec_per_pkt),
      usec_per_print(prints_per_sec > 0 ? 1e6 / prints_per_sec : 0),
      remoteaddr_len(raddr_len),
      handshake_state(NEW_SESSION),
      handshake_retry_count(0),
      next_tx_id(1),
      next_rx_id(0),
      next_rxack_id(0),
      start_rtxtime(0),
      start_rxtime(0),
      last_rxtime(0),
      min_cycle_rxdiff(0),
      next_cycle(0),
      next_send(first_send),
      num_lost(0),
      next_txack_index(0),
      last_print(first_send - usec_per_pkt),
      lat_tx(0), lat_tx_min(0x7fffffff), lat_tx_max(0),
      lat_tx_count(0), lat_tx_sum(0), lat_tx_var_sum(0),
      lat_rx(0), lat_rx_min(0x7fffffff), lat_rx_max(0),
      lat_rx_count(0), lat_rx_sum(0), lat_rx_var_sum(0) {
  memcpy(&remoteaddr, &raddr, raddr_len);
  memset(&tx, 0, sizeof(tx));
  strcpy(last_ackinfo, "");
  DLOG("Handshake state: NEW_SESSION\n");
}

SessionMap::iterator Sessions::NewSession(uint32_t first_send,
                                          uint32_t usec_per_pkt,
                                          struct sockaddr_storage *addr,
                                          socklen_t addr_len) {
  std::pair<SessionMap::iterator, bool> p = session_map.insert(std::make_pair(
      *addr, Session(first_send, usec_per_pkt, *addr, addr_len)));
  next_sends.push(p.first);
  return p.first;
}

bool Sessions::CalculateCookie(Packet *p, struct sockaddr_storage *remoteaddr,
                               size_t remoteaddr_len) {
  return CalculateCookieWithSecret(p, remoteaddr, remoteaddr_len,
                                   cookie_secret, sizeof(cookie_secret));
}

bool Sessions::CalculateCookieWithSecret(Packet *p,
                                         struct sockaddr_storage *remoteaddr,
                                         size_t remoteaddr_len,
                                         unsigned char *secret,
                                         size_t secret_len) {
  if (p->packet_type != PACKET_TYPE_HANDSHAKE) {
    fprintf(stderr, "Tried to create cookie for a non-handshake packet\n");
    return false;
  }
  if (!EVP_DigestInit_ex(&digest_context, md, NULL)) {
    fprintf(stderr, "Unable to initialize hash digest\n");
    return false;
  }

  // Hash the data
  EVP_DigestUpdate(&digest_context, secret, secret_len);
  EVP_DigestUpdate(&digest_context, &p->usec_per_pkt, sizeof(p->usec_per_pkt));
  EVP_DigestUpdate(&digest_context, remoteaddr, remoteaddr_len);

  unsigned int digest_size = 0;
  EVP_DigestFinal_ex(&digest_context, p->data.handshake.cookie, &digest_size);
  if (digest_size != COOKIE_SIZE) {
    fprintf(stderr, "Invalid digest size %d for cookie; expected %d\n",
            digest_size, COOKIE_SIZE);
    return false;
  }
  p->data.handshake.cookie_epoch = cookie_epoch;
  return true;
}

bool Sessions::ValidateCookie(Packet *p, struct sockaddr_storage *addr,
                              socklen_t addr_len) {
  if (p->data.handshake.cookie_epoch != cookie_epoch &&
      p->data.handshake.cookie_epoch != prev_cookie_epoch) {
    fprintf(stderr, "Obsolete cookie epoch: %d\n",
            p->data.handshake.cookie_epoch);
    return false;
  }
  Packet golden;
  golden.packet_type = PACKET_TYPE_HANDSHAKE;
  golden.usec_per_pkt = p->usec_per_pkt;
  if (p->data.handshake.cookie_epoch == cookie_epoch) {
    CalculateCookieWithSecret(&golden, addr, addr_len, cookie_secret,
                              sizeof(cookie_secret));
  } else {
    CalculateCookieWithSecret(&golden, addr, addr_len, prev_cookie_secret,
                              sizeof(prev_cookie_secret));
  }
  DLOG("Handshake: cookie epoch=%d, cookie=0x",
       p->data.handshake.cookie_epoch);
  debug_print_hex(p->data.handshake.cookie, sizeof(p->data.handshake.cookie));
  DLOG("Expected handshake: cookie epoch=%d, cookie=0x",
       golden.data.handshake.cookie_epoch);
  debug_print_hex(golden.data.handshake.cookie,
                  sizeof(golden.data.handshake.cookie));
  if (memcmp(golden.data.handshake.cookie, p->data.handshake.cookie,
             COOKIE_SIZE)) {
    fprintf(stderr, "Invalid cookie in handshake packet from %s\n",
            sockaddr_to_str((struct sockaddr *)addr));
    return false;
  }
  return true;
}

void Sessions::MaybeRotateCookieSecrets() {
  // Round off the unix timestamp to 64 seconds as an epoch, so we don't have to
  // track which ones we've already used.
  uint32_t new_epoch = time(NULL) >> 6;
  if (new_epoch != cookie_epoch) {
    RotateCookieSecrets(new_epoch);
  }
}

void Sessions::RotateCookieSecrets(uint32_t new_epoch) {
  prev_cookie_epoch = cookie_epoch;
  memcpy(&prev_cookie_secret[0], &cookie_secret[0],
         sizeof(prev_cookie_secret));
  cookie_epoch = new_epoch;
  NewRandomCookieSecret();
}

void Sessions::NewRandomCookieSecret() {
  uint64_t random;
  for (size_t i = 0; i < sizeof(cookie_secret); i += sizeof(random)) {
    random = rng();
    memcpy(&cookie_secret[i], &random,
           std::min(sizeof(random), sizeof(cookie_secret) - i));
  }
  DLOG("Generated new cookie secret.\n");
}

// Returns the kernel monotonic timestamp in microseconds, truncated to
// 32 bits.  That will wrap around every ~4000 seconds, which is okay
// for our purposes.  We use 32 bits to save space in our packets.
// This function never returns the value 0; it returns 1 instead, so that
// 0 can be used as a magic value.
#ifdef __MACH__  // MacOS X doesn't have clock_gettime()
#include <mach/mach.h>
#include <mach/mach_time.h>

static uint64_t ustime64(void) {
  static mach_timebase_info_data_t timebase;
  if (!timebase.denom) mach_timebase_info(&timebase);
  uint64_t result = (mach_absolute_time() * timebase.numer /
                     timebase.denom / 1000);
  return !result ? 1 : result;
}
#else
static uint64_t ustime64(void) {
  // CLOCK_MONOTONIC_RAW, when available, is not subject to NTP speed
  // adjustments while CLOCK_MONOTONIC is.  You might expect NTP speed
  // adjustments to make things better if we're trying to sync timings
  // between two machines, but at least our ntpd is pretty bad at making
  // adjustments, so it tends the vary the speed wildly in order to kind
  // of oscillate around the right time.  Experimentally, CLOCK_MONOTONIC_RAW
  // creates less trouble for isoping's use case.
  struct timespec ts;
  if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) < 0) {
    if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) {
      perror("clock_gettime");
      exit(98); // really should never happen, so don't try to recover
    }
  }
  uint64_t result = ts.tv_sec * 1000000LL + ts.tv_nsec / 1000;
  return !result ? 1 : result;
}
#endif


static uint32_t ustime(void) {
  return (uint32_t)ustime64();
}


static void usage_and_die(char *argv0) {
  fprintf(stderr,
          "\n"
          "Usage: %s                          (server mode)\n"
          "   or: %s <server-hostname-or-ip>  (client mode)\n"
          "\n"
          "      -f <lines/sec>  max output lines per second\n"
          "      -r <pps>        packets per second (default=%g)\n"
          "      -t <ttl>        packet ttl to use (default=2 for safety)\n"
          "      -q              quiet mode (don't print packets)\n"
          "      -T              print timestamps\n",
          argv0, argv0, (double)DEFAULT_PACKETS_PER_SEC);
  exit(99);
}


bool CompareSockaddr::operator()(const struct sockaddr_storage &lhs,
                                 const struct sockaddr_storage &rhs) {
  if (lhs.ss_family != rhs.ss_family) {
    return lhs.ss_family < rhs.ss_family;
  }
  if (lhs.ss_family == AF_INET) {
    const struct sockaddr_in &lhs4 = *(const struct sockaddr_in*)&lhs;
    const struct sockaddr_in &rhs4 = *(const struct sockaddr_in*)&rhs;
    long long c = (ntohl(lhs4.sin_addr.s_addr) - ntohl(rhs4.sin_addr.s_addr));
    if (c == 0) {
      return ntohs(lhs4.sin_port) < ntohs(rhs4.sin_port);
    }
    return c < 0;
  } else {
    const struct sockaddr_in6 &lhs6 = *(const struct sockaddr_in6*)&lhs;
    const struct sockaddr_in6 &rhs6 = *(const struct sockaddr_in6*)&rhs;
    int c = memcmp(&lhs6.sin6_addr, &rhs6.sin6_addr, sizeof(struct in6_addr));
    if (c == 0) {
      return ntohs(lhs6.sin6_port) < ntohs(rhs6.sin6_port);
    }
    return c < 0;
  }
}

bool CompareNextSend::operator()(const SessionMap::iterator &lhs,
                                 const SessionMap::iterator &rhs) {
  return lhs->second.next_send > rhs->second.next_send;
}

// Print the timestamp corresponding to the current time.
// Deliberately the same format as tcpdump uses, so we can easily sort and
// correlate messages between isoping and tcpdump.
static void print_timestamp(uint32_t when) {
  uint64_t now = ustime64();
  int32_t nowdiff = DIFF(now, when);
  uint64_t when64 = now - nowdiff;
  time_t t = when64 / 1000000;
  struct tm tm;
  memset(&tm, 0, sizeof(tm));
  localtime_r(&t, &tm);
  printf("%02d:%02d:%02d.%06d ", tm.tm_hour, tm.tm_min, tm.tm_sec,
         (int)(when64 % 1000000));
}


static double onepass_stddev(long long sumsq, long long sum, long long count) {
  // Incremental standard deviation calculation, without needing to know the
  // mean in advance.  See:
  // http://mathcentral.uregina.ca/QQ/database/QQ.09.02/carlos1.html
  long long numer = (count * sumsq) - (sum * sum);
  long long denom = count * (count - 1);
  return sqrt(DIV(numer, denom));
}

static void debug_print_packet(Packet *p) {
  DLOG("Packet contents: magic=0x%x id=%d usec_per_pkt=%d txtime=%u "
       "clockdiff=%d num_lost=%d first_ack=%d type=%d\n",
       ntohl(p->magic), ntohl(p->id), ntohl(p->usec_per_pkt),
       ntohl(p->txtime), ntohl(p->clockdiff), ntohl(p->num_lost),
       p->first_ack, p->packet_type);
  if (p->packet_type == PACKET_TYPE_HANDSHAKE) {
    DLOG("cookie epoch=%u, cookie=0x", p->data.handshake.cookie_epoch);
    debug_print_hex(p->data.handshake.cookie, sizeof(p->data.handshake.cookie));
  } else {
    DLOG("Acks:\n");
    for (uint32_t i = 0; i < ARRAY_LEN(p->data.acks); i++) {
      uint32_t acki = (p->first_ack + i) % ARRAY_LEN(p->data.acks);
      uint32_t ackid = ntohl(p->data.acks[acki].id);
      if (!ackid) continue;  // empty slot
      DLOG(" acki=%d id=%d rxtime=%u\n",
           acki, ackid, ntohl(p->data.acks[acki].rxtime));
    }
  }
}

void prepare_tx_packet(struct Session *s) {
  s->tx.magic = htonl(MAGIC);
  s->tx.id = htonl(s->next_tx_id++);
  s->tx.usec_per_pkt = htonl(s->usec_per_pkt);
  s->tx.txtime = htonl(s->next_send);
  s->tx.clockdiff = s->start_rtxtime ?
      htonl(s->start_rxtime - s->start_rtxtime) : 0;
  s->tx.num_lost = htonl(s->num_lost);
  s->tx.first_ack = s->next_txack_index;
  switch (s->handshake_state) {
    case Session::NEW_SESSION:
    case Session::HANDSHAKE_REQUESTED:
    case Session::COOKIE_GENERATED:
      DLOG("prepare_tx_packet: Sending handshake packet\n");
      s->tx.packet_type = PACKET_TYPE_HANDSHAKE;
      break;
    case Session::ESTABLISHED:
      s->tx.packet_type = PACKET_TYPE_ACK;
      break;
    default:
      fprintf(stderr, "Unknown handshake state %d\n", s->handshake_state);
      exit(2);
  }
  // note: tx.data.acks[] is filled in incrementally; we just transmit the
  // current state of it here.  The reason we keep a list of the most recent
  // acks is in case our packet gets lost, so the receiver will have more
  // chances to receive the timing information for the packets it sent us.
  debug_print_packet(&s->tx);
}


void prepare_handshake_reply_packet(Packet *tx, Packet *rx, uint32_t now) {
  memset(tx, 0, sizeof(*tx));
  tx->magic = htonl(MAGIC);
  tx->id = rx->id;
  // TODO(pmccurdy): Establish limits on the allowed usec_per_pkt values here
  tx->usec_per_pkt = rx->usec_per_pkt;
  tx->txtime = now;
  tx->clockdiff = htonl(now - ntohl(rx->txtime));
  tx->num_lost = htonl(0);
  tx->packet_type = PACKET_TYPE_HANDSHAKE;
}


int send_packet(struct Session *s, int sock, int is_server) {
  if (is_server) {
    if (sendto(sock, &s->tx, sizeof(s->tx), 0,
               (struct sockaddr *)&s->remoteaddr, s->remoteaddr_len) < 0) {
      perror("sendto");
    }
  } else {
    DLOG("Calling send on socket %d, size=%ld\n", sock, sizeof(s->tx));
    if (send(sock, &s->tx, sizeof(s->tx), 0) < 0) {
      int e = errno;
      perror("send");
      if (e == ECONNREFUSED) return 2;
    }
  }
  if (is_server ||
      s->handshake_state == Session::ESTABLISHED ||
      s->handshake_state == Session::COOKIE_GENERATED) {
    DLOG("send_packet: ack packet, next_send in %d (from %d to %d)\n",
         s->usec_per_pkt, s->next_send, s->next_send + s->usec_per_pkt);
    s->next_send += s->usec_per_pkt;
  } else {
    // Handle resending handshake packets from the client.  If they get lost
    // before we get a valid cookie from the server, the server won't know about
    // us, and our normal retry procedure would get us out of sync.
    if (s->handshake_state == Session::NEW_SESSION) {
      DLOG("Handshake state: sending handshake packet, moving to "
           "HANDSHAKE_REQUESTED\n");
      s->handshake_state = Session::HANDSHAKE_REQUESTED;
      s->handshake_retry_count = 0;
    } else {
      s->handshake_retry_count++;
    }
    // Limit the backoff to a factor of 2^10.
    uint32_t timeout = Session::handshake_timeout_usec *
                       (1 << std::min(10, s->handshake_retry_count));
    DLOG("Sending handshake, retries=%d, next_send in %d us (from %u to %u)\n",
         s->handshake_retry_count, timeout, s->next_send,
         s->next_send + timeout);
    s->next_send += timeout;
    // Don't count the handshake packet as part of the sequence.
    s->next_tx_id--;
  }
  return 0;
}

int send_waiting_packets(Sessions *sessions, int sock, uint32_t now,
                         int is_server) {
  if (sessions == NULL) {
    return -1;
  }
  // TODO(pmccurdy): This will incorrectly send packets too early during the
  // time period where now + usec_per_pkt wraps around, i.e. about once per 71
  // minutes, and will end up blasting packets as fast as possible for that
  // duration.  Consider calculating next_send and now as 64-bit values, and
  // truncating to 32 bits when transmitting.
  while (sessions->next_sends.size() > 0 &&
         DIFF(now, sessions->next_send_time()) >= 0) {
    SessionMap::iterator it = sessions->next_sends.top();
    sessions->next_sends.pop();
    Session &s = it->second;
    prepare_tx_packet(&s);
    int err = send_packet(&s, sock, is_server);
    if (err != 0) {
      return err;
    }
    // TODO(pmccurdy): Detect connection refused on a per-client basis.  Use
    // recvmsg with the MSG_ERRQUEUE flag to get error and client address,
    // instead of waiting for timeout.
    // TODO(pmccurdy): Support very low packet-per-second values, e.g. one
    // packet per hour, without constantly disconnecting the client.
    // TODO(pmccurdy): Instead of a fixed timeout, evict clients if they miss
    // a certain number of expected transmissions, that number changing based on
    // the number of packets they've already sent.
    if (is_server && DIFF(now, s.last_rxtime) > 60 * 1000 * 1000) {
      fprintf(stderr, "client %s disconnected.\n",
              sockaddr_to_str((struct sockaddr *)&s.remoteaddr));
      sessions->session_map.erase(s.remoteaddr);
    } else {
      sessions->next_sends.push(it);
    }
  }
  return 0;
}

int read_incoming_packet(Sessions *s, int sock, uint32_t now, int is_server) {
  struct sockaddr_storage rxaddr;
  socklen_t rxaddr_len = sizeof(rxaddr);

  Packet rx;
  ssize_t got = recvfrom(sock, &rx, sizeof(rx), 0,
                         (struct sockaddr *)&rxaddr, &rxaddr_len);
  if (got < 0) {
    int e = errno;
    perror("recvfrom");
    return e;
  }
  if (got != sizeof(rx) || rx.magic != htonl(MAGIC)) {
    fprintf(stderr, "got invalid packet of length %ld, magic=%d from %s\n",
            (long)got, ntohl(rx.magic),
            sockaddr_to_str((struct sockaddr *)&rxaddr));
    return EINVAL;
  }
  switch (rx.packet_type) {
    case PACKET_TYPE_HANDSHAKE:
    case PACKET_TYPE_ACK:
      break;
    default:
      fprintf(stderr, "received unknown packet type %d\n", rx.packet_type);
      return EINVAL;
  }

  Session *session = NULL;
  if (is_server) {
    SessionMap::iterator it = s->session_map.find(rxaddr);
    if (it != s->session_map.end()) {
      session = &it->second;
    } else {
      // Note: we don't want to allocate any memory here until the client has
      // completed the handshake.
      if (rx.packet_type != PACKET_TYPE_HANDSHAKE) {
        fprintf(stderr, "Received non-handshake packet from unknown client\n");
        // TODO(pmccurdy): Reply with a new handshake packet, including a
        // cookie; we may have dropped a legit client and we need to tell them
        // to renegotiate.
        return -1;
      }
    }
  } else {
    SessionMap::iterator it = s->session_map.begin();
    if (it == s->session_map.end()) {
      fprintf(stderr, "No session configured for %s when receiving packet\n",
              sockaddr_to_str((struct sockaddr *)&rxaddr));
      return EINVAL;
    }
    DLOG("read_incoming_packet: Client received %s packet from server\n",
         rx.packet_type == PACKET_TYPE_ACK ? "ack" : "handshake");
    session = &it->second;
  }
  handle_packet(s, session, &rx, sock, &rxaddr, rxaddr_len, now, is_server);

  return 0;
}

// Checks what kind of packet we've received, and processes it appropriately.
// Session may be null if we're dealing with a handshake packet for a new
// connection.
void handle_packet(struct Sessions *s, struct Session *session, Packet *rx,
                   int sock, struct sockaddr_storage *rxaddr,
                   socklen_t rxaddr_len, uint32_t now, int is_server) {
  switch (rx->packet_type) {
    case PACKET_TYPE_HANDSHAKE:
      if (is_server) {
        handle_new_client_handshake_packet(s, rx, sock, rxaddr, rxaddr_len,
                                           now);
        return;
      } else {
        DLOG("Client received handshake packet from server\n");
        handle_server_handshake_packet(s, rx, now);
        return;
      }
      break;
    case PACKET_TYPE_ACK:
      if (session != NULL) {
        memcpy(&session->rx, rx, sizeof(session->rx));
        if (!is_server &&
            session->handshake_state == Session::COOKIE_GENERATED) {
          // Now we know the server has accepted our connection.  Clear out the
          // handshake data from the send buffer and prepare to track acks.
          DLOG("Ack from server on new connection; moving to state "
               "ESTABLISHED.");
          session->handshake_state = Session::ESTABLISHED;
          memset(&session->tx.data.acks, 0, sizeof(session->tx.data.acks));
        }
      }
      handle_ack_packet(session, now);
      break;
    default:
      fprintf(stderr, "handle_packet called for unknown packet type %d\n",
              rx->packet_type);
      break;
  }
}

void handle_new_client_handshake_packet(Sessions *s, Packet *rx, int sock,
                                       struct sockaddr_storage *remoteaddr,
                                       size_t remoteaddr_len, uint32_t now) {
  assert(s != NULL);
  assert(rx != NULL);
  assert(remoteaddr != NULL);
  DLOG("Server received handshake packet from client; cookie epoch=%u\n",
       rx->data.handshake.cookie_epoch);
  if (rx->data.handshake.cookie_epoch == 0) {
    // New connection with no cookie.  Return a cookie to validate the client.
    s->session_map.erase(*remoteaddr);
    fprintf(stderr, "New connection from %s, sending cookie\n",
            sockaddr_to_str((struct sockaddr *)remoteaddr));
    Packet tx;
    memset(&tx, 0, sizeof(tx));
    prepare_handshake_reply_packet(&tx, rx, now);
    s->CalculateCookie(&tx, remoteaddr, remoteaddr_len);
    sendto(sock, &tx, sizeof(tx), 0, (struct sockaddr *)remoteaddr,
           remoteaddr_len);
    // The handshake_state is conceptually in the COOKIE_GENERATED state now,
    // but the whole point of the cookie is to avoid saving state in the server,
    // so we don't store a Session here.
  } else {
    // Cookie provided, validate it to accept or reject the connection.
    if (!s->ValidateCookie(rx, remoteaddr, remoteaddr_len)) {
      return;
    }
    fprintf(stderr, "New client connection: %s\n",
            sockaddr_to_str((struct sockaddr *)remoteaddr));
    SessionMap::iterator it = s->NewSession(
        now + 10 * 1000, ntohl(rx->usec_per_pkt), remoteaddr, remoteaddr_len);
    Session &session = it->second;
    session.handshake_state = Session::ESTABLISHED;
    memcpy(&session.rx, rx, sizeof(session.rx));
    // This is a new session we haven't sent any timing packets on, so the
    // client can't possibly have acknowledged any packets.  Replace the
    // handshake data with a set of empty acks and process as normal.
    session.rx.packet_type = PACKET_TYPE_ACK;
    memset(&session.rx.data.acks, 0, sizeof(session.rx.data.acks));
    assert(sizeof(session.rx.data.acks) > sizeof(void *));
    handle_ack_packet(&session, now);
  }
}

void handle_server_handshake_packet(Sessions *s, Packet *rx, uint32_t now) {
  assert(s != NULL);
  assert(rx != NULL);
  assert(s->session_map.size() == 1);
  assert(s->next_sends.size() == 1);

  SessionMap::iterator it = s->session_map.begin();
  Session &session = it->second;
  // We don't need to resend the handshake packet any more.
  s->next_sends.pop();

  session.tx.packet_type = PACKET_TYPE_HANDSHAKE;
  session.tx.data.handshake.cookie_epoch = rx->data.handshake.cookie_epoch;
  memcpy(&session.tx.data.handshake.cookie, &rx->data.handshake.cookie,
         COOKIE_SIZE);
  int usec_per_pkt = ntohl(rx->usec_per_pkt);
  if (usec_per_pkt != session.usec_per_pkt) {
    fprintf(stderr, "Server overrode packets per second to %f\n",
            1000000.0 / usec_per_pkt);
    session.usec_per_pkt = usec_per_pkt;
  }
  DLOG("Handshake state: client received cookie from server, moving to "
       "COOKIE_GENERATED; next_send=%d (was %d)\n",
       now, session.next_send);
  DLOG("Handshake: cookie epoch=%d, cookie=0x",
       rx->data.handshake.cookie_epoch);
  debug_print_hex(rx->data.handshake.cookie, sizeof(rx->data.handshake.cookie));
  session.handshake_state = Session::COOKIE_GENERATED;
  session.next_send = now;
  s->next_sends.push(it);
}

void handle_ack_packet(struct Session *s, uint32_t now) {
  assert(s != NULL);
  assert(s->rx.packet_type == PACKET_TYPE_ACK);
  // process the incoming packet header.
  // Most of the complexity here comes from the fact that the remote
  // system's clock will be skewed vs. ours.  (We use CLOCK_MONOTONIC
  // instead of CLOCK_REALTIME, so unless we figure out the skew offset,
  // it's essentially meaningless to compare the two values.)  We can
  // however assume that both clocks are ticking at 1 microsecond per
  // tick... except for inevitable clock rate errors, which we have to
  // account for occasionally.

  uint32_t txtime = ntohl(s->rx.txtime), rxtime = now;
  uint32_t id = ntohl(s->rx.id);
  if (!s->next_rx_id) {
    // The remote txtime is told to us by the sender, so it is always perfectly
    // correct... but it uses the sender's clock.
    s->start_rtxtime = txtime - id * s->usec_per_pkt;

    // The receive time uses our own clock and is estimated by us, so it needs
    // to be corrected over time because:
    //   a) the two clocks inevitably run at slightly different speeds;
    //   b) there's an unknown, variable, network delay between tx and rx.
    // Here, we're just assigning an initial estimate.
    s->start_rxtime = rxtime - id * s->usec_per_pkt;

    s->min_cycle_rxdiff = 0;
    s->next_rx_id = id;
    s->next_cycle = now + USEC_PER_CYCLE;
  }

  // see if we missed receiving any previous packets.
  int32_t tmpdiff = DIFF(id, s->next_rx_id);
  if (tmpdiff > 0) {
    // arriving packet has id > expected, so something was lost.
    // Note that we don't use the rx.acks[] structure to determine packet loss;
    // that's because the limited size of the array means that, during a longer
    // outage, we might not see an ack for a packet *even if that packet arrived
    // safely* at the remote.  So we count on the remote end to count its own
    // packet losses using sequence numbers, and send that count back to us.  We
    // do the same here for incoming packets from the remote, and send the error
    // count back to them next time we're ready to transmit.
    fprintf(stderr, "lost %ld  expected=%ld  got=%ld\n",
            (long)tmpdiff, (long)s->next_rx_id, (long)id);
    s->num_lost += tmpdiff;
    s->next_rx_id += tmpdiff + 1;
  } else if (!tmpdiff) {
    // exactly as expected; good.
    s->next_rx_id++;
  } else if (tmpdiff < 0) {
    // packet before the expected one? weird.
    fprintf(stderr, "out-of-order packets? %ld\n", (long)tmpdiff);
  }

  // fix up the clock offset if there's any drift.
  tmpdiff = DIFF(rxtime, s->start_rxtime + id * s->usec_per_pkt);
  if (tmpdiff < -20) {
    // packet arrived before predicted time, so prediction was based on
    // a packet that was "slow" before, or else one of our clocks is
    // drifting. Use earliest legitimate start time.
    fprintf(stderr, "time paradox: backsliding start by %ld usec\n",
            (long)tmpdiff);
    s->start_rxtime = rxtime - id * s->usec_per_pkt;
  }
  int32_t rxdiff = DIFF(rxtime, s->start_rxtime + id * s->usec_per_pkt);
  DLOG("ack: rxdiff=%d, rxtime=%u, start_rxtime=%u, id=%d, usec_per_pkt=%d\n",
       rxdiff, rxtime, s->start_rxtime, id, s->usec_per_pkt);

  // Figure out the offset between our clock and the remote's clock, so we can
  // calculate the minimum round trip time (rtt). Then, because the consecutive
  // packets sent in both directions are equally spaced in time, we can figure
  // out how much a particular packet was delayed in transit - independently in
  // each direction! This is an advantage over the normal "ping" program which
  // has no way to tell which direction caused the delay, or which direction
  // dropped the packet.

  // Our clockdiff is
  //   (our rx time) - (their tx time)
  //   == (their rx time + offset) - (their tx time)
  //   == (their tx time + offset + 1/2 rtt) - (their tx time)
  //   == offset + 1/2 rtt
  // and theirs (rx.clockdiff) is:
  //   (their rx time) - (our tx time)
  //   == (their rx time) - (their tx time + offset)
  //   == (their tx time + 1/2 rtt) - (their tx time + offset)
  //   == 1/2 rtt - offset
  // So add them together and we get:
  //   offset + 1/2 rtt + 1/2 rtt - offset
  //   == rtt
  // Subtract them and we get:
  //   offset + 1/2 rtt - 1/2 rtt + offset
  //   == 2 * offset
  // ...but that last subtraction is dangerous because if we divide by 2 to get
  // offset, it doesn't work with 32-bit math, which may have discarded a
  // high-order bit somewhere along the way.  Instead, we can extract offset
  // once we have rtt by substituting it into
  //   clockdiff = offset + 1/2 rtt
  //   offset = clockdiff - 1/2 rtt
  // (Dividing rtt by 2 is safe since it's always small and positive.)
  //
  // (This example assumes 1/2 rtt in each direction. There's no way to
  // determine it more accurately than that.)
  int32_t clockdiff = DIFF(s->start_rxtime, s->start_rtxtime);
  int32_t rtt = clockdiff + ntohl(s->rx.clockdiff);
  int32_t offset = DIFF(clockdiff, rtt / 2);
  if (!ntohl(s->rx.clockdiff)) {
    // don't print the first packet: it has an invalid clockdiff since the
    // client can't calculate the clockdiff until it receives at least one
    // packet from us.
    s->last_print = now - s->usec_per_print + 1;
  } else {
    // not the first packet, so statistics are valid.
    s->lat_rx_count++;
    s->lat_rx = rxdiff + rtt/2;
    s->lat_rx_min = s->lat_rx_min > s->lat_rx ? s->lat_rx : s->lat_rx_min;
    s->lat_rx_max = s->lat_rx_max < s->lat_rx ? s->lat_rx : s->lat_rx_max;
    s->lat_rx_sum += s->lat_rx;
    s->lat_rx_var_sum += s->lat_rx * s->lat_rx;
  }
  DLOG("ack packet: rx id=%d, clockdiff=%d, rtt=%d, offset=%d, rxdiff=%d\n",
       id, clockdiff, rtt, offset, rxdiff);

  // Note: the way ok_to_print is structured, if there is a dropout in the
  // connection for more than usec_per_print, we will statistically end up
  // printing the first packet after the dropout ends.  That one should have the
  // longest timeout, ie. a "worst case" packet, which is usually the
  // information you want to see.
  int ok_to_print = !quiet && DIFF(now, s->last_print) >= s->usec_per_print;
  if (ok_to_print) {
    if (want_timestamps) print_timestamp(rxtime);
    printf("%12s  %6.1f ms rx  (min=%.1f)  loss: %ld/%ld tx  %ld/%ld rx\n",
           s->last_ackinfo,
           (rxdiff + rtt/2) / 1000.0,
           (rtt/2) / 1000.0,
           (long)ntohl(s->rx.num_lost),
           (long)s->next_tx_id - 1,
           (long)s->num_lost,
           (long)s->next_rx_id - 1);
    s->last_ackinfo[0] = '\0';
    s->last_print = now;
  }

  if (rxdiff < s->min_cycle_rxdiff) s->min_cycle_rxdiff = rxdiff;
  if (DIFF(now, s->next_cycle) >= 0) {
    if (s->min_cycle_rxdiff > 0) {
      fprintf(stderr, "clock skew: sliding start by %ld usec\n",
              (long)s->min_cycle_rxdiff);
      s->start_rxtime += s->min_cycle_rxdiff;
    }
    s->min_cycle_rxdiff = 0x7fffffff;
    s->next_cycle += USEC_PER_CYCLE;
  }

  // schedule this for an ack next time we send the packet
  s->tx.data.acks[s->next_txack_index].id = htonl(id);
  s->tx.data.acks[s->next_txack_index].rxtime = htonl(rxtime);
  s->next_txack_index = (s->next_txack_index + 1) % ARRAY_LEN(s->tx.data.acks);

  // see which of our own transmitted packets have been acked
  uint32_t first_ack = s->rx.first_ack;
  for (uint32_t i = 0; i < ARRAY_LEN(s->rx.data.acks); i++) {
    uint32_t acki = (first_ack + i) % ARRAY_LEN(s->rx.data.acks);
    uint32_t ackid = ntohl(s->rx.data.acks[acki].id);
    if (!ackid) continue;  // empty slot
    if (DIFF(ackid, s->next_rxack_id) >= 0) {
      // an expected ack
      uint32_t start_txtime = s->next_send - s->next_tx_id * s->usec_per_pkt;
      uint32_t txtime = start_txtime + ackid * s->usec_per_pkt;
      uint32_t rrxtime = ntohl(s->rx.data.acks[acki].rxtime);
      uint32_t rxtime = rrxtime + offset;
      // note: already contains 1/2 rtt, unlike rxdiff
      int32_t txdiff = DIFF(rxtime, txtime);
      DLOG("acki=%d ackid=%d txdiff=%d rxtime=%u txtime=%u offset=%u, "
           "start_txtime=%u\n",
           acki, ackid, txdiff, rxtime, txtime, offset, start_txtime);
      if (!quiet && s->usec_per_print <= 0 && s->last_ackinfo[0]) {
        // only print multiple acks per rx if no usec_per_print limit
        if (want_timestamps) print_timestamp(rxtime);
        printf("%12s\n", s->last_ackinfo);
        s->last_ackinfo[0] = '\0';
      }
      if (!s->last_ackinfo[0]) {
        snprintf(s->last_ackinfo, sizeof(s->last_ackinfo), "%6.1f ms tx",
                 txdiff / 1000.0);
      }
      s->next_rxack_id = ackid + 1;
      s->lat_tx_count++;
      s->lat_tx = txdiff;
      s->lat_tx_min = s->lat_tx_min > s->lat_tx ? s->lat_tx : s->lat_tx_min;
      s->lat_tx_max = s->lat_tx_max < s->lat_tx ? s->lat_tx : s->lat_tx_max;
      s->lat_tx_sum += s->lat_tx;
      s->lat_tx_var_sum += s->lat_tx * s->lat_tx;
    }
  }

  s->last_rxtime = rxtime;
}

int isoping_main(int argc, char **argv) {
  struct sockaddr_in6 listenaddr;
  struct addrinfo *ai = NULL;
  int sock = -1;

  setvbuf(stdout, NULL, _IOLBF, 0);

  int c;
  while ((c = getopt(argc, argv, "f:r:t:qTh?")) >= 0) {
    switch (c) {
    case 'f':
      prints_per_sec = atof(optarg);
      if (prints_per_sec <= 0) {
        fprintf(stderr, "%s: lines per second must be >= 0\n", argv[0]);
        return 99;
      }
      break;
    case 'r':
      packets_per_sec = atof(optarg);
      if (packets_per_sec < 0.001 || packets_per_sec > 1e6) {
        fprintf(stderr, "%s: packets per sec (-r) must be 0.001..1000000\n",
                argv[0]);
        return 99;
      }
      break;
    case 't':
      ttl = atoi(optarg);
      if (ttl < 1) {
        fprintf(stderr, "%s: ttl must be >= 1\n", argv[0]);
        return 99;
      }
      break;
    case 'q':
      quiet = 1;
      break;
    case 'T':
      want_timestamps = 1;
      break;
    case 'h':
    case '?':
    default:
      usage_and_die(argv[0]);
      break;
    }
  }

  sock = socket(PF_INET6, SOCK_DGRAM, 0);
  if (sock < 0) {
    perror("socket");
    return 1;
  }

  int is_server;
  uint32_t now = ustime();       // current time
  Sessions sessions;

  if (argc - optind == 0) {
    is_server = 1;
    memset(&listenaddr, 0, sizeof(listenaddr));
    listenaddr.sin6_family = AF_INET6;
    listenaddr.sin6_port = htons(SERVER_PORT);
    if (bind(sock, (struct sockaddr *)&listenaddr, sizeof(listenaddr)) != 0) {
      perror("bind");
      return 1;
    }
    socklen_t addrlen = sizeof(listenaddr);
    if (getsockname(sock, (struct sockaddr *)&listenaddr, &addrlen) != 0) {
      perror("getsockname");
      return 1;
    }
    fprintf(stderr, "server listening at [%s]:%d\n",
           sockaddr_to_str((struct sockaddr *)&listenaddr),
           ntohs(listenaddr.sin6_port));
  } else if (argc - optind == 1) {
    const char *remotename = argv[optind];
    is_server = 0;
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
    hints.ai_family = AF_INET6;
    hints.ai_socktype = SOCK_DGRAM;
    int err = getaddrinfo(remotename, STR(SERVER_PORT), &hints, &ai);
    if (err != 0 || !ai) {
      fprintf(stderr, "getaddrinfo(%s): %s\n", remotename, gai_strerror(err));
      return 1;
    }
    fprintf(stderr, "connecting to %s...\n", sockaddr_to_str(ai->ai_addr));
    if (connect(sock, ai->ai_addr, ai->ai_addrlen) != 0) {
      perror("connect");
      return 1;
    }
    sessions.NewSession(now, 1e6 / packets_per_sec,
                        (struct sockaddr_storage *)ai->ai_addr, ai->ai_addrlen);
  } else {
    usage_and_die(argv[0]);
  }

  fprintf(stderr, "using ttl=%d\n", ttl);
  // IPPROTO_IPV6 is the only one that works on MacOS, and is arguably the
  // technically correct thing to do since it's an AF_INET6 socket.
  if (setsockopt(sock, IPPROTO_IPV6, IP_TTL, &ttl, sizeof(ttl))) {
    perror("setsockopt(TTLv6)");
    return 1;
  }
  // ...but in Linux (at least 3.13), IPPROTO_IPV6 does not actually
  // set the TTL if the IPv6 socket ends up going over IPv4.  We have to
  // set that separately.  On MacOS, that always returns EINVAL, so ignore
  // the error if that happens.
  if (setsockopt(sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))) {
    if (errno != EINVAL) {
      perror("setsockopt(TTLv4)");
      return 1;
    }
  }

  struct sigaction act;
  memset(&act, 0, sizeof(act));
  act.sa_handler = sighandler;
  act.sa_flags = SA_RESETHAND;
  sigaction(SIGINT, &act, NULL);

  uint32_t last_secret_update_time = 0;

  while (!want_to_die) {
    fd_set rfds;
    FD_ZERO(&rfds);
    FD_SET(sock, &rfds);
    struct timeval tv;
    tv.tv_sec = 0;

    now = ustime();
    if (sessions.next_sends.size() == 0 ||
        DIFF(sessions.next_send_time(), now) < 0) {
      tv.tv_usec = 0;
    } else {
      tv.tv_usec = DIFF(sessions.next_send_time(), now);
    }
    int nfds = select(sock + 1, &rfds, NULL, NULL,
                      sessions.next_sends.size() > 0 ? &tv : NULL);
    now = ustime();
    if (nfds < 0 && errno != EINTR) {
      perror("select");
      return 1;
    }

    // Periodically check if the cookie secrets need updating.
    if (is_server && (now - last_secret_update_time) > 1000000) {
      sessions.MaybeRotateCookieSecrets();
      last_secret_update_time = now;
    }

    int err = send_waiting_packets(&sessions, sock, now, is_server);
    if (err != 0) {
      return err;
    }

    if (nfds > 0) {
      err = read_incoming_packet(&sessions, sock, now, is_server);
      if (!is_server && err == ECONNREFUSED) return 2;
      if (err != 0) {
        continue;
      }
    }
  }

  // TODO(pmccurdy): Separate out per-client and global stats, print stats for
  // the server when each client disconnects.
  if (!is_server) {
    Session &s = sessions.session_map.begin()->second;
    printf("\n---\n");
    printf("tx: min/avg/max/mdev = %.2f/%.2f/%.2f/%.2f ms\n",
           s.lat_tx_min / 1000.0,
           DIV(s.lat_tx_sum, s.lat_tx_count) / 1000.0,
           s.lat_tx_max / 1000.0,
           onepass_stddev(
               s.lat_tx_var_sum, s.lat_tx_sum, s.lat_tx_count) / 1000.0);
    printf("rx: min/avg/max/mdev = %.2f/%.2f/%.2f/%.2f ms\n",
           s.lat_rx_min / 1000.0,
           DIV(s.lat_rx_sum, s.lat_rx_count) / 1000.0,
           s.lat_rx_max / 1000.0,
           onepass_stddev(
               s.lat_rx_var_sum, s.lat_rx_sum, s.lat_rx_count) / 1000.0);
    printf("\n");
  }

  if (ai) freeaddrinfo(ai);
  if (sock >= 0) close(sock);
  return 0;
}
