示例#1
0
static int ctrl_listen(const char *host, const char *port,
                       struct addrinfo **ai, struct options *opts,
                       struct callbacks *cb)
{
        struct addrinfo *result, *rp;
        int flags = AI_PASSIVE;
        int fd_listen = 0;

        result = do_getaddrinfo(host, port, flags, opts, cb);
        for (rp = result; rp != NULL; rp = rp->ai_next) {
                fd_listen = socket(rp->ai_family, rp->ai_socktype,
                                   rp->ai_protocol);
                if (fd_listen == -1) {
                        PLOG_ERROR(cb, "socket");
                        continue;
                }
                set_reuseport(fd_listen, cb);
                set_reuseaddr(fd_listen, 1, cb);
                if (bind(fd_listen, rp->ai_addr, rp->ai_addrlen) == 0)
                        break;
                PLOG_ERROR(cb, "bind");
                do_close(fd_listen);
        }
        if (rp == NULL)
                LOG_FATAL(cb, "Could not bind");
        *ai = copy_addrinfo(rp);
        freeaddrinfo(result);
        if (listen(fd_listen, opts->listen_backlog))
                PLOG_FATAL(cb, "listen");
        return fd_listen;
}
示例#2
0
/*
 * Do another pass over the array to check for missing addresses and
 * try resolving the names.  Normally, the DNS response from AD will
 * have supplied additional address records for all the SRV records.
 */
