Example #1
0
void forwarder_deinit(forwarder_t *f)
{
  su_root_unregister(f->f_pr->pr_root, f->f_wait, NULL, f);
  su_wait_destroy(f->f_wait);
  su_root_unregister(f->f_pr->pr_root, f->f_wait + 1, NULL, f);
  su_wait_destroy(f->f_wait + 1);
  if (f->f_socket != INVALID_SOCKET)
    su_close(f->f_socket), f->f_socket = INVALID_SOCKET;
  if (f->f_buf)
    su_free(f->f_pr->pr_home, f->f_buf), f->f_buf = NULL;
}
Example #2
0
int tport_ws_init_secondary(tport_t *self, int socket, int accepted,
			     char const **return_reason)
{
  int one = 1;
  tport_ws_primary_t *wspri = (tport_ws_primary_t *)self->tp_pri;
  tport_ws_t *wstp = (tport_ws_t *)self;

  self->tp_has_connection = 1;

  if (setsockopt(socket, SOL_TCP, TCP_NODELAY, (void *)&one, sizeof one) == -1)
	  return *return_reason = "TCP_NODELAY", -1;

#if defined(SO_KEEPALIVE)
  setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, sizeof one);
#endif
  one = 30;
#if defined(TCP_KEEPIDLE)
  setsockopt(socket, SOL_TCP, TCP_KEEPIDLE, (void *)&one, sizeof one);
#endif
#if defined(TCP_KEEPINTVL)
  setsockopt(socket, SOL_TCP, TCP_KEEPINTVL, (void *)&one, sizeof one);
#endif


  if (!accepted)
    tport_ws_setsndbuf(socket, 64 * 1024);

  if ( wspri->ws_secure ) wstp->ws_secure = 1;

  memset(&wstp->ws, 0, sizeof(wstp->ws));

  if (ws_init(&wstp->ws, socket, wstp->ws_secure ? wspri->ssl_ctx : NULL, 0) < 0) {
	  ws_destroy(&wstp->ws);
	  su_close(socket);
	  wstp->ws_initialized = -1;
	  return *return_reason = "WS_INIT", -1;
  }

  wstp->ws_initialized = 1;
  self->tp_pre_framed = 1;
  


  return 0;
}
Example #3
0
/** Initialize logging. */
int tport_open_log(tport_master_t *mr, tagi_t *tags)
{
  int n;
  int log_msg = mr->mr_log != 0;
  char const *dump = NULL;
  char const *capt = NULL;;
  
  if(mr->mr_capt_name) capt = mr->mr_capt_name;
  
  n = tl_gets(tags,
	      TPTAG_LOG_REF(log_msg),
	      TPTAG_DUMP_REF(dump),
	      TPTAG_CAPT_REF(capt),
	      TAG_END());

  if (getenv("MSG_STREAM_LOG") != NULL || getenv("TPORT_LOG") != NULL)
    log_msg = 1;
  mr->mr_log = log_msg ? MSG_DO_EXTRACT_COPY : 0;

  if (getenv("TPORT_CAPT"))
    capt = getenv("TPORT_CAPT");
  if (getenv("MSG_DUMP"))
    dump = getenv("MSG_DUMP");
  if (getenv("TPORT_DUMP"))
    dump = getenv("TPORT_DUMP");
 
  if(capt) {

        char *captname, *p, *host_s;
        char port[10];
        su_addrinfo_t *ai = NULL, hints[1] = {{ 0 }};
        unsigned len =0;

        if (mr->mr_capt_name && mr->mr_capt_sock && strcmp(capt, mr->mr_capt_name) == 0)                
              return n;

        captname = su_strdup(mr->mr_home, capt);
        if (captname == NULL)
              return n;
                           
        if(strncmp(captname, "udp:",4) != 0) {
              su_log("tport_open_log: capturing. Only udp protocol supported [%s]\n", captname);          
              return n;
        } 
        
        /* separate proto and host */
        p = captname+4;
        if( (*(p)) == '\0') {
                su_log("malformed ip address\n");
                return n;
        }
        host_s = p;

        if( (p = strrchr(p+1, ':')) == 0 ) {
                su_log("no host or port specified\n");
                return n;
        }
 
        /*the address contains a port number*/
        *p = '\0';
        p++;

        if (atoi(p) <1024  || atoi(p)>65536)
        {
                su_log("invalid port number; must be in [1024,65536]\n");
                return n;
        }

        strncpy(port, p, sizeof(port));
                        
        *p = '\0'; 
        
        /* check if we have [] */
        if (host_s[0] == '[') {
              len = strlen(host_s + 1) - 1;              
              if(host_s[len+1] != ']') {
                su_log("bracket not closed\n");
                return n;            
            }            
            memmove(host_s, host_s + 1, len);
            host_s[len] = '\0';
        }                              

        /* and again */
        captname = su_strdup(mr->mr_home, capt);
        if (captname == NULL) return n;
        
        su_free(mr->mr_home, mr->mr_capt_name);
        mr->mr_capt_name = captname;

        if (mr->mr_capt_sock)
          su_close(mr->mr_capt_sock), mr->mr_capt_sock = 0;        

        /* HINTS && getaddrinfo */
        hints->ai_flags = AI_NUMERICSERV;
        hints->ai_family = AF_UNSPEC; 
        hints->ai_socktype = SOCK_DGRAM;
        hints->ai_protocol = IPPROTO_UDP;
        

        if (su_getaddrinfo(host_s, port, hints, &ai)) {
            su_perror("capture: su_getaddrinfo()");
            return n;
        }
        
	mr->mr_capt_sock = su_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
	if (mr->mr_capt_sock == INVALID_SOCKET) {
	    su_perror("capture: invalid socket");
	    return n;
	}

	su_setblocking(mr->mr_capt_sock, 0);         /* Don't block */

	if (connect(mr->mr_capt_sock, ai->ai_addr, (socklen_t)(ai->ai_addrlen)) == -1) {
	    if (errno != EINPROGRESS) {
		    su_perror("capture: socket connect");
		    return n;
	    }	                
	}
		
	su_freeaddrinfo(ai);        
  }
  else if(mr->mr_capt_sock) {
      /* close capture server*/
      su_close(mr->mr_capt_sock);
      mr->mr_capt_sock = 0;
  }

  if (dump) {
    time_t now;
    char *dumpname;
    
    if (mr->mr_dump && strcmp(dump, mr->mr_dump) == 0)
      return n;
    dumpname = su_strdup(mr->mr_home, dump);
    if (dumpname == NULL)
      return n;
    su_free(mr->mr_home, mr->mr_dump);
    mr->mr_dump = dumpname;

    if (mr->mr_dump_file && mr->mr_dump_file != stdout)
      fclose(mr->mr_dump_file), mr->mr_dump_file = NULL;

    if (strcmp(dumpname, "-"))
      mr->mr_dump_file = fopen(dumpname, "ab"); /* XXX */
    else
      mr->mr_dump_file = stdout;

    if (mr->mr_dump_file) {
      time(&now);
      fprintf(mr->mr_dump_file, "dump started at %s\n\n", ctime(&now));
    }
  }

  return n;
}
Example #4
0
/** Build a list of local IPv4 addresses and append it to *rresult. */
static
int localinfo4(su_localinfo_t const *hints, su_localinfo_t **rresult)
{
  su_localinfo_t *tbf = NULL, **lli = &tbf;
  su_localinfo_t *li = NULL, *li_first = NULL;
  su_sockaddr_t *su;
  int error = ELI_NOADDRESS;
  char *canonname = NULL;
  su_socket_t s;

#if SU_HAVE_IN6
  int su_xtra = (hints->li_flags & LI_V4MAPPED) ? sizeof(*su) : 0;
#else
  int const su_xtra = 0;
#endif

  struct ifconf ifc;
  int numifs;
  char *buffer;
  struct ifreq *ifr, *ifr_next;

#if HAVE_OPEN_C
    su_sockaddr_t *sa;
    socklen_t salen = sizeof(*sa);
#endif

  s = su_socket(AF_INET, SOCK_DGRAM, 0);
  if (s == -1) {
    SU_DEBUG_1(("su_localinfo: su_socket failed: %s\n",
		su_strerror(su_errno())));
    return ELI_SYSTEM;
  }

# if HAVE_IFNUM
  /* Get the list of known IP address from the kernel */
  if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0) {
    /* can't get number of interfaces -- fall back */
    SU_DEBUG_1(("su_localinfo: SIOCGIFNUM failed: %s\n",
		su_strerror(su_errno())));
    error = ELI_SYSTEM;
    goto err;
  }

  SU_DEBUG_9(("su_localinfo: %d active interfaces according to SIOCGIFNUM\n",
	      numifs));

  if (numifs < 0)
