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; }
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); }
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; }