static void
get_addresses(ad_disc_cds_t *cds, int cnt)
{
	int i;

	for (i = 0; i < cnt; i++) {
		if (cds[i].cds_ai == NULL) {
			do_getaddrinfo(&cds[i]);
		}
	}
}
示例#3
0
static intptr_t getaddrinfo_in_thread(void *_data)
{
  rktio_t *rktio = (rktio_t *)_data;
  rktio_addrinfo_lookup_t *lookup;
  rktio_addrinfo_t *result;
  int err;

  ghbn_lock(rktio);
  while (rktio->ghbn_run) {
    lookup = rktio->ghbn_requests;
    if (lookup) {
      rktio->ghbn_requests = lookup->next;
      ghbn_unlock(rktio);

      /* Handle one lookup request: */
      err = do_getaddrinfo(lookup->name, lookup->svc, lookup->hints, &result);
      lookup->err = err;
      if (!err)
        lookup->result = result;

      ghbn_lock(rktio);

# ifdef RKTIO_SYSTEM_WINDOWS
      ReleaseSemaphore(lookup->done_sema, 1, NULL);  
# else
      {
        long v = 1;
        do {
          err = write(lookup->done_fd[1], &v, sizeof(v));
        } while ((err == -1) && (errno == EINTR));
        rktio_reliably_close(lookup->done_fd[1]);
      }
# endif

      if (lookup->mode == GHBN_ABANDONED) {
# ifdef RKTIO_SYSTEM_WINDOWS
        CloseHandle(lookup->done_sema);
# else
        rktio_reliably_close(lookup->done_fd[0]);
# endif
        free_lookup(lookup);
      }
    } else {
      ghbn_wait(rktio);
    }
  }

  ghbn_unlock(rktio);
  
  return 0;
}
示例#4
0
static int resolve_addr(server_generic_t *server, const char *addr, unsigned int port)
{
        struct addrinfo *ai;
        int ret, ai_family, ai_addrlen;

#if ! ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        const char *unixpath = NULL;

        if ( is_unix_addr(&unixpath, addr) ) {
                ai_family = AF_UNIX;
                ai_addrlen = sizeof(struct sockaddr_un);
        }

        else {
#endif
                ret = do_getaddrinfo(&ai, addr, port);
                if ( ret < 0 )
                        return ret;

                ai_family = ai->ai_family;
                ai_addrlen = ai->ai_addrlen;
#if ! ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        }
#endif

        server->sa = malloc(ai_addrlen);
        if ( ! server->sa ) {
                freeaddrinfo(ai);
                return prelude_error_from_errno(errno);
        }

        server->slen = ai_addrlen;
        server->sa->sa_family = ai_family;

        if ( ai_family != AF_UNIX ) {
                memcpy(server->sa, ai->ai_addr, ai->ai_addrlen);
                freeaddrinfo(ai);
        }

#if ! ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
        else {
                struct sockaddr_un *un = (struct sockaddr_un *) server->sa;
                strncpy(un->sun_path, unixpath, sizeof(un->sun_path));
        }
#endif

        return 0;
}
示例#5
0
rktio_addrinfo_t *rktio_addrinfo_lookup_get(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup)
{
  int err;
  rktio_addrinfo_t *result;

  err = do_getaddrinfo(lookup->name, lookup->svc, lookup->hints, &result);
  if (err)
    set_gai_error(err);
  
  free_lookup(lookup);

  if (err)
    return NULL;
  else
    return result;
}
static int do_standalone_mode(int daemonize)
{
	struct addrinfo *ai_head;
	int sockfdlist[MAXSOCKFD];
	int nsockfd;
	int i, terminate;
	struct pollfd *fds;
	struct timespec timeout;
	sigset_t sigmask;

	if (usbip_host_driver_open()) {
		err("please load " USBIP_CORE_MOD_NAME ".ko and "
		    USBIP_HOST_DRV_NAME ".ko!");
		return -1;
	}

	if (daemonize) {
		if (daemon(0, 0) < 0) {
			err("daemonizing failed: %s", strerror(errno));
			usbip_host_driver_close();
			return -1;
		}
		umask(0);
		usbip_use_syslog = 1;
	}
	set_signal();

	ai_head = do_getaddrinfo(NULL, PF_UNSPEC);
	if (!ai_head) {
		usbip_host_driver_close();
		return -1;
	}

	info("starting " PROGNAME " (%s)", usbip_version_string);

	nsockfd = listen_all_addrinfo(ai_head, sockfdlist);
	if (nsockfd <= 0) {
		err("failed to open a listening socket");
		freeaddrinfo(ai_head);
		usbip_host_driver_close();
		return -1;
	}
	fds = calloc(nsockfd, sizeof(struct pollfd));
	for (i = 0; i < nsockfd; i++) {
		fds[i].fd = sockfdlist[i];
		fds[i].events = POLLIN;
	}
	timeout.tv_sec = MAIN_LOOP_TIMEOUT;
	timeout.tv_nsec = 0;

	sigfillset(&sigmask);
	sigdelset(&sigmask, SIGTERM);
	sigdelset(&sigmask, SIGINT);

	terminate = 0;
	while (!terminate) {
		int r;

		r = ppoll(fds, nsockfd, &timeout, &sigmask);
		if (r < 0) {
			dbg("%s", strerror(errno));
			terminate = 1;
		} else if (r) {
			for (i = 0; i < nsockfd; i++) {
				if (fds[i].revents & POLLIN) {
					dbg("read event on fd[%d]=%d",
					    i, sockfdlist[i]);
					process_request(sockfdlist[i]);
				}
			}
		} else
			dbg("heartbeat timeout on ppoll()");
	}

	info("shutting down " PROGNAME);
	free(fds);
	freeaddrinfo(ai_head);
	usbip_host_driver_close();

	return 0;
}
示例#7
0
int zmq::ip_resolver_t::resolve_getaddrinfo (ip_addr_t *ip_addr_,
                                             const char *addr_)
{
#if defined ZMQ_HAVE_OPENVMS && defined __ia64
    __addrinfo64 *res = NULL;
    __addrinfo64 req;
#else
    addrinfo *res = NULL;
    addrinfo req;
#endif

    memset (&req, 0, sizeof (req));

    //  Choose IPv4 or IPv6 protocol family. Note that IPv6 allows for
    //  IPv4-in-IPv6 addresses.
    req.ai_family = options.ipv6 () ? AF_INET6 : AF_INET;

    //  Arbitrary, not used in the output, but avoids duplicate results.
    req.ai_socktype = SOCK_STREAM;

    req.ai_flags = 0;

    if (options.bindable ()) {
        req.ai_flags |= AI_PASSIVE;
    }

    if (!options.allow_dns ()) {
        req.ai_flags |= AI_NUMERICHOST;
    }

#if defined AI_V4MAPPED
    //  In this API we only require IPv4-mapped addresses when
    //  no native IPv6 interfaces are available (~AI_ALL).
    //  This saves an additional DNS roundtrip for IPv4 addresses.
    if (req.ai_family == AF_INET6) {
        req.ai_flags |= AI_V4MAPPED;
    }
#endif

    //  Resolve the literal address. Some of the error info is lost in case
    //  of error, however, there's no way to report EAI errors via errno.
    int rc = do_getaddrinfo (addr_, NULL, &req, &res);

#if defined AI_V4MAPPED
    // Some OS do have AI_V4MAPPED defined but it is not supported in getaddrinfo()
    // returning EAI_BADFLAGS. Detect this and retry
    if (rc == EAI_BADFLAGS && (req.ai_flags & AI_V4MAPPED)) {
        req.ai_flags &= ~AI_V4MAPPED;
        rc = do_getaddrinfo (addr_, NULL, &req, &res);
    }
#endif

#if defined ZMQ_HAVE_WINDOWS
    //  Resolve specific case on Windows platform when using IPv4 address
    //  with ZMQ_IPv6 socket option.
    if ((req.ai_family == AF_INET6) && (rc == WSAHOST_NOT_FOUND)) {
        req.ai_family = AF_INET;
        rc = do_getaddrinfo (addr_, NULL, &req, &res);
    }
#endif

    if (rc) {
        switch (rc) {
            case EAI_MEMORY:
                errno = ENOMEM;
                break;
            default:
                if (options.bindable ()) {
                    errno = ENODEV;
                } else {
                    errno = EINVAL;
                }
                break;
        }
        return -1;
    }

    //  Use the first result.
    zmq_assert (res != NULL);
    zmq_assert ((size_t) res->ai_addrlen <= sizeof (*ip_addr_));
    memcpy (ip_addr_, res->ai_addr, res->ai_addrlen);

    //  Cleanup getaddrinfo after copying the possibly referenced result.
    do_freeaddrinfo (res);

    return 0;
}