# endif
    /* Default to 64 interfaces. Enough? */
    numifs = 64;

  if (numifs == 0)
    return 0;

  /*
   * Allocate memory for SIOCGIFCONF ioctl buffer. This memory block is also
   * used as li_first, first localinfo struct that is returned, so it can be
   * freed by freelocalinfo() without any complications.
   */
  ifc.ifc_len = numifs * sizeof (struct ifreq);
  buffer = malloc(sizeof(su_localinfo_t) + ifc.ifc_len + su_xtra);
  if (!buffer) {
    SU_DEBUG_1(("su_localinfo: memory exhausted\n"));
    error = ELI_MEMORY;
    goto err;
  }

  li_first = (su_localinfo_t *)buffer;
  memset(li_first, 0, sizeof(su_localinfo_t) + su_xtra);
  ifc.ifc_buf = buffer + sizeof(su_localinfo_t) + su_xtra;
#if HAVE_OPEN_C
  if (ioctl(s, SIOCGIFACTIVECONF, (char *)&ifc) < 0) {
    SU_DEBUG_1(("su_localinfo: SIOCGIFCONF failed: %s\n",
		su_strerror(su_errno())));
    error = ELI_SYSTEM;
    goto err;
  }
#else
  if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
    SU_DEBUG_1(("su_localinfo: SIOCGIFCONF failed: %s\n",
		su_strerror(su_errno())));
    error = ELI_SYSTEM;
    goto err;
  }
#endif

  buffer = ifc.ifc_buf + ifc.ifc_len;

  for (ifr = ifc.ifc_req;
       (void *)ifr < (void *)buffer;
       ifr = ifr_next) {
    struct ifreq ifreq[1];
    int scope, if_index, flags = 0, gni_flags = 0;
    char *if_name;
#if SU_HAVE_IN6
    su_sockaddr_t su2[1];
#endif

#if SA_LEN
    if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr))
      ifr_next = (struct ifreq *)
	(ifr->ifr_addr.sa_len + (char *)(&ifr->ifr_addr));
    else
#else
      ifr_next = ifr + 1;
#endif

    if_name = ifr->ifr_name;

#if defined(SIOCGIFINDEX)
    ifreq[0] = *ifr;
    if (ioctl(s, SIOCGIFINDEX, ifreq) < 0) {
      SU_DEBUG_1(("su_localinfo: SIOCGIFINDEX failed: %s\n",
		  su_strerror(su_errno())));
      error = ELI_SYSTEM;
      goto err;
    }
#if HAVE_IFR_INDEX
    if_index = ifreq->ifr_index;
#elif HAVE_IFR_IFINDEX
    if_index = ifreq->ifr_ifindex;
#else
#error Unknown index field in struct ifreq
#endif

#else
#warning su_localinfo() cannot map interface name to number
    if_index = 0;
#endif

    SU_DEBUG_9(("su_localinfo: if %s with index %d\n", if_name, if_index));


