/*
 * Copyright 2014 The Android Open Source Project
 *
 * 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.
 *
 * clatd_microbenchmark.c - micro-benchmark for clatd tun send path
 *
 * Run with:
 *
 * adb push {$ANDROID_PRODUCT_OUT,}/data/nativetest/clatd_microbenchmark/clatd_microbenchmark
 * adb shell /data/nativetest/clatd_microbenchmark/clatd_microbenchmark
 *
 */
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/udp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <time.h>
#include <unistd.h>

#include "netutils/checksum.h"
#include "tun.h"

#define DEVICENAME "clat4"

#define PORT 51339
#define PAYLOADSIZE (1280 - sizeof(struct iphdr) - sizeof(struct udphdr))
#define NUMPACKETS 1000000
#define SEC_TO_NANOSEC (1000 * 1000 * 1000)

void init_sockaddr_in(struct sockaddr_in *sin, const char *addr) {
  sin->sin_family      = AF_INET;
  sin->sin_port        = 0;
  sin->sin_addr.s_addr = inet_addr(addr);
}

void die(const char *str) {
  perror(str);
  exit(1);
}

int setup_tun() {
  int fd = tun_open();
  if (fd == -1) die("tun_open");

  char dev[IFNAMSIZ] = DEVICENAME;
  int ret            = tun_alloc(dev, fd, sizeof(dev));
  if (ret == -1) die("tun_alloc");
  struct ifreq ifr = {
    .ifr_name = DEVICENAME,
  };

  int s = socket(AF_INET, SOCK_DGRAM, 0);
  init_sockaddr_in((struct sockaddr_in *)&ifr.ifr_addr, "192.0.0.4");
  if (ioctl(s, SIOCSIFADDR, &ifr) < 0) die("SIOCSIFADDR");
  init_sockaddr_in((struct sockaddr_in *)&ifr.ifr_addr, "255.255.255.248");
  if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0) die("SIOCSIFNETMASK");
  if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) die("SIOCGIFFLAGS");
  ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
  if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) die("SIOCSIFFLAGS");
  return fd;
}

int send_packet(int fd, uint8_t payload[], int len, uint32_t payload_checksum) {
  struct tun_pi tun = { 0, htons(ETH_P_IP) };
  struct udphdr udp = {
    .source = htons(1234),
    .dest   = htons(PORT),
    .len    = htons(len + sizeof(udp)),
    .check  = 0,
  };
  struct iphdr ip = {
    .version  = 4,
    .ihl      = 5,
    .tot_len  = htons(len + sizeof(ip) + sizeof(udp)),
    .frag_off = htons(IP_DF),
    .ttl      = 55,
    .protocol = IPPROTO_UDP,
    .saddr    = htonl(0xc0000006),  // 192.0.0.6
    .daddr    = htonl(0xc0000004),  // 192.0.0.4
  };
  clat_packet out = {
    { &tun, sizeof(tun) },  // tun header
    { &ip, sizeof(ip) },    // IP header
    { NULL, 0 },            // Fragment header
    { &udp, sizeof(udp) },  // Transport header
    { NULL, 0 },            // ICMP error IP header
    { NULL, 0 },            // ICMP error fragment header
    { NULL, 0 },            // ICMP error transport header
    { payload, len },       // Payload
  };

  ip.check = ip_checksum(&ip, sizeof(ip));

  uint32_t sum;
  sum = ipv4_pseudo_header_checksum(&ip, ntohs(udp.len));
  sum = ip_checksum_add(sum, &udp, sizeof(udp));
  sum += payload_checksum;
  udp.check = ip_checksum_finish(sum);

  return send_tun(fd, out, sizeof(out) / sizeof(out[0]));
}

double timedelta(const struct timespec tv1, const struct timespec tv2) {
  struct timespec end = tv2;
  if (end.tv_nsec < tv1.tv_nsec) {
    end.tv_sec -= 1;
    end.tv_nsec += SEC_TO_NANOSEC;
  }
  double seconds = (end.tv_sec - tv1.tv_sec);
  seconds += (((double)(end.tv_nsec - tv1.tv_nsec)) / SEC_TO_NANOSEC);
  return seconds;
}

void benchmark(const char *name, int fd, int s, int num, int do_read, uint8_t payload[], int len,
               uint32_t payload_sum) {
  int i;
  char buf[4096];
  struct timespec tv1, tv2;
  int write_err = 0, read_err = 0;
  clock_gettime(CLOCK_MONOTONIC, &tv1);
  for (i = 0; i < num; i++) {
    if (send_packet(fd, payload, len, payload_sum) == -1) write_err++;
    if (do_read && recvfrom(s, buf, sizeof(buf), 0, NULL, NULL) == -1) {
      read_err++;
      if (errno == ETIMEDOUT) {
        printf("Timed out after %d packets!\n", i);
        break;
      }
    }
  }
  clock_gettime(CLOCK_MONOTONIC, &tv2);
  double seconds = timedelta(tv1, tv2);
  int pps        = (int)(i / seconds);
  double mbps    = (i * PAYLOADSIZE / 1000000 * 8 / seconds);
  printf("%s: %d packets in %.2fs (%d pps, %.2f Mbps), ", name, i, seconds, pps, mbps);
  printf("read err %d (%.2f%%), write err %d (%.2f%%)\n", read_err, (float)read_err / i * 100,
         write_err, (float)write_err / i * 100);
}

int open_socket() {
  int sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);

  int on = 1;
  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) die("SO_REUSEADDR");

  struct timeval tv = { 1, 0 };
  if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) die("SO_RCVTIMEO");

  struct sockaddr_in addr = {
    .sin_family = AF_INET,
    .sin_port   = ntohs(PORT),
    .sin_addr   = { INADDR_ANY },
  };
  if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) die("bind");

  return sock;
}

int main() {
  int fd   = setup_tun();
  int sock = open_socket();

  int i;
  uint8_t payload[PAYLOADSIZE];
  for (i = 0; i < (int)sizeof(payload); i++) {
    payload[i] = (uint8_t)i;
  }
  uint32_t payload_sum = ip_checksum_add(0, payload, sizeof(payload));

  // Check things are working.
  char buf[4096];
  if (send_packet(fd, payload, sizeof(payload), payload_sum) == -1) die("send_packet");
  if (recvfrom(sock, buf, sizeof(buf), 0, NULL, NULL) == -1) die("recvfrom");

  benchmark("Blocking", fd, sock, NUMPACKETS, 1, payload, sizeof(payload), payload_sum);
  close(fd);

  fd = setup_tun();
  benchmark("No read", fd, sock, NUMPACKETS, 0, payload, sizeof(payload), payload_sum);
  close(fd);

  fd = setup_tun();
  benchmark("Nonblocking", fd, sock, NUMPACKETS, 1, payload, sizeof(payload), payload_sum);
  close(fd);

  return 0;
}
