/* * Parse an ascii host/IP and port tuple into a sockaddr_storage. * On success, returns address family and fills in addr, addrlen. * Returns -1 on error. */ int sys_sockaddr_parse(struct sockaddr_storage *addr, socklen_t *addrlen, char *naddr, char *nport, int af, int flags) { struct evutil_addrinfo hints; struct evutil_addrinfo *ai; int rv; memset(&hints, 0, sizeof(hints)); hints.ai_family = af; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = EVUTIL_AI_ADDRCONFIG | flags; rv = evutil_getaddrinfo(naddr, nport, &hints, &ai); if (rv != 0) { log_err_printf("Cannot resolve address '%s' port '%s': %s\n", naddr, nport, gai_strerror(rv)); return -1; } memcpy(addr, ai->ai_addr, ai->ai_addrlen); *addrlen = ai->ai_addrlen; af = ai->ai_family; freeaddrinfo(ai); return af; }
static void start_listening(struct event_base *base, struct evdns_base *dns, const char *laddr, const char *lport) { struct evutil_addrinfo hints; struct evutil_addrinfo *ai = NULL; int ret; if (!evutil_ascii_strcasecmp(laddr, "any")) laddr = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* turn NULL hostname into INADDR_ANY, and skip looking up any address * types we don't have an interface to connect to. */ hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG; ret = evutil_getaddrinfo(laddr, lport, &hints, &ai); if (ret < 0) { log_error("shim: bad listen address: %s", evutil_gai_strerror(ret)); exit(1); } if (proxy_init(base, dns, ai->ai_addr, ai->ai_addrlen) < 0) exit(1); }
evutil_addrinfo* make_addrinfo_(const char* address, ev_uint16_t port) { struct evutil_addrinfo *ai = NULL; struct evutil_addrinfo hints; char strport[NI_MAXSERV]; int ai_result; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* turn NULL hostname into INADDR_ANY, and skip looking up any address * types we don't have an interface to connect to. */ hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG; evutil_snprintf(strport, sizeof(strport), "%d", port); if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai)) != 0) { /* if (ai_result == EVUTIL_EAI_SYSTEM) { event_warn("getaddrinfo"); } else { event_warnx("getaddrinfo: %s", evutil_gai_strerror(ai_result)); } */ return (NULL); } return (ai); }
static int dns_lookup (const char *addr_str, struct sockaddr_in *sa, ev_socklen_t *sa_len) { struct evutil_addrinfo hints; struct evutil_addrinfo *answer = NULL; int err; /* Build the hints to tell getaddrinfo how to act. */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; /* only use IPv4 now. */ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; /* We want a TCP socket */ /* Only return addresses we can use. */ hints.ai_flags = EVUTIL_AI_ADDRCONFIG; /* Look up the hostname. */ err = evutil_getaddrinfo(addr_str, NULL, &hints, &answer); if (err != 0) { seaf_warning("Error while resolving '%s': %s\n", addr_str, evutil_gai_strerror(err)); return -1; } *sa = *((struct sockaddr_in *)answer->ai_addr); *sa_len = (ev_socklen_t)answer->ai_addrlen; evutil_freeaddrinfo (answer); return 0; }
static void * dns_lookup (void *vdata) { DNSLookupData *data = vdata; struct evutil_addrinfo hints; struct evutil_addrinfo *answer = NULL; int err; void *addr; char *addr_str; socklen_t size; /* Build the hints to tell getaddrinfo how to act. */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; /* only use IPv4 now. */ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; /* We want a TCP socket */ /* Only return addresses we can use. */ hints.ai_flags = EVUTIL_AI_ADDRCONFIG; /* Look up the hostname. */ err = evutil_getaddrinfo(data->peer->public_addr, NULL, &hints, &answer); if (err != 0) { ccnet_warning("Error while resolving '%s': %s\n", data->peer->public_addr, evutil_gai_strerror(err)); return vdata; } /* just use the first answer */ if (answer->ai_family == AF_INET) { size = INET_ADDRSTRLEN; addr = &((struct sockaddr_in *)(answer->ai_addr))->sin_addr; } else if (answer->ai_family == AF_INET6) { size = INET6_ADDRSTRLEN; addr = &((struct sockaddr_in6 *)(answer->ai_addr))->sin6_addr; } else goto out; addr_str = (char *)calloc(size, sizeof(char)); if (addr_str == NULL) { ccnet_error("Out of memory\n"); goto out; } if (!inet_ntop(answer->ai_family, addr, addr_str, size)) { ccnet_warning("Peer %s domain name %s lookup fail\n", data->peer->name, data->peer->public_addr); free(addr_str); goto out; } data->addr_str = addr_str; out: evutil_freeaddrinfo (answer); return vdata; }
void hub_add_peer(struct hub *hub, char const *address) { int e; char *hostname, *ptr, port[6]; struct evutil_addrinfo hints, *answer = NULL; struct peer *peer; if ((ptr = strchr(address, ':'))) { hostname = calloc(ptr - address + 1, sizeof(*hostname)); if (!hostname) err(1, NULL); strncpy(hostname, address, ptr - address); strncpy(port, ptr + 1, sizeof(port)); } else { hostname = (char *) address; evutil_snprintf(port, sizeof(port), "%hi", hub->port); } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = EVUTIL_AI_ADDRCONFIG; if ((e = evutil_getaddrinfo(hostname, port, &hints, &answer)) < 0) { fprintf(stderr, "Error while resolving '%s': %s", hostname, evutil_gai_strerror(e)); return; } if (!answer) return; peer = calloc(1, sizeof(*peer)); if (!peer) err(1, NULL); peer->name = address; peer->addrlen = answer->ai_addrlen; peer->addr = malloc(peer->addrlen); if (!peer->addr) err(1, NULL); memcpy(peer->addr, answer->ai_addr, peer->addrlen); peer->next = hub->peers; hub->peers = peer; evutil_freeaddrinfo(answer); }
static int tcpip_open(const gchar *h, const gchar *p) { GRID_DEBUG("opening tcp ip connection"); struct evutil_addrinfo ai_hint, *ai_res = NULL; int rc; socklen_t ss_len; struct sockaddr_storage ss; int fd; fd = socket(PF_INET, SOCK_STREAM, 0); if (fd < 0) { GRID_ERROR("accept error on fd=%d : %s", fd, strerror(errno)); return -1; } sock_set_linger_default(fd); sock_set_reuseaddr(fd, TRUE); bzero(&ai_hint, sizeof(ai_hint)); ai_hint.ai_flags = AI_NUMERICHOST; ai_hint.ai_family = PF_INET; ai_hint.ai_socktype = SOCK_STREAM; rc = evutil_getaddrinfo(h, p, &ai_hint, &ai_res); if (rc != 0) { errno = rc; return -1; } bzero(&ss, sizeof(ss)); ss_len = ai_res->ai_addrlen; g_memmove(&ss, (ai_res->ai_addr), ss_len); evutil_freeaddrinfo(ai_res); switch (connect(fd, (struct sockaddr *) &ss, ss_len)) { case 0: return fd; case -1: if (errno==EALREADY || errno==EAGAIN || errno==EINPROGRESS || errno==EWOULDBLOCK) { errno = 0; return fd; } return -1; default:/* unexpected */ return -1; } }
int conn_set_socks_server(const char *name, int port, enum socks_ver ver) { int ret; int rv = -1; struct evutil_addrinfo *ai = NULL; struct evutil_addrinfo hint; char portstr[NI_MAXSERV]; assert(ver != SOCKS_NONE); evutil_snprintf(portstr, sizeof(portstr), "%d", port); memset(&hint, 0, sizeof(hint)); hint.ai_family = AF_UNSPEC; hint.ai_protocol = IPPROTO_TCP; hint.ai_socktype = SOCK_STREAM; hint.ai_flags = EVUTIL_AI_ADDRCONFIG; ret = evutil_getaddrinfo(name, portstr, &hint, &ai); if (!ret) { rv = 0; memset(&socks_addr, 0, sizeof(socks_addr)); memcpy(&socks_addr, ai->ai_addr, ai->ai_addrlen); socks_addr_len = ai->ai_addrlen; use_socks = ver; log_notice("conn: socks server set to %s", format_addr((struct sockaddr*)&socks_addr)); } else { log_error("conn: can't resolve socks server %s: %s", name, evutil_gai_strerror(ret)); } if (ai) evutil_freeaddrinfo(ai); return rv; }
static void test_bufferevent_connect_hostname(void *arg) { struct basic_test_data *data = arg; struct evconnlistener *listener = NULL; struct bufferevent *be1=NULL, *be2=NULL, *be3=NULL, *be4=NULL, *be5=NULL; struct be_conn_hostname_result be1_outcome={0,0}, be2_outcome={0,0}, be3_outcome={0,0}, be4_outcome={0,0}, be5_outcome={0,0}; int expect_err5; struct evdns_base *dns=NULL; struct evdns_server_port *port=NULL; evutil_socket_t server_fd=-1; struct sockaddr_in sin; int listener_port=-1; ev_uint16_t dns_port=0; int n_accept=0, n_dns=0; char buf[128]; be_connect_hostname_base = data->base; /* Bind an address and figure out what port it's on. */ memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ sin.sin_port = 0; listener = evconnlistener_new_bind(data->base, nil_accept_cb, &n_accept, LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC, -1, (struct sockaddr *)&sin, sizeof(sin)); listener_port = regress_get_socket_port( evconnlistener_get_fd(listener)); port = regress_get_dnsserver(data->base, &dns_port, NULL, be_getaddrinfo_server_cb, &n_dns); tt_assert(port); tt_int_op(dns_port, >=, 0); /* Start an evdns_base that uses the server as its resolver. */ dns = evdns_base_new(data->base, 0); evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)dns_port); evdns_base_nameserver_ip_add(dns, buf); /* Now, finally, at long last, launch the bufferevents. One should do * a failing lookup IP, one should do a successful lookup by IP, * and one should do a successful lookup by hostname. */ be1 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); be2 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); be3 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); be4 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); be5 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(be1, NULL, NULL, be_connect_hostname_event_cb, &be1_outcome); bufferevent_setcb(be2, NULL, NULL, be_connect_hostname_event_cb, &be2_outcome); bufferevent_setcb(be3, NULL, NULL, be_connect_hostname_event_cb, &be3_outcome); bufferevent_setcb(be4, NULL, NULL, be_connect_hostname_event_cb, &be4_outcome); bufferevent_setcb(be5, NULL, NULL, be_connect_hostname_event_cb, &be5_outcome); /* Launch an async resolve that will fail. */ tt_assert(!bufferevent_socket_connect_hostname(be1, dns, AF_INET, "nosuchplace.example.com", listener_port)); /* Connect to the IP without resolving. */ tt_assert(!bufferevent_socket_connect_hostname(be2, dns, AF_INET, "127.0.0.1", listener_port)); /* Launch an async resolve that will succeed. */ tt_assert(!bufferevent_socket_connect_hostname(be3, dns, AF_INET, "nobodaddy.example.com", listener_port)); /* Use the blocking resolver. This one will fail if your resolver * can't resolve localhost to 127.0.0.1 */ tt_assert(!bufferevent_socket_connect_hostname(be4, NULL, AF_INET, "localhost", listener_port)); /* Use the blocking resolver with a nonexistent hostname. */ tt_assert(!bufferevent_socket_connect_hostname(be5, NULL, AF_INET, "nonesuch.nowhere.example.com", 80)); { /* The blocking resolver will use the system nameserver, which * might tell us anything. (Yes, some twits even pretend that * example.com is real.) Let's see what answer to expect. */ struct evutil_addrinfo hints, *ai = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; expect_err5 = evutil_getaddrinfo( "nonesuch.nowhere.example.com", "80", &hints, &ai); } event_base_dispatch(data->base); tt_int_op(be1_outcome.what, ==, BEV_EVENT_ERROR); tt_int_op(be1_outcome.dnserr, ==, EVUTIL_EAI_NONAME); tt_int_op(be2_outcome.what, ==, BEV_EVENT_CONNECTED); tt_int_op(be2_outcome.dnserr, ==, 0); tt_int_op(be3_outcome.what, ==, BEV_EVENT_CONNECTED); tt_int_op(be3_outcome.dnserr, ==, 0); tt_int_op(be4_outcome.what, ==, BEV_EVENT_CONNECTED); tt_int_op(be4_outcome.dnserr, ==, 0); if (expect_err5) { tt_int_op(be5_outcome.what, ==, BEV_EVENT_ERROR); tt_int_op(be5_outcome.dnserr, ==, expect_err5); } tt_int_op(n_accept, ==, 3); tt_int_op(n_dns, ==, 2); end: if (listener) evconnlistener_free(listener); if (server_fd>=0) evutil_closesocket(server_fd); if (port) evdns_close_server_port(port); if (dns) evdns_base_free(dns, 0); if (be1) bufferevent_free(be1); if (be2) bufferevent_free(be2); if (be3) bufferevent_free(be3); if (be4) bufferevent_free(be4); if (be5) bufferevent_free(be5); }