#if HAVE_OPEN_C
    su_close(s);

    li = calloc(1, sizeof(su_localinfo_t));
    sa = calloc(1, sizeof(su_sockaddr_t));

    if (su_get_local_ip_addr(sa) < 0)
      goto err;

    li->li_family = sa->su_family;
    li->li_scope = LI_SCOPE_GLOBAL /* scope */;
    li->li_index = if_index;
    li->li_addrlen = su_sockaddr_size(sa);
    li->li_addr = sa;

    if ((error = li_name(hints, gni_flags, sa, &canonname)) < 0)
      goto err;

    if (canonname) {
      if (strchr(canonname, ':') ||
	  strspn(canonname, "0123456789.") == strlen(canonname))
	    li->li_flags |= LI_NUMERIC;
    }
    else
      li->li_flags = 0;

    li->li_canonname = canonname;

    canonname = NULL;

    *rresult = li;

    return 0;
#endif

#if defined(SIOCGIFFLAGS)
    ifreq[0] = *ifr;
    if (ioctl(s, SIOCGIFFLAGS, ifreq) < 0) {
      SU_DEBUG_1(("su_localinfo: SIOCGIFFLAGS failed: %s\n",
		  su_strerror(su_errno())));
      error = ELI_SYSTEM;
      goto err;
    }
    /* Do not include interfaces that are down unless explicitly asked */
    if ((ifreq->ifr_flags & IFF_UP) == 0 && (hints->li_flags & LI_DOWN) == 0) {
      SU_DEBUG_9(("su_localinfo: if %s with index %d is down\n",
		  if_name, if_index));
      continue;
    }
#elif defined(SIOCGIFACTIVECONF)
/* Handled above in SIOCGIFACTIVECONF vs. SIOCGIFCONF*/
#else
#error su_localinfo() cannot determine interface status
#endif

#if 0
    *ifreq = *ifr;
    ifreq->ifr_addr.sa_family = AF_INET;
    if (ioctl(s, SIOCGIFADDR, ifreq) < 0) {
      SU_DEBUG_1(("su_localinfo: SIOCGIFADDR failed: %s\n",
		  su_strerror(su_errno())));
      error = ELI_SYSTEM;
      goto err;
    }
    ifr->ifr_addr = ifreq->ifr_addr;
#endif

    su = (su_sockaddr_t *)&ifr->ifr_addr;

    if (SU_HAS_INADDR_ANY(su))
      continue;

    scope = li_scope4(su->su_sin.sin_addr.s_addr);

    if ((hints->li_scope && (hints->li_scope & scope) == 0) ||
	(hints->li_ifname && strcmp(hints->li_ifname, if_name) != 0) ||
	(hints->li_index && hints->li_index != if_index))
      continue;

#if SU_HAVE_IN6
    if (su_xtra) {
      /* Map IPv4 address to IPv6 address */
      memset(su2, 0, sizeof(*su2));
      su2->su_family = AF_INET6;
      ((int32_t*)&su2->su_sin6.sin6_addr)[2] = htonl(0xffff);
      ((int32_t*)&su2->su_sin6.sin6_addr)[3] = su->su_sin.sin_addr.s_addr;
      su = su2;
    }
#endif

    if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
      gni_flags = NI_NUMERICHOST;

    if ((error = li_name(hints, gni_flags, su, &canonname)) < 0)
      goto err;
    else if (error > 0)
      continue;

    if (canonname)
      if (strchr(canonname, ':') ||
	  strspn(canonname, "0123456789.") == strlen(canonname))
	flags |= LI_NUMERIC;

    if (li_first)
      li = li_first;      /* Use li_first with all ifr structs to be freed */
    else if (!(li = calloc(1, (sizeof *li) + su_xtra))) {
      error = ELI_MEMORY;
      goto err;
    }
    if (!tbf) tbf = li;
    *lli = li; lli = &li->li_next;

    if (su_xtra)
      su = (su_sockaddr_t *)memcpy(li + 1, su, su_xtra);

    li->li_flags = flags;
    li->li_family = su->su_family;
    li->li_scope = scope;
    li->li_index = if_index;
    li->li_addrlen = su_sockaddr_size(su);
    li->li_addr = su;
    li->li_canonname = canonname;
    li->li_ifname = if_name;

    canonname = NULL;
    li_first = NULL;
  }

  if (canonname) free(canonname);
  if (li_first) free(li_first);
  su_close(s);

  if (tbf) *rresult = tbf;
  return 0;

