From 12c29b0f6eb55cfc096276f3ad808248cee6ff76 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 21 Mar 2014 17:32:09 +0400 Subject: [PATCH 1/4] Add evhttp_connection_set_family() to set addrinfo->family for DNS requests This is useful if you want to avoid extra dns requests. --- http-internal.h | 1 + http.c | 9 ++++++++- include/event2/http.h | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/http-internal.h b/http-internal.h index 82dd402a..6f2f5b85 100644 --- a/http-internal.h +++ b/http-internal.h @@ -99,6 +99,7 @@ struct evhttp_connection { struct event_base *base; struct evdns_base *dns_base; + int ai_family; /* Saved conn_addr, to extract IP address from it. * diff --git a/http.c b/http.c index e8672b77..2c153b71 100644 --- a/http.c +++ b/http.c @@ -2259,6 +2259,7 @@ evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_bas evhttp_deferred_read_cb, evcon); evcon->dns_base = dnsbase; + evcon->ai_family = AF_UNSPEC; return (evcon); @@ -2286,6 +2287,12 @@ evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase, return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port); } +void evhttp_connection_set_family(struct evhttp_connection *evcon, + int family) +{ + evcon->ai_family = family; +} + void evhttp_connection_set_base(struct evhttp_connection *evcon, struct event_base *base) @@ -2411,7 +2418,7 @@ evhttp_connection_connect_(struct evhttp_connection *evcon) evcon->state = EVCON_CONNECTING; if (bufferevent_socket_connect_hostname(evcon->bufev, evcon->dns_base, - AF_UNSPEC, evcon->address, evcon->port) < 0) { + evcon->ai_family, evcon->address, evcon->port) < 0) { evcon->state = old_state; event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed", __func__, evcon->address); diff --git a/include/event2/http.h b/include/event2/http.h index 956d9d6c..69aa8012 100644 --- a/include/event2/http.h +++ b/include/event2/http.h @@ -546,6 +546,12 @@ struct evhttp_connection *evhttp_connection_base_new( struct event_base *base, struct evdns_base *dnsbase, const char *address, unsigned short port); +/** + * Set family hint for DNS requests. + */ +void evhttp_connection_set_family(struct evhttp_connection *evcon, + int family); + /** Takes ownership of the request object * * Can be used in a request callback to keep onto the request until From 177b8a7ce8b99253f9bbe27bdda177462296ee6b Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 27 Mar 2014 00:44:51 +0400 Subject: [PATCH 2/4] test: add family argument for http_connection_test_() --- test/regress_http.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index faebabc4..aa384917 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -858,7 +858,8 @@ static void http_request_done(struct evhttp_request *, void *); static void http_request_empty_done(struct evhttp_request *, void *); static void -http_connection_test_(struct basic_test_data *data, int persistent, const char *address, struct evdns_base *dnsbase, int ipv6) +http_connection_test_(struct basic_test_data *data, int persistent, + const char *address, struct evdns_base *dnsbase, int ipv6, int family) { ev_uint16_t port = 0; struct evhttp_connection *evcon = NULL; @@ -870,6 +871,7 @@ http_connection_test_(struct basic_test_data *data, int persistent, const char * evcon = evhttp_connection_base_new(data->base, dnsbase, address, port); tt_assert(evcon); + evhttp_connection_set_family(evcon, family); tt_assert(evhttp_connection_get_base(evcon) == data->base); @@ -943,12 +945,12 @@ http_connection_test_(struct basic_test_data *data, int persistent, const char * static void http_connection_test(void *arg) { - http_connection_test_(arg, 0, "127.0.0.1", NULL, 0); + http_connection_test_(arg, 0, "127.0.0.1", NULL, 0, AF_UNSPEC); } static void http_persist_connection_test(void *arg) { - http_connection_test_(arg, 1, "127.0.0.1", NULL, 0); + http_connection_test_(arg, 1, "127.0.0.1", NULL, 0, AF_UNSPEC); } static struct regress_dns_server_table search_table[] = { @@ -3656,7 +3658,8 @@ http_ipv6_for_domain_test(void *arg) evutil_snprintf(address, sizeof(address), "127.0.0.1:%d", portnum); evdns_base_nameserver_ip_add(dns_base, address); - http_connection_test_(arg, 0 /* not persistent */, "localhost", dns_base, 1 /* ipv6 */); + http_connection_test_(arg, 0 /* not persistent */, "localhost", dns_base, + 1 /* ipv6 */, AF_UNSPEC); end: if (dns_base) From 42aefeb0afd91337e079b045c1e5a598f137c3c5 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 27 Mar 2014 00:40:14 +0400 Subject: [PATCH 3/4] test: add regress for evhttp_connection_set_family() with AF_INET and AF_UNSPEC --- test/regress_http.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/regress_http.c b/test/regress_http.c index aa384917..0a015a31 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -3730,6 +3730,17 @@ http_get_addr_test(void *arg) evhttp_free(http); } +static void +http_set_family_test(void *arg) +{ + http_connection_test_(arg, 0, "127.0.0.1", NULL, 0, AF_UNSPEC); +} +static void +http_set_family_ipv4_test(void *arg) +{ + http_connection_test_(arg, 0, "127.0.0.1", NULL, 0, AF_INET); +} + #define HTTP_LEGACY(name) \ { #name, run_legacy_test_fn, TT_ISOLATED|TT_LEGACY, &legacy_setup, \ http_##name##_test } @@ -3781,6 +3792,9 @@ struct testcase_t http_testcases[] = { HTTP(ipv6_for_domain), HTTP(get_addr), + HTTP(set_family), + HTTP(set_family_ipv4), + END_OF_TESTCASES }; From 3fbf3cc9088a0c7c9d36ef84b3b465f23f52a0e0 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 27 Mar 2014 00:49:00 +0400 Subject: [PATCH 4/4] test/http: add regress test for set family to AF_INET6 --- test/regress_http.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index 0a015a31..c5fc9dd8 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -3641,7 +3641,7 @@ static struct regress_dns_server_table ipv6_search_table[] = { }; static void -http_ipv6_for_domain_test(void *arg) +http_ipv6_for_domain_test_impl(void *arg, int family) { struct basic_test_data *data = arg; struct evdns_base *dns_base = NULL; @@ -3659,13 +3659,18 @@ http_ipv6_for_domain_test(void *arg) evdns_base_nameserver_ip_add(dns_base, address); http_connection_test_(arg, 0 /* not persistent */, "localhost", dns_base, - 1 /* ipv6 */, AF_UNSPEC); + 1 /* ipv6 */, family); end: if (dns_base) evdns_base_free(dns_base, 0); regress_clean_dnsserver(); } +static void +http_ipv6_for_domain_test(void *arg) +{ + http_ipv6_for_domain_test_impl(arg, AF_UNSPEC); +} static void http_request_get_addr_on_close(struct evhttp_connection *evcon, void *arg) @@ -3740,6 +3745,11 @@ http_set_family_ipv4_test(void *arg) { http_connection_test_(arg, 0, "127.0.0.1", NULL, 0, AF_INET); } +static void +http_set_family_ipv6_test(void *arg) +{ + http_ipv6_for_domain_test_impl(arg, AF_INET6); +} #define HTTP_LEGACY(name) \ { #name, run_legacy_test_fn, TT_ISOLATED|TT_LEGACY, &legacy_setup, \ @@ -3794,6 +3804,7 @@ struct testcase_t http_testcases[] = { HTTP(set_family), HTTP(set_family_ipv4), + HTTP(set_family_ipv6), END_OF_TESTCASES };