/* 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, OPTSTR_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
    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 = fork())) {
      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_optargs(2); //skip IP PORT
    } else if(pid > 0) {
      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);
    } else error_msg(" fork failed");
  } //while(1)
}