err:
  if (canonname) free(canonname);
  if (li_first) free(li_first);
  su_freelocalinfo(tbf);
  su_close(s);

  return error;
}
Example #5
0
/** Build a list of local IPv4 addresses and append it to *rresult. */
static
int localinfo4(su_localinfo_t const *hints, su_localinfo_t **rresult)
{
  su_localinfo_t *li = NULL;
  su_sockaddr_t *su;
  int error = ELI_NOADDRESS;
  char *canonname = NULL;
  su_socket_t s;

#if SU_HAVE_IN6
  int su_xtra = (hints->li_flags & LI_V4MAPPED) ? sizeof(*su) : 0;
#else
  int const su_xtra = 0;
#endif

  struct ifconf ifc;
  int numifs;
  char *buffer;
  struct ifreq *ifr, *ifr_next;

  su_sockaddr_t *sa;
  socklen_t salen = sizeof(*sa);
  int scope = 0, gni_flags = 0;

  s = su_socket(AF_INET, SOCK_DGRAM, 0);
  if (s == -1) {
    SU_DEBUG_1(("su_localinfo: su_socket failed: %s\n",
		su_strerror(su_errno())));
    return ELI_SYSTEM;
  }


  li = calloc(1, (sizeof *li) + (sizeof *sa));
  sa = (void *)(li + 1);

  error = getsockname(s, (struct sockaddr *) sa, &salen);
  if (error < 0 && errno == SOCKET_ERROR) {
    SU_DEBUG_1(("%s: getsockname() failed: %s\n", __func__,
                su_strerror(su_errno())));
  }

  error = bind(s, (struct sockaddr *) sa, salen);

  if (error < 0) {
    SU_DEBUG_1(("%s: bind() failed: %s\n", __func__,
                su_strerror(su_errno())));
    goto err;
  }

  su_close(s);

  scope = li_scope4(sa->su_sin.sin_addr.s_addr);

  if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
    gni_flags = NI_NUMERICHOST;

  if (su_xtra) {
    /* Map IPv4 address to IPv6 address */
    memset(sa, 0, sizeof(*sa));
    sa->su_family = AF_INET6;
    ((int32_t*)&sa->su_sin6.sin6_addr)[3] = sa->su_sin.sin_addr.s_addr;
      ((int32_t*)&sa->su_sin6.sin6_addr)[2] = htonl(0xffff);
  }

  li->li_family = sa->su_family;
  li->li_scope = scope;
  li->li_index = 0;
  li->li_addrlen = su_sockaddr_size(sa);
  li->li_addr = sa;

  if ((error = li_name(hints, gni_flags, sa, &canonname)) < 0)
    goto err;

  if (canonname) {
    if (strchr(canonname, ':') ||
       strspn(canonname, "0123456789.") == strlen(canonname))
	  li->li_flags |= LI_NUMERIC;
  }
  else
    li->li_flags = 0;

  li->li_canonname = canonname;

  canonname = NULL;

  *rresult = li;
  return 0;

err:
  if (canonname) free(canonname);
  if (li) free(li);
  su_close(s);

  return error;
}
Example #6
0
static
int localinfo0(su_localinfo_t const *hints, su_localinfo_t **rresult)
{
  /* This is Windows IPv4 code */
  short family = AF_INET;
  su_socket_t s;
  union {
    SOCKET_ADDRESS_LIST sal[1];
#if HAVE_INTERFACE_INFO_EX
    INTERFACE_INFO_EX   ii[1];
#else
    INTERFACE_INFO      ii[1];
#endif
    char buffer[2048];
  } b = {{ 1 }};
  DWORD salen = sizeof(b);
  int i, error = -1;
#if SU_HAVE_IN6
  int v4_mapped = (hints->li_flags & LI_V4MAPPED) != 0;
#endif
  su_localinfo_t *li, *head = NULL, **next = &head;
  char *canonname = NULL, *if_name = NULL;

  *rresult = NULL;

  s = su_socket(family, SOCK_DGRAM, 0);
  if (s == INVALID_SOCKET) {
    SU_DEBUG_1(("su_getlocalinfo: %s: %s\n", "su_socket",
		            su_strerror(su_errno())));
    return -1;
  }

  /* get the list of known IP address (NT5 and up) */
  if (WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0,
               &b, sizeof(b), &salen, NULL, NULL) == SOCKET_ERROR) {
    SU_DEBUG_1(("su_getlocalinfo: %s: %s\n", "SIO_ADDRESS_LIST_QUERY",
		su_strerror(su_errno())));
    error = -1; goto err;
  }
  if (b.sal->iAddressCount < 1) {
    SU_DEBUG_1(("su_getlocalinfo: no local addresses\n"));
    error = -1; goto err;
  }

  for (i = 0; i < b.sal->iAddressCount; i++) {
    su_sockaddr_t *su = (su_sockaddr_t *)b.sal->Address[i].lpSockaddr;
#if SU_HAVE_IN6
    socklen_t sulen = v4_mapped ? sizeof(*su) : b.sal->Address[i].iSockaddrLength;
    su_sockaddr_t su2[1];
#else
    socklen_t sulen = b.sal->Address[i].iSockaddrLength;
#endif
    int scope, flags = 0, gni_flags = 0;

    scope = li_scope4(su->su_sin.sin_addr.s_addr);

    if (hints->li_scope && (hints->li_scope & scope) == 0)
      continue;

    if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK)
      gni_flags = NI_NUMERICHOST;

    if (!(li = calloc(1, sizeof(*li) + sulen))) {
      SU_DEBUG_1(("su_getlocalinfo: memory exhausted\n"));
      error = -1; goto err;
    }
    *next = li, next = &li->li_next;

#if SU_HAVE_IN6
    if (v4_mapped) {
      /* Map IPv4 address to IPv6 address */
      memset(su2, 0, sizeof(*su2));
      su2->su_family = AF_INET6;
      ((int32_t*)&su2->su_sin6.sin6_addr)[2] = htonl(0xffff);
      ((int32_t*)&su2->su_sin6.sin6_addr)[3] = su->su_sin.sin_addr.s_addr;
      su = su2;
    }
#endif

    if ((error = li_name(hints, gni_flags, su, &canonname)) < 0)
      goto err;
    else if (error > 0)
      continue;

    if (canonname)
      if (strchr(canonname, ':') ||
	  strspn(canonname, "0123456789.") == strlen(canonname))
	flags |= LI_NUMERIC;

    li->li_flags = flags;
    li->li_family = su->su_family;
    li->li_scope = scope;
    li->li_index = i;
    li->li_addrlen = su_sockaddr_size(su);
    li->li_addr = su;
    li->li_canonname = canonname, canonname = NULL;
    if (hints->li_flags & LI_IFNAME)
      li->li_ifname = if_name;
    li->li_addr = (su_sockaddr_t *)(li + 1);
    li->li_addrlen = sulen;
    memcpy(li->li_addr, su, sulen);
  }

  *rresult = head;
  su_close(s);

  return 0;

