Пример #1
0
static void do_standalone_mode(gboolean daemonize)
{
	int ret;
	int lsock[MAXSOCK];
	struct addrinfo *ai_head;
	int n;



	ret = usbip_names_init(USBIDS_FILE);
	if (ret)
		err("open usb.ids");

	ret = usbip_stub_driver_open();
	if (ret < 0)
		g_error("driver open failed");

	if (daemonize) {
		if (daemon(0,0) < 0)
			g_error("daemonizing failed: %s", g_strerror(errno));

		usbip_use_syslog = 1;
	}

	set_signal();

	ai_head = my_getaddrinfo(NULL, PF_UNSPEC);
	if (!ai_head)
		return;

	n = listen_all_addrinfo(ai_head, lsock);
	if (n <= 0)
		g_error("no socket to listen to");

	for (int i = 0; i < n; i++) {
		GIOChannel *gio;

		gio = g_io_channel_unix_new(lsock[i]);
		g_io_add_watch(gio, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
				process_comming_request, NULL);
	}


	info("usbipd start (%s)", version);


	main_loop = g_main_loop_new(FALSE, FALSE);
	g_main_loop_run(main_loop);

	info("shutdown");

	freeaddrinfo(ai_head);
	usbip_names_free();
	usbip_stub_driver_close();

	return;
}
Пример #2
0
static int parse_host(const char* s, struct in_addr* ip_out)
{
  const struct sockaddr_in* sin;
  struct addrinfo* ai;
  if( my_getaddrinfo(s, 0, &ai) < 0 )
    return 0;
  sin = (const struct sockaddr_in*) ai->ai_addr;
  *ip_out = sin->sin_addr;
  return 1;
}
Пример #3
0
static int parse_ip4_port(const char* port, uint16_t* port_out)
{
  int rc;
  struct addrinfo* ai;
  if( (rc = my_getaddrinfo("0", port, &ai)) )
    return rc;
  const struct sockaddr_in* sin = (void*) ai->ai_addr;
  *port_out = sin->sin_port;
  freeaddrinfo(ai);
  return 0;
}
Пример #4
0
static int parse_ip4_host(const char* host, uint32_t* ip_out)
{
  int rc;
  struct addrinfo* ai;
  if( (rc = my_getaddrinfo(host, "0", &ai)) )
    return rc;
  const struct sockaddr_in* sin = (void*) ai->ai_addr;
  *ip_out = sin->sin_addr.s_addr;
  freeaddrinfo(ai);
  return 0;
}
Пример #5
0
pid_t	async_getaddrinfo (const char *nodename, const char *servname, const AI *hints, int fd)
{
	AI *results = NULL;
	ssize_t	err;

#ifdef ASYNC_DNS
	{
	/* XXX Letting /exec clean up after us is a hack. */
	pid_t	helper;
	if ((helper = fork()))
		return helper;
	}
#endif

        if ((err = my_getaddrinfo(nodename, servname, hints, &results)))
        {
		err = -labs(err);		/* Always a negative number */
		if (!write(fd, &err, sizeof(err))) 
			(void) 0;
		close(fd);
#ifdef ASYNC_DNS
		exit(0);
#else
		return 0;
#endif
        }

	if (!results)
	{
		err = 0;
		if (!write(fd, &err, sizeof(err))) 
			(void) 0;
		close(fd);
#ifdef ASYNC_DNS
		exit(0);
#else
		return 0;
#endif
        }

        marshall_getaddrinfo(fd, results);
        my_freeaddrinfo(results);
        close(fd);
#ifdef ASYNC_DNS
	exit(0);
#endif
	return 0;	/* XXX This function should be void */
}
Пример #6
0
/*
 * NAME: inet_strton
 * USAGE: Convert "any" kind of address represented by a string into
 *	  a socket address suitable for connect()ing or bind()ing with.
 * ARGS: hostname - The address to convert.  It may be any of the following:
 *		IPv4 "Presentation Address"	(A.B.C.D)
 *		IPv6 "Presentation Address"	(A:B::C:D)
 *		Hostname			(foo.bar.com)
 *		32 bit host order ipv4 address	(2134546324)
 *	 storage - A pointer to a (struct sockaddr_storage) with the 
 *		"family" argument filled in (AF_INET or AF_INET6).  
 *		If "hostname" is a p-addr, then the form of the p-addr
 *		must agree with the family in 'storage'.
 */
int	inet_strton (const char *host, const char *port, SA *storage, int flags)
{
	int family = storage->sa_family;

        /* First check for legacy 32 bit integer DCC addresses */
	if ((family == AF_INET || family == AF_UNSPEC) && host && is_number(host))
	{
		((ISA *)storage)->sin_family = AF_INET;
#ifdef HAVE_SA_LEN
		((ISA *)storage)->sin_len = sizeof(ISA);
#endif
		((ISA *)storage)->sin_addr.s_addr = htonl(strtoul(host, NULL, 10));
		if (port)
			((ISA *)storage)->sin_port = htons((unsigned short)strtoul(port, NULL, 10));
		return 0;
	}
	else
	{
		AI hints;
		AI *results;
		int retval;

		memset(&hints, 0, sizeof(hints));
		hints.ai_flags = flags;
		hints.ai_family = family;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_protocol = 0;

		if ((retval = my_getaddrinfo(host, port, &hints, &results))) 
		{
			syserr(-1, "inet_strton: my_getaddrinfo(%s,%s) failed: %s", 
					host, port, gai_strerror(retval));
			return -1;
		}

		/* memcpy can bite me. */
		memcpy(storage, results->ai_addr, results->ai_addrlen);

		my_freeaddrinfo(results);
		return 0;
	}
}
Пример #7
0
/*
 * NAME: inet_vhostsockaddr
 * USAGE: Get the sockaddr of the current virtual host, if one is in use.
 * ARGS: family - The family whose sockaddr info is to be retrieved
 *       storage - Pointer to a sockaddr structure appropriate for family.
 *       len - This will be set to the size of the sockaddr structure that
 *             was copied, or set to 0 if no virtual host is available in
 *             the given family.
 * NOTES: If "len" is set to 0, do not attempt to bind() 'storage'!
 */
