Logo Search packages:      
Sourcecode: openssl version File versions

ip.c

#include "tunala.h"

#ifndef NO_IP

#define IP_LISTENER_BACKLOG 511 /* So if it gets masked by 256 or some other
                           such value it'll still be respectable */

/* Any IP-related initialisations. For now, this means blocking SIGPIPE */
int ip_initialise(void)
{
      struct sigaction sa;

      sa.sa_handler = SIG_IGN;
      sa.sa_flags = 0;
      sigemptyset(&sa.sa_mask);
      if(sigaction(SIGPIPE, &sa, NULL) != 0)
            return 0;
      return 1;
}

int ip_create_listener_split(const char *ip, unsigned short port)
{
      struct sockaddr_in in_addr;
      int fd = -1;
      int reuseVal = 1;

      /* Create the socket */
      if((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
            goto err;
      /* Set the SO_REUSEADDR flag - servers act weird without it */
      if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)(&reuseVal),
                        sizeof(reuseVal)) != 0)
            goto err;
      /* Prepare the listen address stuff */
      in_addr.sin_family = AF_INET;
      memcpy(&in_addr.sin_addr.s_addr, ip, 4);
      in_addr.sin_port = htons(port);
      /* Bind to the required port/address/interface */
      if(bind(fd, (struct sockaddr *)&in_addr, sizeof(struct sockaddr_in)) != 0)
            goto err;
      /* Start "listening" */
      if(listen(fd, IP_LISTENER_BACKLOG) != 0)
            goto err;
      return fd;
err:
      if(fd != -1)
            close(fd);
      return -1;
}

int ip_create_connection_split(const char *ip, unsigned short port)
{
      struct sockaddr_in in_addr;
      int flags, fd = -1;

      /* Create the socket */
      if((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
            goto err;
      /* Make it non-blocking */
      if(((flags = fcntl(fd, F_GETFL, 0)) < 0) ||
                  (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0))
            goto err;
      /* Prepare the connection address stuff */
      in_addr.sin_family = AF_INET;
      memcpy(&in_addr.sin_addr.s_addr, ip, 4);
      in_addr.sin_port = htons(port);
      /* Start a connect (non-blocking, in all likelihood) */
      if((connect(fd, (struct sockaddr *)&in_addr,
                  sizeof(struct sockaddr_in)) != 0) &&
                  (errno != EINPROGRESS))
            goto err;
      return fd;
err:
      if(fd != -1)
            close(fd);
      return -1;
}

static char all_local_ip[] = {0x00,0x00,0x00,0x00};

int ip_parse_address(const char *address, const char **parsed_ip,
            unsigned short *parsed_port, int accept_all_ip)
{
      char buf[256];
      struct hostent *lookup;
      unsigned long port;
      const char *ptr = strstr(address, ":");
      const char *ip = all_local_ip;

      if(!ptr) {
            /* We assume we're listening on all local interfaces and have
             * only specified a port. */
            if(!accept_all_ip)
                  return 0;
            ptr = address;
            goto determine_port;
      }
      if((ptr - address) > 255)
            return 0;
      memset(buf, 0, 256);
      memcpy(buf, address, ptr - address);
      ptr++;
      if((lookup = gethostbyname(buf)) == NULL) {
            /* Spit a message to differentiate between lookup failures and
             * bad strings. */
            fprintf(stderr, "hostname lookup for '%s' failed\n", buf);
            return 0;
      }
      ip = lookup->h_addr_list[0];
determine_port:
      if(strlen(ptr) < 1)
            return 0;
      if(!int_strtoul(ptr, &port) || (port > 65535))
            return 0;
      *parsed_ip = ip;
      *parsed_port = (unsigned short)port;
      return 1;
}

int ip_create_listener(const char *address)
{
      const char *ip;
      unsigned short port;

      if(!ip_parse_address(address, &ip, &port, 1))
            return -1;
      return ip_create_listener_split(ip, port);
}

int ip_create_connection(const char *address)
{
      const char *ip;
      unsigned short port;

      if(!ip_parse_address(address, &ip, &port, 0))
            return -1;
      return ip_create_connection_split(ip, port);
}

int ip_accept_connection(int listen_fd)
{
      return accept(listen_fd, NULL, NULL);
}

#endif /* !defined(NO_IP) */


Generated by  Doxygen 1.6.0   Back to index