/* tcpsvd.c - TCP(UDP)/IP service daemon 
 *
 * Copyright 2013 Ashwini Kumar <ak.ashwini@gmail.com>
 * Copyright 2013 Sandeep Sharma <sandeep.jack2756@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 * 
 * No Standard.

USE_TCPSVD(NEWTOY(tcpsvd, "^<3c#=30<1C:b#=20<0u:l:hEv", TOYFLAG_USR|TOYFLAG_BIN))
USE_TCPSVD(OLDTOY(udpsvd, tcpsvd, TOYFLAG_USR|TOYFLAG_BIN))

config TCPSVD
  bool "tcpsvd"
  default n
  depends on TOYBOX_FORK
  help
    usage: tcpsvd [-hEv] [-c N] [-C N[:MSG]] [-b N] [-u User] [-l Name] IP Port Prog
    usage: udpsvd [-hEv] [-c N] [-u User] [-l Name] IP Port Prog
    
    Create TCP/UDP socket, bind to IP:PORT and listen for incoming connection. 
    Run PROG for each connection.

    IP            IP to listen on, 0 = all
    PORT          Port to listen on
    PROG ARGS     Program to run
    -l NAME       Local hostname (else looks up local hostname in DNS)
    -u USER[:GRP] Change to user/group after bind
    -c N          Handle up to N (> 0) connections simultaneously
    -b N          (TCP Only) Allow a backlog of approximately N TCP SYNs
    -C N[:MSG]    (TCP Only) Allow only up to N (> 0) connections from the same IP
                  New connections from this IP address are closed
                  immediately. MSG is written to the peer before close
    -h            Look up peer's hostname
    -E            Don't set up environment variables
    -v            Verbose
*/

#define FOR_tcpsvd
#include "toys.h"

GLOBALS(
  char *name;
  char *user;
  long bn;
  char *nmsg;
  long cn;

  int maxc;
  int count_all;
  int udp;
)

struct list_pid {
  struct list_pid *next;
  char *ip;  
  int pid;
};

struct list {
  struct list* next;
  char *d;
  int count;
};

struct hashed {
  struct list *head;
};

#define HASH_NR 256
struct hashed h[HASH_NR];
struct list_pid *pids = NULL;

// convert IP address to string.
static char *sock_to_address(struct sockaddr *sock, int flags)
{
  char hbuf[NI_MAXHOST] = {0,};
  char sbuf[NI_MAXSERV] = {0,}; 
  int status = 0;
  socklen_t len = sizeof(struct sockaddr_in6);

  if (!(status = getnameinfo(sock, len, hbuf, sizeof(hbuf), sbuf, 
          sizeof(sbuf), flags))) {
    if (flags & NI_NUMERICSERV) return xmprintf("%s:%s",hbuf, sbuf);
    return xmprintf("%s",hbuf);
  }
  error_exit("getnameinfo: %s", gai_strerror(status));
}

// Insert pid, ip and fd in the list.
static void insert(struct list_pid **l, int pid, char *addr)
{
  struct list_pid *newnode = xmalloc(sizeof(struct list_pid));
  newnode->pid = pid;
  newnode->ip = addr;
  newnode->next = NULL;
  if (!*l) *l = newnode;
  else {
    newnode->next = (*l);
   *l = newnode;
  }
}

// Hashing of IP address.
static int haship( char *addr)
{
  uint32_t ip[8] = {0,};
  int count = 0, i = 0;

  if (!addr) error_exit("NULL ip");
  while (i < strlen(addr)) {
    while (addr[i] && (addr[i] != ':') && (addr[i] != '.')) {
      ip[count] = ip[count]*10 + (addr[i]-'0');
      i++;
    }
    if (i >= strlen(addr)) break;
    count++;
    i++;
  }
  return (ip[0]^ip[1]^ip[2]^ip[3]^ip[4]^ip[5]^ip[6]^ip[7])%HASH_NR;
}

// Remove a node from the list.
static char *delete(struct list_pid **pids, int pid)
{
  struct list_pid *prev, *free_node, *head = *pids; 
  char *ip = NULL;
 
  if (!head) return NULL;
  prev = free_node = NULL;
  while (head) {
    if (head->pid == pid) {
      ip = head->ip;
      free_node = head;
      if (!prev) *pids = head->next;
      else prev->next = head->next;
      free(free_node);
      return ip;
    }
    prev = head;
    head = head->next;
  }
  return NULL;
}