err:
  if (canonname) free(canonname);
  su_freelocalinfo(head);
  su_close(s);

  return error;
}
Example #7
0
/* Use HOSTADDR6 */
static
int localinfo6(su_localinfo_t const *hints, su_localinfo_t **rresult)
{
  char *addr, *ifname;
  int flags, error;
  su_localinfo_t *li = NULL;
  su_sockaddr_t *su;
  int const su_sockaddr_size = sizeof(*su);

  error = ELI_NOADDRESS;

#if defined(__APPLE_CC__)
  {
    su_sockaddr_t *sa;
    int salen = sizeof(*sa);
    int s;

    if (hints->li_scope == 0 || (hints->li_scope & LI_SCOPE_GLOBAL)) {
      if ((addr = getenv("HOSTADDR6"))) {

	li = calloc(1, sizeof(su_localinfo_t));
	sa = calloc(1, sizeof(su_sockaddr_t));

	sa->su_family = AF_INET6;
	if (su_inet_pton(AF_INET6, addr, &sa->su_sin6.sin6_addr) <= 0)
	  goto err;

	s = su_socket(AF_INET6, SOCK_DGRAM, 0);
	if (s == -1) {
	  SU_DEBUG_1(("su_localinfo: su_socket failed: %s\n",
		      su_strerror(su_errno())));
	  return ELI_SYSTEM;
	}

	error = getsockname(s, (struct sockaddr *) sa, &salen);
	if (error < 0 && errno == SOCKET_ERROR) {
	  SU_DEBUG_1(("%s: getsockname() failed: %s\n", __func__,
		      su_strerror(su_errno())));
	}

	error = bind(s, (struct sockaddr *) sa, salen);

	if (error < 0) {
	  SU_DEBUG_1(("%s: bind() failed: %s\n", __func__,
		      su_strerror(su_errno())));
	  goto err;
	}

	su_close(s);

	li->li_family = sa->su_family;
	li->li_scope = LI_SCOPE_GLOBAL;
	li->li_index = 0;
	li->li_addrlen = su_sockaddr_size(sa);
	li->li_addr = sa;

	if ((error = li_name(hints, NI_NUMERICHOST, sa, &li->li_canonname)) < 0)
	  goto err;

	li->li_flags = NI_NUMERICHOST;
      }
    }

    *rresult = li;
    return 0;
  }
#endif


  if (hints->li_scope == 0 || (hints->li_scope & LI_SCOPE_GLOBAL)) {
    if ((addr = getenv("HOSTADDR6"))) {
      flags = hints->li_flags & (LI_CANONNAME|LI_NUMERIC|LI_IFNAME);

      if ((li = calloc(1, sizeof(*li) + su_sockaddr_size)) == NULL) {
	error = ELI_MEMORY;
	goto err;
      }
      li->li_flags = flags;
      li->li_scope = LI_SCOPE_GLOBAL, li->li_index = 2, ifname = "eth";
      li->li_addrlen = sizeof(*su);
      li->li_addr = su = (su_sockaddr_t *)(li + 1);
      su->su_family = li->li_family = AF_INET6;
      if (su_inet_pton(AF_INET6, addr, &su->su_sin6.sin6_addr) <= 0)
	goto err;
      if (li->li_flags & LI_IFNAME)
	li->li_ifname = ifname;
      if ((error = li_name(hints, NI_NUMERICHOST, su, &li->li_canonname)) < 0)
	goto err;
      else if (error > 0) {
	free(li); li = NULL;
      }
    }
  }

  *rresult = li;

  return 0;

err:
  if (li) su_freelocalinfo(li);
  return error;
}
Example #8
0
int su_close_wrp(lua_State *L) {
	su_state *s = (su_state*)lua_touserdata(L, -1);
	su_close(s);
	return 0;
}
Example #9
0
static int test_sockaddr(void)
{
  su_localinfo_t hints[1] = {{ LI_CANONNAME }};
  su_localinfo_t *li, *res = NULL;
  int s;
  su_sockaddr_t  su[1], a[1], b[1];

  BEGIN();

  hints->li_family = AF_INET;

  TEST(su_getlocalinfo(hints, &res), 0);

  for (li = res; li; li = li->li_next) {
    if (li->li_addrlen != res->li_addrlen ||
	memcmp(li->li_addr, res->li_addr, li->li_addrlen) != 0)
      TEST_1(su_cmp_sockaddr(li->li_addr, res->li_addr) != 0);
    else
      TEST_1(su_cmp_sockaddr(li->li_addr, res->li_addr) == 0);
  }

  memset(su, 0, sizeof su);
  TEST(su_getlocalip(su), 0);

  if (res->li_family == AF_INET)
    TEST(su_cmp_sockaddr(res->li_addr, su), 0);

  TEST_1(su_gli_strerror(ELI_NOERROR));
  TEST_1(su_gli_strerror(ELI_NOADDRESS));
  TEST_1(su_gli_strerror(ELI_FAMILY));
  TEST_1(su_gli_strerror(ELI_MEMORY));
  TEST_1(su_gli_strerror(ELI_RESOLVER));
  TEST_1(su_gli_strerror(ELI_SYSTEM));
  TEST_1(su_gli_strerror(-100));

  li = su_copylocalinfo(res); TEST_1(li);
  su_freelocalinfo(li);

  s = su_socket(res->li_family, SOCK_DGRAM, 0); TEST_1(s != -1);
  TEST(su_setblocking(s, 0), 0);
  TEST(su_setblocking(s, 1), 0);
  TEST(su_close(s), 0);

  su_freelocalinfo(res), res = NULL;

#if SU_HAVE_IN6
  hints->li_family = AF_INET6;
  hints->li_flags &= ~LI_CANONNAME;
  hints->li_flags |= LI_V4MAPPED;

  TEST(su_getlocalinfo(hints, &res), 0);
  for (li = res; li; li = li->li_next)
    TEST(li->li_family, AF_INET6);

  su_freelocalinfo(res), res = NULL;
#endif

  hints->li_flags |= LI_NUMERIC;
  TEST(su_getlocalinfo(hints, &res), 0);
  su_freelocalinfo(res), res = NULL;

  res = NULL;
  hints->li_flags |= LI_NAMEREQD;
  su_getlocalinfo(hints, &res);
  su_freelocalinfo(res), res = NULL;

  memset(a, 0, sizeof *a);
  memset(b, 0, sizeof *b);

  TEST_1(su_match_sockaddr(a, b));
  b->su_family = AF_INET;
  TEST_1(su_match_sockaddr(a, b));
  a->su_port = htons(12);
  TEST_1(!su_match_sockaddr(a, b));
  b->su_port = htons(12);
  TEST_1(su_match_sockaddr(a, b));
  a->su_sin.sin_addr.s_addr = htonl(0x7f000001);
  TEST_1(su_match_sockaddr(a, b));
  a->su_family = AF_INET;
  TEST_1(!su_match_sockaddr(a, b));
  b->su_sin.sin_addr.s_addr = htonl(0x7f000001);
  TEST_1(su_match_sockaddr(a, b));
  a->su_sin.sin_addr.s_addr = 0;
  TEST_1(su_match_sockaddr(a, b));
#if SU_HAVE_IN6
  a->su_family = AF_INET6;
  TEST_1(!su_match_sockaddr(a, b));
  b->su_family = AF_INET6;
  TEST_1(su_match_sockaddr(a, b));
  b->su_sin6.sin6_addr.s6_addr[15] = 1;
  TEST_1(su_match_sockaddr(a, b));
  TEST_1(!su_match_sockaddr(b, a));
  a->su_sin6.sin6_addr.s6_addr[15] = 2;
  TEST_1(!su_match_sockaddr(a, b));
  a->su_family = 0;
  TEST_1(su_match_sockaddr(a, b));
  TEST_1(!su_match_sockaddr(b, a));
#endif
  END();
}
Example #10
0
/* Test assumptions in su_select_port implementation */
int test_select(void)
{
  su_socket_t s;
  su_sockaddr_t su;
  socklen_t sulen = sizeof su.su_sin;
  size_t bytes;
  fd_set *rset, *wset;
  struct timeval tv;

  BEGIN();

  s = su_socket(AF_INET, SOCK_DGRAM, 0); TEST_1(s != -1);

  memset(&su, 0, sulen);
  su.su_len = sulen;
  su.su_family = AF_INET;
  TEST(su_inet_pton(AF_INET, "127.0.0.1", &su.su_sin.sin_addr), 1);
  TEST(bind(s, &su.su_sa, sulen), 0);
  TEST(getsockname(s, &su.su_sa, &sulen), 0);

  tv.tv_sec = 0; tv.tv_usec = 1000;
  TEST(select(0, NULL, NULL, NULL, &tv), 0);

  bytes = howmany(s);
  TEST_1(rset = malloc(bytes));
  TEST_1(wset = malloc(bytes));

  FD_ZERO_TO(s, rset); FD_ZERO_TO(s, wset); FD_SET(s, wset);
  tv.tv_sec = 0, tv.tv_usec = 1000;
  TEST(select(s + 1, NULL, wset, NULL, &tv), 1);
  TEST_1(FD_ISSET(s, wset));

  FD_ZERO_TO(s, rset); FD_ZERO_TO(s, wset);
  FD_SET(s, rset); FD_SET(s, wset);
  tv.tv_sec = 0, tv.tv_usec = 1000;
  TEST(select(s + 1, rset, wset, NULL, &tv), 1);
  TEST_1(!FD_ISSET(s, rset));
  TEST_1(FD_ISSET(s, wset));

  FD_ZERO_TO(s, rset); FD_ZERO_TO(s, wset);
  FD_SET(s, rset); FD_SET(s, wset);
  tv.tv_sec = 0, tv.tv_usec = 1000;
  TEST(select(s + 1, rset, NULL, NULL, &tv), 0);
  TEST_1(!FD_ISSET(s, rset));

  FD_ZERO_TO(s, rset); FD_ZERO_TO(s, wset);
  FD_SET(s, rset); FD_CLR(s, wset);
  tv.tv_sec = 0, tv.tv_usec = 1000;
  TEST(select(s + 1, rset, wset, NULL, &tv), 0);
  TEST_1(!FD_ISSET(s, rset));
  TEST_1(!FD_ISSET(s, wset));

  TEST(su_sendto(s, "foo", 3, 0, &su, sulen), 3);

  FD_ZERO_TO(s, rset); FD_ZERO_TO(s, wset);
  FD_SET(s, rset); FD_CLR(s, wset);
  tv.tv_sec = 0, tv.tv_usec = 1000;
  TEST(select(s + 1, rset, wset, NULL, &tv), 1);
  TEST_1(FD_ISSET(s, rset));
  TEST_1(!FD_ISSET(s, wset));

  FD_ZERO_TO(s, rset); FD_ZERO_TO(s, wset);
  FD_SET(s, rset); FD_SET(s, wset);
  tv.tv_sec = 0, tv.tv_usec = 1000;
  TEST(select(s + 1, rset, wset, NULL, &tv), 2);
  TEST_1(FD_ISSET(s, rset));
  TEST_1(FD_ISSET(s, wset));

  su_close(s);

  free(wset);
  free(rset);

  END();
}
Example #11
0
int test_sendrecv(void)
{
  su_socket_t s, l, a;
  ssize_t n;
  su_sockaddr_t su, csu;
  socklen_t sulen = sizeof su.su_sin, csulen = sizeof csu.su_sin;
  char b1[8], b2[8], b3[8];
  su_iovec_t sv[3], rv[3];

  sv[0].siv_base = "one!one!", sv[0].siv_len = 8;
  sv[1].siv_base = "two!two!", sv[1].siv_len = 8;
  sv[2].siv_base = "third!", sv[2].siv_len = 6;

  rv[0].siv_base = b1, rv[0].siv_len = 8;
  rv[1].siv_base = b2, rv[1].siv_len = 8;
  rv[2].siv_base = b3, rv[2].siv_len = 8;

  BEGIN();

  s = su_socket(AF_INET, SOCK_DGRAM, 0); TEST_1(s != -1);
  su_setblocking(s, 1);

  memset(&su, 0, sulen);
  su.su_len = sulen;
  su.su_family = AF_INET;
  TEST(su_inet_pton(AF_INET, "127.0.0.1", &su.su_sin.sin_addr), 1);

  TEST(bind(s, &su.su_sa, sulen), 0);
  TEST(getsockname(s, &su.su_sa, &sulen), 0);

  n = su_vsend(s, sv, 3, 0, &su, sulen); TEST(n, 8 + 8 + 6);
  n = su_vrecv(s, rv, 3, 0, &su, &sulen); TEST(n, 8 + 8 + 6);

  TEST_M(rv[0].siv_base, sv[0].siv_base, sv[0].siv_len);
  TEST_M(rv[1].siv_base, sv[1].siv_base, sv[1].siv_len);
  TEST_M(rv[2].siv_base, sv[2].siv_base, sv[2].siv_len);

  su_close(s);

  l = su_socket(AF_INET, SOCK_STREAM, 0); TEST_1(l != -1);
  s = su_socket(AF_INET, SOCK_STREAM, 0); TEST_1(s != -1);

  memset(&su, 0, sulen);
  su.su_len = sulen;
  su.su_family = AF_INET;
  TEST(su_inet_pton(AF_INET, "127.0.0.1", &su.su_sin.sin_addr), 1);

  TEST(bind(l, &su.su_sa, sulen), 0);
  TEST(bind(s, &su.su_sa, sulen), 0);

  TEST(getsockname(l, &su.su_sa, &sulen), 0);
  TEST(listen(l, 5), 0);

  TEST(su_setblocking(s, 1), 0);

  TEST(connect(s, &su.su_sa, sulen), 0);
  a = accept(l, &csu.su_sa, &csulen); TEST_1(a != -1);

  TEST(su_setblocking(a, 1), 0);

  n = su_vsend(s, sv, 3, 0, NULL, 0); TEST(n, 8 + 8 + 6);
  n = su_vrecv(a, rv, 3, 0, NULL, NULL); TEST(n, 8 + 8 + 6);

  TEST_M(rv[0].siv_base, sv[0].siv_base, sv[0].siv_len);
  TEST_M(rv[1].siv_base, sv[1].siv_base, sv[1].siv_len);
  TEST_M(rv[2].siv_base, sv[2].siv_base, sv[2].siv_len);

  n = send(a, "", 0, 0); TEST(n, 0);
  n = su_vsend(a, sv, 3, 0, NULL, 0); TEST(n, 8 + 8 + 6);

  {
    su_wait_t w[1] = { SU_WAIT_INIT };

    TEST(su_wait_create(w, s, SU_WAIT_IN | SU_WAIT_HUP), 0);

    TEST(su_wait(w, 0, 500), SU_WAIT_TIMEOUT);

    TEST(su_wait(w, 1, 500), 0);
    TEST(su_wait_events(w, s), SU_WAIT_IN);

    TEST_SIZE(su_getmsgsize(s), 8 + 8 + 6);
    n = su_vrecv(s, rv, 3, 0, NULL, NULL); TEST(n, 8 + 8 + 6);

    TEST(su_wait(w, 1, 100), SU_WAIT_TIMEOUT);

    shutdown(a, 2);

    TEST(su_wait(w, 1, 100), 0);
#if SU_HAVE_WINSOCK
    TEST_1(su_wait_events(w, s) & SU_WAIT_HUP);
#else
    TEST_1(su_wait_events(w, s));
    n = su_vrecv(s, rv, 3, 0, NULL, NULL); TEST(n, 0);
#endif

    su_wait_destroy(w);
  }

  su_close(a);

  su_close(l);
  su_close(s);

  END();
}
Example #12
0
    int su_compile(su_state *s, const char *code, const char *name, char **inline_c, char **result, size_t *size) {
        const char *tmp;
        size_t buffer_size;
        lua_State *L = lua_open();
        su_state *sc = su_init(su_allocator(s));
        su_libinit(sc);
        ___saurus(sc);

        luaL_openlibs(L);
        luaopen_writebin(L);

        if (luaL_loadstring(L, compiler_code)) {
            *result = dup(s, lua_tostring(L, -1));
            if (size) *size = strlen(*result);
            lua_close(L);
            su_close(sc);
            return -1;
        }

        if (lua_pcall(L, 0, 0, 0)) {
            lua_getglobal(L, "saurus_error");
            if (lua_isnil(L, -1))
                lua_pop(L, 1);
            *result = dup(s, lua_tostring(L, -1));
            if (size) *size = strlen(*result);
            lua_close(L);
            su_close(sc);
            return -2;
        }

        lua_getglobal(L, "repl");
        lua_pushstring(L, code);
        lua_pushstring(L, name ? name : "?");
        if (lua_pcall(L, 2, 1, 0)) {
            lua_getglobal(L, "saurus_error");
            if (lua_isnil(L, -1)) {
                lua_pop(L, 1);
                *result = dup(s, lua_tostring(L, -1));
            } else {
                *result = dup(s, lua_tostring(L, -1));
            }
            if (size) *size = strlen(*result);
            lua_close(L);
            su_close(sc);
            return -3;
        }

        tmp = lua_tolstring(L, -1, &buffer_size);
        *result = (char*)su_allocate(s, NULL, buffer_size);
        memcpy(*result, tmp, buffer_size);
        if (size) *size = buffer_size;

        if (inline_c) {
            lua_getglobal(L, "c_code");
            if (lua_isnil(L, -1))
                tmp = lua_tostring(L, -1);
            *inline_c = (char*)su_allocate(s, NULL, strlen(tmp) + 1);
            strcpy(*inline_c, tmp);
        }

        lua_close(L);
        su_close(sc);
        return 0;
    }
