/* 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
  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)
}