// decrement the ref count fora connection, if count reches ZERO then remove the node
static void remove_connection(char *ip)
{
  struct list *head, *prev = NULL, *free_node = NULL;
  int hash = haship(ip);

  head = h[hash].head;
  while (head) {
    if (!strcmp(ip, head->d)) {
      head->count--;
      free_node = head;
      if (!head->count) {
        if (!prev) h[hash].head = head->next;
        else prev->next = head->next;
        free(free_node);
      }
      break;
    }
    prev = head;
    head = head->next;
  }
  free(ip);
}

// Handler function.
static void handle_exit(int sig)
{
  int status;
  pid_t pid_n = wait(&status);

  if (pid_n <= 0) return;
  char *ip = delete(&pids, pid_n);
  if (!ip) return;
  remove_connection(ip);
  TT.count_all--;
  if (toys.optflags & FLAG_v) {
    if (WIFEXITED(status))
      xprintf("%s: end %d exit %d\n",toys.which->name, pid_n, WEXITSTATUS(status));
    else if (WIFSIGNALED(status))
      xprintf("%s: end %d signaled %d\n",toys.which->name, pid_n, WTERMSIG(status));
    if (TT.cn > 1) xprintf("%s: status %d/%d\n",toys.which->name, TT.count_all, TT.cn);
  }
}

// Grab uid and gid 
static void get_uidgid(uid_t *uid, gid_t *gid, char *ug)
{
  struct passwd *pass = NULL;
  struct group *grp = NULL;
  char *user = NULL, *group = NULL;
  unsigned int n;

  user = ug;
  group = strchr(ug,':');
  if (group) {
    *group = '\0';
    group++;
  }
  if (!(pass = getpwnam(user))) {
    n = atolx_range(user, 0, INT_MAX);
    if (!(pass = getpwuid(n))) perror_exit("Invalid user '%s'", user);
  }
  *uid = pass->pw_uid;
  *gid = pass->pw_gid;

  if (group) {
    if (!(grp = getgrnam(group))) {
      n = atolx_range(group, 0, INT_MAX);
      if (!(grp = getgrgid(n))) perror_exit("Invalid group '%s'",group);
    }    
  }
  if (grp) *gid = grp->gr_gid;
}

// Bind socket.
static int create_bind_sock(char *host, struct sockaddr *haddr)
{
  struct addrinfo hints, *res = NULL, *rp;
  int sockfd, ret, set = 1;
  char *ptr;
  unsigned long port;

  errno = 0;
  port = strtoul(toys.optargs[1], &ptr, 10);  
  if (errno || port > 65535) 
    error_exit("Invalid port, Range is [0-65535]");
  if (*ptr) ptr = toys.optargs[1];
  else {
    sprintf(toybuf, "%lu", port);
    ptr = toybuf;
  }

  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_UNSPEC;  
  hints.ai_socktype = ((TT.udp) ?SOCK_DGRAM : SOCK_STREAM);
  if ((ret = getaddrinfo(host, ptr, &hints, &res))) 
    perror_exit("%s", gai_strerror(ret));

  for (rp = res; rp; rp = rp->ai_next) 
    if ( (rp->ai_family == AF_INET) || (rp->ai_family == AF_INET6)) break;

  if (!rp) error_exit("Invalid IP %s", host);

  sockfd = xsocket(rp->ai_family, TT.udp ?SOCK_DGRAM :SOCK_STREAM, 0);
  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(set));
  if (TT.udp) setsockopt(sockfd, IPPROTO_IP, IP_PKTINFO, &set, sizeof(set));
  if ((bind(sockfd, rp->ai_addr, rp->ai_addrlen)) < 0) perror_exit("Bind failed");
  if(haddr) memcpy(haddr, rp->ai_addr, rp->ai_addrlen);
  freeaddrinfo(res);
  return sockfd;
}

static void handle_signal(int sig)
{
  if (toys.optflags & FLAG_v) xprintf("got signal %d, exit\n", sig);
  raise(sig);
  _exit(sig + 128); //should not reach here
} 