Example #13
0
    int main(int argc, char *argv[]) {
    	int ret, i;
    	int compile;
    	FILE *fp;
    	jmp_buf err;
    	su_state *s;
    	lua_State *L;
    	char *tmp;
    	const char *tmp2;
    	const char *input, *output;
    	int print_help = argc > 1 && strstr("-h -v --help --version", argv[1]) != NULL;
    	int pipe = argc > 1 && !strcmp("--", argv[1]);

        compiler = su_init(NULL);
        su_libinit(compiler);
        ___saurus(compiler);
        atexit(shutdown);

    	if (!pipe && (argc <= 1 || print_help)) {
    		printf("S A U R U S\nCopyright (c) 2009-2015 Andreas T Jonsson <*****@*****.**>\nVersion: %s\n\n", su_version(NULL, NULL, NULL));
    		if (print_help) {
    			puts("Usage: saurus <options> <input.su> <output.suc>\n\tOptions:\n\t\t'-c' Compile source file to binary file.\n\t\t'--' read from STDIN.");
    			return 0;
    		}
    	}

    	s = su_init(NULL);
    	su_libinit(s);

    	L = lua_open();
    	luaL_openlibs(L);
    	luaopen_writebin(L);

    	if (luaL_loadstring(L, compiler_code)) {
    		fprintf(stderr, "%s\n", lua_tostring(L, -1));
    		lua_close(L);
    		su_close(s);
    		return -1;
    	}

    	if (lua_pcall(L, 0, 0, 0)) {
    		lua_getglobal(L, "saurus_error");
    		if (lua_isnil(L, -1))
    			lua_pop(L, 1);
    		fprintf(stderr, "%s\n", lua_tostring(L, -1));
    		lua_close(L);
    		su_close(s);
    		return -1;
    	}

    	ret = 0;
    	if (argc < 2 || pipe) {
    		if (!pipe)
    			puts("Type '_h' for help or '_q' to exit.\n");
    		su_pushstring(s, repl_help_text);
    		su_setglobal(s, "_h");
    		su_pushstring(s, "_q");
    		su_setglobal(s, "_q");

    		ret = setjmp(err);
    		if (!pipe)
    			su_seterror(s, err, ret);

    		jump: for (;;) {
    			if (!pipe)
    				printf("> ");
    			fgets(buffer, BUFFER_SIZE, stdin);

    			lua_getglobal(L, "repl");
    			lua_pushstring(L, buffer);
    			lua_pushstring(L, argv[0]);
    			if (lua_pcall(L, 2, 1, 0)) {
    				lua_getglobal(L, "saurus_error");
    				if (lua_isnil(L, -1)) {
    					lua_pop(L, 1);
    					puts(lua_tostring(L, -1));
    				} else {
    					puts(lua_tostring(L, -1));
    					lua_pop(L, 1);
    				}
    				lua_pop(L, 1);
    				goto jump;
    			}

    			lua_getglobal(L, "c_code");
    			su_assert(s, lua_isnil(L, -1), "Inline C is not supported in interpreter!");
    			lua_pop(L, 1);

    			tmp2 = lua_tolstring(L, -1, NULL);
    			su_assert(s, su_getglobal(s, "io"), "Could not retrieve 'io' namespace.");
    			su_pushstring(s, "print");
    			su_assert(s, su_map_get(s, -2), "Could not retrieve 'print' function.");

    			if (su_load(s, NULL, (void*)tmp2)) {
    				su_close(s);
    				lua_close(L);
    				fprintf(stderr, "Could not load: %s\n", argv[1]);
    				return -1;
    			}

    			lua_pop(L, 1);
    			su_call(s, 0, 1);
    			if (su_type(s, -1) == SU_STRING && !strcmp(su_tostring(s, -1, NULL), "_q")) {
    				ret = 0;
    				break;
    			}
    			su_call(s, 1, 0);
    			su_pop(s, 1);
    		}
    	} else {
    		compile = !strcmp(argv[1], "-c");
    		input = compile ? argv[2] : argv[1];

    		if (compile) {
    			if (argc < 4) {
    				fputs("Expected input and output file!", stderr);
    				lua_close(L);
    				su_close(s);
    				return -1;
    			}
    		} else {
    			fp = fopen(input, "rb");
    			if (!fp) {
    				fprintf(stderr, "Could not open: %s\n", input);
    				lua_close(L);
    				su_close(s);
    				return -1;
    			}

    			if (fread(buffer, 1, 1, fp) == 1) {
    				if (*buffer == '\x1b') {
    					rewind(fp);
    					if (su_load(s, &reader_fp, fp)) {
    						su_close(s);
    						lua_close(L);
    						fclose(fp);
    						fprintf(stderr, "Could not load: %s\n", input);
    						return -1;
    					}

    					su_pushstring(s, input);
    					for (i = 2; i < argc; i++)
                            su_pushstring(s, argv[i]);

                        su_call(s, argc - 1, 1);
                        if (su_type(s, -1) == SU_NUMBER)
                            ret = (int)su_tonumber(s, -1);

    					su_close(s);
    					lua_close(L);
    					fclose(fp);
    					return ret;
    				}
    			}
    			fclose(fp);
    		}

    		tmp = tmpnam(buffer);
    		output = compile ? argv[3] : tmp;

    		lua_getglobal(L, "compile");
    		lua_pushstring(L, input);
    		lua_pushstring(L, output);
    		lua_pushboolean(L, compile);
    		if (lua_pcall(L, 3, 0, 0)) {
    			lua_getglobal(L, "saurus_error");
    			if (lua_isnil(L, -1))
    				lua_pop(L, 1);
    			fprintf(stderr, "%s\n", lua_tostring(L, -1));
    			lua_close(L);
    			su_close(s);
    			return -1;
    		}

    		if (!compile) {
    			fp = fopen(output, "rb");
    			if (!fp) {
    				fprintf(stderr, "Could not open: %s\n", output);
    				lua_close(L);
    				su_close(s);
    				return -1;
    			}

    			if (su_load(s, &reader_fp, fp)) {
    				su_close(s);
    				lua_close(L);
    				fclose(fp);
    				remove(tmp);
    				fprintf(stderr, "Could not load: %s\n", output);
    				return -1;
    			}

    			fclose(fp);
    			remove(tmp);

    			su_pushstring(s, argv[1]);
    			for (i = 2; i < argc; i++)
    				su_pushstring(s, argv[i]);

                su_call(s, argc - 1, 1);
    			if (su_type(s, -1) == SU_NUMBER)
                    ret = (int)su_tonumber(s, -1);
    		}
    	}

    	lua_close(L);
    	su_close(s);
    	return ret;
    }
Example #14
0
 void shutdown() {
     su_close(compiler);
 }