int	inet_vhostsockaddr (int family, int port, const char *wanthost, SS *storage, socklen_t *len)
{
	char	p_port[12];
	char	*p = NULL;
	AI	hints, *res;
	int	err;
	const char *lhn;

	/*
	 * If port == -1, AND "wanthost" is NULL, then this is a client connection, 
	 * so we punt if there is no virtual host name.  But if port is NOT zero, 
	 * then the caller expects us to return a sockaddr they can bind() to, 
	 * so we need to use LocalIPv(4|6)HostName, even if it's NULL.  If you 
	 * return *len == 0 for port != -1, then /dcc breaks.
	 */
	if ((family == AF_UNIX) || 
            (family == AF_INET && port == -1 && empty(wanthost) && LocalIPv4HostName == NULL) 
#ifdef INET6
	 || (family == AF_INET6 && port == -1 && empty(wanthost) && LocalIPv6HostName == NULL)
#endif
									   )
	{
		*len = 0;
		return 0;		/* No vhost needed */
	}

	if (wanthost && *wanthost)
		lhn = wanthost;
	else if (family == AF_INET)
		lhn = LocalIPv4HostName;
#ifdef INET6
	else if (family == AF_INET6)
		lhn = LocalIPv6HostName;
#endif
	else
		lhn = NULL;

	/*
	 * Can it really be this simple?
	 */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;
	if (port != -1) 
	{
		hints.ai_flags = AI_PASSIVE;
		snprintf(p_port, 12, "%d", port);
		p = p_port;
	}

	if ((err = my_getaddrinfo(lhn, p, &hints, &res)))
	{
		syserr(-1, "inet_vhostsockaddr: my_getaddrinfo(%s,%s) failed: %s", 
				lhn, p, gai_strerror(err));
		return -1;
	}

	memcpy(storage, res->ai_addr, res->ai_addrlen);
	my_freeaddrinfo(res);
	*len = socklen((SA *)storage);
	return 0;
}
Пример #8
0
/* Resolve a name and return a pointer in the 'entry' argument if one
   is available.

   Return codes:

   -1 = error, no pointer
   0 = OK, pointer provided
   1 = waiting for response, no pointer
*/
int Curl_resolv(struct connectdata *conn,
                char *hostname,
                int port,
                struct Curl_dns_entry **entry)
{
  char *entry_id = NULL;
  struct Curl_dns_entry *dns = NULL;
  size_t entry_len;
  int wait;
  struct SessionHandle *data = conn->data;
  CURLcode result;

  /* default to failure */
  int rc = -1;
  *entry = NULL;

#ifdef HAVE_SIGSETJMP
  /* this allows us to time-out from the name resolver, as the timeout
     will generate a signal and we will siglongjmp() from that here */
  if(!data->set.no_signal && sigsetjmp(curl_jmpenv, 1)) {
    /* this is coming from a siglongjmp() */
    failf(data, "name lookup timed out");
    return -1;
  }
#endif

  /* Create an entry id, based upon the hostname and port */
  entry_id = create_hostcache_id(hostname, port, &entry_len);
  /* If we can't create the entry id, fail */
  if (!entry_id)
    return -1;

  if(data->share)
    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);

  /* See if its already in our dns cache */
  dns = Curl_hash_pick(data->hostcache, entry_id, entry_len+1);
  
  if(data->share)
    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);

  /* free the allocated entry_id again */
  free(entry_id);

  if (!dns) {
    /* The entry was not in the cache. Resolve it to IP address */
      
    /* If my_getaddrinfo() returns NULL, 'wait' might be set to a non-zero
       value indicating that we need to wait for the response to the resolve
       call */
    Curl_addrinfo *addr = my_getaddrinfo(conn, hostname, port, &wait);
    
    if (!addr) {
      if(wait) {
        /* the response to our resolve call will come asynchronously at 
           a later time, good or bad */
        /* First, check that we haven't received the info by now */
        result = Curl_is_resolved(conn, &dns);
        if(result) /* error detected */
          return -1;
        if(dns)
          rc = 0; /* pointer provided */
        else
          rc = 1; /* no info yet */
      }
    }
    else {
      if(data->share)
        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);

      /* we got a response, store it in the cache */
      dns = cache_resolv_response(data, addr, hostname, port);
      
      if(data->share)
        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);

      if(!dns)
        /* returned failure, bail out nicely */
        Curl_freeaddrinfo(addr);
      else
        rc = 0;
    }
  }
  else {
    dns->inuse++; /* we use it! */
    rc = 0;
  }

  *entry = dns;

  return rc;
}