mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-13 06:16:10 -04:00
Report DNS error when lookup fails during bufferevent_socket_connect_hostname.
This commit is contained in:
parent
25c442e582
commit
0ef407065e
@ -165,6 +165,9 @@ struct bufferevent_private {
|
|||||||
* an events callback is pending. */
|
* an events callback is pending. */
|
||||||
int errno_pending;
|
int errno_pending;
|
||||||
|
|
||||||
|
/** The DNS error code for bufferevent_socket_connect_hostname */
|
||||||
|
int dns_error;
|
||||||
|
|
||||||
/** Used to implement deferred callbacks */
|
/** Used to implement deferred callbacks */
|
||||||
struct deferred_cb deferred;
|
struct deferred_cb deferred;
|
||||||
|
|
||||||
|
@ -431,6 +431,8 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai,
|
|||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
struct bufferevent *bev = arg;
|
struct bufferevent *bev = arg;
|
||||||
|
struct bufferevent_private *bev_p =
|
||||||
|
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
|
||||||
int r;
|
int r;
|
||||||
BEV_LOCK(bev);
|
BEV_LOCK(bev);
|
||||||
|
|
||||||
@ -438,7 +440,7 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai,
|
|||||||
bufferevent_unsuspend_read(bev, BEV_SUSPEND_LOOKUP);
|
bufferevent_unsuspend_read(bev, BEV_SUSPEND_LOOKUP);
|
||||||
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
/* XXX Communicate the error somehow. */
|
bev_p->dns_error = result;
|
||||||
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
|
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
|
||||||
_bufferevent_decref_and_unlock(bev);
|
_bufferevent_decref_and_unlock(bev);
|
||||||
if (ai)
|
if (ai)
|
||||||
@ -459,12 +461,18 @@ bufferevent_socket_connect_hostname(struct bufferevent *bev,
|
|||||||
char portbuf[10];
|
char portbuf[10];
|
||||||
struct evutil_addrinfo hint;
|
struct evutil_addrinfo hint;
|
||||||
int err;
|
int err;
|
||||||
|
struct bufferevent_private *bev_p =
|
||||||
|
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
|
||||||
|
|
||||||
if (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC)
|
if (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC)
|
||||||
return -1;
|
return -1;
|
||||||
if (port < 1 || port > 65535)
|
if (port < 1 || port > 65535)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
BEV_LOCK(bev);
|
||||||
|
bev_p->dns_error = 0;
|
||||||
|
BEV_UNLOCK(bev);
|
||||||
|
|
||||||
evutil_snprintf(portbuf, sizeof(portbuf), "%d", port);
|
evutil_snprintf(portbuf, sizeof(portbuf), "%d", port);
|
||||||
|
|
||||||
memset(&hint, 0, sizeof(hint));
|
memset(&hint, 0, sizeof(hint));
|
||||||
@ -488,6 +496,20 @@ bufferevent_socket_connect_hostname(struct bufferevent *bev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bufferevent_socket_get_dns_error(struct bufferevent *bev)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
struct bufferevent_private *bev_p =
|
||||||
|
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
|
||||||
|
|
||||||
|
BEV_LOCK(bev);
|
||||||
|
rv = bev_p->dns_error;
|
||||||
|
BEV_LOCK(bev);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new buffered event object.
|
* Create a new buffered event object.
|
||||||
*
|
*
|
||||||
|
@ -185,6 +185,16 @@ struct evdns_base;
|
|||||||
int bufferevent_socket_connect_hostname(struct bufferevent *b,
|
int bufferevent_socket_connect_hostname(struct bufferevent *b,
|
||||||
struct evdns_base *, int, const char *, int);
|
struct evdns_base *, int, const char *, int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the error code for the last failed DNS lookup attempt made by
|
||||||
|
bufferevent_socket_connect_hostname().
|
||||||
|
|
||||||
|
@param bev The bufferevent object.
|
||||||
|
@return DNS error code.
|
||||||
|
@see evutil_gai_strerror()
|
||||||
|
*/
|
||||||
|
int bufferevent_socket_get_dns_error(struct bufferevent *bev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Assign a bufferevent to a specific event_base.
|
Assign a bufferevent to a specific event_base.
|
||||||
|
|
||||||
|
@ -969,26 +969,37 @@ nil_accept_cb(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *s,
|
|||||||
/* don't do anything with the socket; let it close when we exit() */
|
/* don't do anything with the socket; let it close when we exit() */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct be_conn_hostname_result {
|
||||||
|
int dnserr;
|
||||||
|
int what;
|
||||||
|
};
|
||||||
|
|
||||||
/* Bufferevent event callback for the connect_hostname test: remembers what
|
/* Bufferevent event callback for the connect_hostname test: remembers what
|
||||||
* event we got. */
|
* event we got. */
|
||||||
static void
|
static void
|
||||||
be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx)
|
be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx)
|
||||||
{
|
{
|
||||||
int *got = ctx;
|
struct be_conn_hostname_result *got = ctx;
|
||||||
if (!*got) {
|
if (!got->what) {
|
||||||
TT_BLATHER(("Got a bufferevent event %d", what));
|
TT_BLATHER(("Got a bufferevent event %d", what));
|
||||||
*got = what;
|
got->what = what;
|
||||||
|
|
||||||
if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) {
|
if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) {
|
||||||
|
int r;
|
||||||
++total_connected_or_failed;
|
++total_connected_or_failed;
|
||||||
TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed));
|
TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed));
|
||||||
|
if ((r = bufferevent_socket_get_dns_error(bev))) {
|
||||||
|
got->dnserr = r;
|
||||||
|
TT_BLATHER(("DNS error %d: %s", r,
|
||||||
|
evutil_gai_strerror(r)));
|
||||||
|
}
|
||||||
if (total_connected_or_failed >= 5)
|
if (total_connected_or_failed >= 5)
|
||||||
event_base_loopexit(be_connect_hostname_base,
|
event_base_loopexit(be_connect_hostname_base,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TT_FAIL(("Two events on one bufferevent. %d,%d",
|
TT_FAIL(("Two events on one bufferevent. %d,%d",
|
||||||
(int)*got, (int)what));
|
got->what, (int)what));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -998,8 +1009,8 @@ test_bufferevent_connect_hostname(void *arg)
|
|||||||
struct basic_test_data *data = arg;
|
struct basic_test_data *data = arg;
|
||||||
struct evconnlistener *listener = NULL;
|
struct evconnlistener *listener = NULL;
|
||||||
struct bufferevent *be1=NULL, *be2=NULL, *be3=NULL, *be4=NULL, *be5=NULL;
|
struct bufferevent *be1=NULL, *be2=NULL, *be3=NULL, *be4=NULL, *be5=NULL;
|
||||||
int be1_outcome=0, be2_outcome=0, be3_outcome=0, be4_outcome=0,
|
struct be_conn_hostname_result be1_outcome={0,0}, be2_outcome={0,0},
|
||||||
be5_outcome=0;
|
be3_outcome={0,0}, be4_outcome={0,0}, be5_outcome={0,0};
|
||||||
struct evdns_base *dns=NULL;
|
struct evdns_base *dns=NULL;
|
||||||
struct evdns_server_port *port=NULL;
|
struct evdns_server_port *port=NULL;
|
||||||
evutil_socket_t server_fd=-1;
|
evutil_socket_t server_fd=-1;
|
||||||
@ -1072,11 +1083,16 @@ test_bufferevent_connect_hostname(void *arg)
|
|||||||
|
|
||||||
event_base_dispatch(data->base);
|
event_base_dispatch(data->base);
|
||||||
|
|
||||||
tt_int_op(be1_outcome, ==, BEV_EVENT_ERROR);
|
tt_int_op(be1_outcome.what, ==, BEV_EVENT_ERROR);
|
||||||
tt_int_op(be2_outcome, ==, BEV_EVENT_CONNECTED);
|
tt_int_op(be1_outcome.dnserr, ==, EVUTIL_EAI_NONAME);
|
||||||
tt_int_op(be3_outcome, ==, BEV_EVENT_CONNECTED);
|
tt_int_op(be2_outcome.what, ==, BEV_EVENT_CONNECTED);
|
||||||
tt_int_op(be4_outcome, ==, BEV_EVENT_CONNECTED);
|
tt_int_op(be2_outcome.dnserr, ==, 0);
|
||||||
tt_int_op(be5_outcome, ==, BEV_EVENT_ERROR);
|
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);
|
||||||
|
tt_int_op(be5_outcome.what, ==, BEV_EVENT_ERROR);
|
||||||
|
tt_int_op(be5_outcome.dnserr, ==, EVUTIL_EAI_NONAME);
|
||||||
|
|
||||||
tt_int_op(n_accept, ==, 3);
|
tt_int_op(n_accept, ==, 3);
|
||||||
tt_int_op(n_dns, ==, 2);
|
tt_int_op(n_dns, ==, 2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user