コード例 #1
0
ファイル: common.c プロジェクト: hyc/heimdal
int
client_doit (const char *hostname, int port, const char *service,
	     int (*func)(int, const char *hostname, const char *service))
{
    struct addrinfo *ai, *a;
    struct addrinfo hints;
    int error;
    char portstr[NI_MAXSERV];

    memset (&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    snprintf (portstr, sizeof(portstr), "%u", ntohs(port));

    error = getaddrinfo (hostname, portstr, &hints, &ai);
    if (error) {
	errx (1, "%s: %s", hostname, gai_strerror(error));
	return -1;
    }

    for (a = ai; a != NULL; a = a->ai_next) {
	int s;

	s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
	if (s < 0)
	    continue;

	socket_set_ipv6only(s, 1);

	if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
	    warn ("connect(%s)", hostname);
	    close (s);
	    continue;
	}
	freeaddrinfo (ai);
	return (*func) (s, hostname, service);
    }
    warnx ("failed to contact %s", hostname);
    freeaddrinfo (ai);
    return 1;
}
コード例 #2
0
void
start_server(krb5_context context, const char *port_str)
{
    int e;
    struct kadm_port *p;

    krb5_socket_t *socks = NULL, *tmp;
    unsigned int num_socks = 0;
    int i;

    if (port_str == NULL)
	port_str = "+";

    parse_ports(context, port_str);

    for(p = kadm_ports; p; p = p->next) {
	struct addrinfo hints, *ai, *ap;
	char portstr[32];
	memset (&hints, 0, sizeof(hints));
	hints.ai_flags    = AI_PASSIVE;
	hints.ai_socktype = SOCK_STREAM;

	e = getaddrinfo(NULL, p->port, &hints, &ai);
	if(e) {
	    snprintf(portstr, sizeof(portstr), "%u", p->def_port);
	    e = getaddrinfo(NULL, portstr, &hints, &ai);
	}

	if(e) {
	    krb5_warn(context, krb5_eai_to_heim_errno(e, errno),
		      "%s", portstr);
	    continue;
	}
	i = 0;
	for(ap = ai; ap; ap = ap->ai_next)
	    i++;
	tmp = realloc(socks, (num_socks + i) * sizeof(*socks));
	if(tmp == NULL) {
	    krb5_warnx(context, "failed to reallocate %lu bytes",
		       (unsigned long)(num_socks + i) * sizeof(*socks));
	    continue;
	}
	socks = tmp;
	for(ap = ai; ap; ap = ap->ai_next) {
	    krb5_socket_t s = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
	    if(rk_IS_BAD_SOCKET(s)) {
		krb5_warn(context, rk_SOCK_ERRNO, "socket");
		continue;
	    }

	    socket_set_reuseaddr(s, 1);
	    socket_set_ipv6only(s, 1);

	    if (rk_IS_SOCKET_ERROR(bind (s, ap->ai_addr, ap->ai_addrlen))) {
		krb5_warn(context, rk_SOCK_ERRNO, "bind");
		rk_closesocket(s);
		continue;
	    }
	    if (rk_IS_SOCKET_ERROR(listen (s, SOMAXCONN))) {
		krb5_warn(context, rk_SOCK_ERRNO, "listen");
		rk_closesocket(s);
		continue;
	    }
	    socks[num_socks++] = s;
	}
	freeaddrinfo (ai);
    }
    if(num_socks == 0)
	krb5_errx(context, 1, "no sockets to listen to - exiting");

    wait_for_connection(context, socks, num_socks);
}
コード例 #3
0
int inet_listen_opts(QemuOpts *opts, int port_offset)
{
    SockAddress**  list;
    SockAddress*   e;
    unsigned       flags = SOCKET_LIST_PASSIVE;
    const char *addr;
    char port[33];
    char uaddr[256+1];
    char uport[33];
    int slisten,to,try_next,nn;

#ifdef CONFIG_ANDROID
    const char* socket_fd = qemu_opt_get(opts, "socket");
    if (socket_fd) {
        return atoi(socket_fd);
    }
#endif

    if ((qemu_opt_get(opts, "host") == NULL) ||
        (qemu_opt_get(opts, "port") == NULL)) {
        fprintf(stderr, "%s: host and/or port not specified\n", __FUNCTION__);
        return -1;
    }
    pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port"));
    addr = qemu_opt_get(opts, "host");

    to = qemu_opt_get_number(opts, "to", 0);
    if (qemu_opt_get_bool(opts, "ipv4", 0))
        flags |= SOCKET_LIST_FORCE_INET;
    if (qemu_opt_get_bool(opts, "ipv6", 0))
        flags |= SOCKET_LIST_FORCE_IN6;

    /* lookup */
    if (port_offset)
        snprintf(port, sizeof(port), "%d", atoi(port) + port_offset);

    list = sock_address_list_create( strlen(addr) ? addr : NULL,
                                       port,
                                       flags );
    if (list == NULL) {
        fprintf(stderr,"%s: getaddrinfo(%s,%s): %s\n", __FUNCTION__,
                addr, port, errno_str);
        return -1;
    }

    /* create socket + bind */
    for (nn = 0; list[nn] != NULL; nn++) {
        SocketFamily  family;

        e      = list[nn];
        family = sock_address_get_family(e);

        sock_address_get_numeric_info(e, uaddr, sizeof uaddr, uport, sizeof uport);
        slisten = socket_create(family, SOCKET_STREAM);
        if (slisten < 0) {
            fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__,
                    sock_address_strfamily(e), errno_str);
            continue;
        }

        socket_set_xreuseaddr(slisten);
#ifdef IPV6_V6ONLY
        /* listen on both ipv4 and ipv6 */
        if (family == SOCKET_IN6) {
            socket_set_ipv6only(slisten);
        }
#endif

        for (;;) {
            if (socket_bind(slisten, e) == 0) {
                if (sockets_debug)
                    fprintf(stderr,"%s: bind(%s,%s,%d): OK\n", __FUNCTION__,
                        sock_address_strfamily(e), uaddr, sock_address_get_port(e));
                goto listen;
            }
            socket_close(slisten);
            try_next = to && (sock_address_get_port(e) <= to + port_offset);
            if (!try_next || sockets_debug)
                fprintf(stderr,"%s: bind(%s,%s,%d): %s\n", __FUNCTION__,
                        sock_address_strfamily(e), uaddr, sock_address_get_port(e),
                        strerror(errno));
            if (try_next) {
                sock_address_set_port(e, sock_address_get_port(e) + 1);
                continue;
            }
            break;
        }
    }
    sock_address_list_free(list);
    fprintf(stderr, "%s: FAILED\n", __FUNCTION__);
    return -1;

listen:
    if (socket_listen(slisten,1) != 0) {
        perror("listen");
        socket_close(slisten);
        return -1;
    }
    snprintf(uport, sizeof(uport), "%d", sock_address_get_port(e) - port_offset);
    qemu_opt_set(opts, "host", uaddr);
    qemu_opt_set(opts, "port", uport);
    qemu_opt_set(opts, "ipv6", (e->family == SOCKET_IN6) ? "on" : "off");
    qemu_opt_set(opts, "ipv4", (e->family != SOCKET_IN6) ? "on" : "off");
    sock_address_list_free(list);
    return slisten;
}