void tcpsvd_main(void)
{
  uid_t uid = 0;
  gid_t gid = 0;
  pid_t pid;
  char haddr[sizeof(struct sockaddr_in6)];
  struct list *head, *newnode;
  int hash, fd, newfd, j;
  char *ptr = NULL, *addr, *server, buf[sizeof(struct sockaddr_in6)];
  socklen_t len = sizeof(buf);

  TT.udp = (*toys.which->name == 'u');
  if (TT.udp) toys.optflags &= ~FLAG_C;
  memset(buf, 0, len);
  if (toys.optflags & FLAG_C) {
    if ((ptr = strchr(TT.nmsg, ':'))) {
      *ptr = '\0';
      ptr++;
    }
    TT.maxc = atolx_range(TT.nmsg, 1, INT_MAX);
  }
  
  fd = create_bind_sock(toys.optargs[0], (struct sockaddr*)&haddr);
  if(toys.optflags & FLAG_u) {
    get_uidgid(&uid, &gid, TT.user);
    setuid(uid);
    setgid(gid);
  }

  if (!TT.udp && (listen(fd, TT.bn) < 0)) perror_exit("Listen failed");
  server = sock_to_address((struct sockaddr*)&haddr, NI_NUMERICHOST|NI_NUMERICSERV);
  if (toys.optflags & FLAG_v) {
    if (toys.optflags & FLAG_u)
      xprintf("%s: listening on %s, starting, uid %u, gid %u\n"
          ,toys.which->name, server, uid, gid);
    else 
      xprintf("%s: listening on %s, starting\n", toys.which->name, server);
  }
  for (j = 0; j < HASH_NR; j++) h[j].head = NULL;
  sigatexit(handle_signal);  
  signal(SIGCHLD, handle_exit);

  while (1) {
    if (TT.count_all  < TT.cn) {
      if (TT.udp) {
        if(recvfrom(fd, NULL, 0, MSG_PEEK, (struct sockaddr *)buf, &len) < 0)
          perror_exit("recvfrom");
        newfd = fd;
      } else {
        newfd = accept(fd, (struct sockaddr *)buf, &len);
        if (newfd < 0) perror_exit("Error on accept");
      }
    } else {
      sigset_t ss;
      sigemptyset(&ss);
      sigsuspend(&ss);
      continue;
    }
    TT.count_all++;
    addr = sock_to_address((struct sockaddr*)buf, NI_NUMERICHOST);

    hash = haship(addr);
    if (toys.optflags & FLAG_C) {
      for (head = h[hash].head; head; head = head->next)
        if (!strcmp(head->d, addr)) break;

      if (head && head->count >= TT.maxc) {
        if (ptr) write(newfd, ptr, strlen(ptr)+1);
        close(newfd);
        TT.count_all--;
        continue;
      }
    }

    newnode = (struct list*)xzalloc(sizeof(struct list));
    newnode->d = addr;
    for (head = h[hash].head; head; head = head->next) {
      if (!strcmp(addr, head->d)) {
        head->count++;
        free(newnode);
        break;
      }
    }

    if (!head) {
      newnode->next = h[hash].head;
      h[hash].head = newnode;
      h[hash].head->count++;
    }

    if (!(pid = xfork())) {
      char *serv = NULL, *clie = NULL;
      char *client = sock_to_address((struct sockaddr*)buf, NI_NUMERICHOST | NI_NUMERICSERV);
      if (toys.optflags & FLAG_h) { //lookup name
        if (toys.optflags & FLAG_l) serv = xstrdup(TT.name);
        else serv = sock_to_address((struct sockaddr*)&haddr, 0);
        clie = sock_to_address((struct sockaddr*)buf, 0);
      }

      if (!(toys.optflags & FLAG_E)) {
        setenv("PROTO", TT.udp ?"UDP" :"TCP", 1);
        setenv("PROTOLOCALADDR", server, 1);
        setenv("PROTOREMOTEADDR", client, 1);
        if (toys.optflags & FLAG_h) {
          setenv("PROTOLOCALHOST", serv, 1);
          setenv("PROTOREMOTEHOST", clie, 1);
        }
        if (!TT.udp) {
          char max_c[32];
          sprintf(max_c, "%d", TT.maxc);
          setenv("TCPCONCURRENCY", max_c, 1); //Not valid for udp
        }
      }
      if (toys.optflags & FLAG_v) {
        xprintf("%s: start %d %s-%s",toys.which->name, getpid(), server, client);
        if (toys.optflags & FLAG_h) xprintf(" (%s-%s)", serv, clie);
        xputc('\n');
        if (TT.cn > 1) 
          xprintf("%s: status %d/%d\n",toys.which->name, TT.count_all, TT.cn);
      }
      free(client);
      if (toys.optflags & FLAG_h) {
        free(serv);
        free(clie);
      }
      if (TT.udp && (connect(newfd, (struct sockaddr *)buf, sizeof(buf)) < 0))
          perror_exit("connect");

      close(0);
      close(1);
      dup2(newfd, 0);
      dup2(newfd, 1);
      xexec(toys.optargs+2); //skip IP PORT
    } else {
      insert(&pids, pid, addr);
      xclose(newfd); //close and reopen for next client.
      if (TT.udp) fd = create_bind_sock(toys.optargs[0],
          (struct sockaddr*)&haddr);
    }
  } //while(1)
}
