mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 13:04:23 -04:00
deal with connect() failing immediately
This commit is contained in:
parent
98edb891f8
commit
7bc48bfd3a
@ -137,6 +137,9 @@ struct bufferevent_private {
|
|||||||
unsigned writecb_pending : 1;
|
unsigned writecb_pending : 1;
|
||||||
/** Flag: set if we are currently busy connecting. */
|
/** Flag: set if we are currently busy connecting. */
|
||||||
unsigned connecting : 1;
|
unsigned connecting : 1;
|
||||||
|
/** Flag: set if a connect failed prematurely; this is a hack for
|
||||||
|
* getting around the bufferevent abstraction. */
|
||||||
|
unsigned connection_refused : 1;
|
||||||
/** Set to the events pending if we have deferred callbacks and
|
/** Set to the events pending if we have deferred callbacks and
|
||||||
* an events callback is pending. */
|
* an events callback is pending. */
|
||||||
short eventcb_pending;
|
short eventcb_pending;
|
||||||
|
@ -213,6 +213,12 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||||||
}
|
}
|
||||||
if (bufev_p->connecting) {
|
if (bufev_p->connecting) {
|
||||||
int c = evutil_socket_finished_connecting(fd);
|
int c = evutil_socket_finished_connecting(fd);
|
||||||
|
/* we need to fake the error if the connection was refused
|
||||||
|
* immediately - usually connection to localhost on BSD */
|
||||||
|
if (bufev_p->connection_refused) {
|
||||||
|
bufev_p->connection_refused = 0;
|
||||||
|
c = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
goto done;
|
goto done;
|
||||||
@ -395,11 +401,19 @@ bufferevent_socket_connect(struct bufferevent *bev,
|
|||||||
result = 0;
|
result = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
} else {
|
} if (r == 1) {
|
||||||
/* The connect succeeded already. How very BSD of it. */
|
/* The connect succeeded already. How very BSD of it. */
|
||||||
result = 0;
|
result = 0;
|
||||||
bufev_p->connecting = 1;
|
bufev_p->connecting = 1;
|
||||||
event_active(&bev->ev_write, EV_WRITE, 1);
|
event_active(&bev->ev_write, EV_WRITE, 1);
|
||||||
|
} else {
|
||||||
|
/* The connect failed already. How very BSD of it. */
|
||||||
|
if (! be_socket_enable(bev, EV_WRITE)) {
|
||||||
|
bufev_p->connection_refused = 1;
|
||||||
|
bufev_p->connecting = 1;
|
||||||
|
result = 0;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
|
4
evutil.c
4
evutil.c
@ -355,7 +355,7 @@ evutil_socket_geterror(evutil_socket_t sock)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 1 for connected, 0 for not yet, -1 for error. */
|
/* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
|
||||||
int
|
int
|
||||||
evutil_socket_connect(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen)
|
evutil_socket_connect(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen)
|
||||||
{
|
{
|
||||||
@ -374,6 +374,8 @@ evutil_socket_connect(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen)
|
|||||||
int e = evutil_socket_geterror(*fd_ptr);
|
int e = evutil_socket_geterror(*fd_ptr);
|
||||||
if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
|
if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (EVUTIL_ERR_CONNECT_REFUSED(e))
|
||||||
|
return 2;
|
||||||
goto err;
|
goto err;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -66,13 +66,17 @@ extern "C" {
|
|||||||
/* True iff e is an error that means a read/write operation can be retried. */
|
/* True iff e is an error that means a read/write operation can be retried. */
|
||||||
#define EVUTIL_ERR_RW_RETRIABLE(e) \
|
#define EVUTIL_ERR_RW_RETRIABLE(e) \
|
||||||
((e) == EINTR || (e) == EAGAIN)
|
((e) == EINTR || (e) == EAGAIN)
|
||||||
/* True iff e is an error that means an accept can be retried. */
|
/* True iff e is an error that means an connect can be retried. */
|
||||||
#define EVUTIL_ERR_CONNECT_RETRIABLE(e) \
|
#define EVUTIL_ERR_CONNECT_RETRIABLE(e) \
|
||||||
((e) == EINTR || (e) == EINPROGRESS)
|
((e) == EINTR || (e) == EINPROGRESS)
|
||||||
/* True iff e is an error that means a connect can be retried. */
|
/* True iff e is an error that means a accept can be retried. */
|
||||||
#define EVUTIL_ERR_ACCEPT_RETRIABLE(e) \
|
#define EVUTIL_ERR_ACCEPT_RETRIABLE(e) \
|
||||||
((e) == EINTR || (e) == EAGAIN || (e) == ECONNABORTED)
|
((e) == EINTR || (e) == EAGAIN || (e) == ECONNABORTED)
|
||||||
|
|
||||||
|
/* True iff e is an error that means the connection was refused */
|
||||||
|
#define EVUTIL_ERR_CONNECT_REFUSED(e) \
|
||||||
|
((e) == ECONNREFUSED)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define EVUTIL_ERR_RW_RETRIABLE(e) \
|
#define EVUTIL_ERR_RW_RETRIABLE(e) \
|
||||||
@ -88,6 +92,9 @@ extern "C" {
|
|||||||
#define EVUTIL_ERR_ACCEPT_RETRIABLE(e) \
|
#define EVUTIL_ERR_ACCEPT_RETRIABLE(e) \
|
||||||
EVUTIL_ERR_RW_RETRIABLE(e)
|
EVUTIL_ERR_RW_RETRIABLE(e)
|
||||||
|
|
||||||
|
#define EVUTIL_ERR_CONNECT_REFUSED(e) \
|
||||||
|
((e) == WSAECONNREFUSED)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _EVENT_socklen_t
|
#ifdef _EVENT_socklen_t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user