Fix evhttp_connection_get_addr() fox incomming http connections

Install conn_address of the bufferevent on incomping http connections
(even though this is kind of subsytem violation, so let's fix it in a
simplest way and thinkg about long-term solution).

Fixes: #510
Closes: #595 (pick)
(cherry picked from commit 367cd9e5c2b8e3f9b8dbed40bfe8a0ed79285c36)
This commit is contained in:
Greg Hazel 2018-02-11 16:28:58 -08:00 committed by Azat Khuzhin
parent f3eb294f79
commit 4215c003f1
No known key found for this signature in database
GPG Key ID: B86086848EF8686D
3 changed files with 23 additions and 6 deletions

View File

@ -444,6 +444,15 @@ EVENT2_EXPORT_SYMBOL
const struct sockaddr* const struct sockaddr*
bufferevent_socket_get_conn_address_(struct bufferevent *bev); bufferevent_socket_get_conn_address_(struct bufferevent *bev);
EVENT2_EXPORT_SYMBOL
void
bufferevent_socket_set_conn_address_fd_(struct bufferevent *bev, int fd);
EVENT2_EXPORT_SYMBOL
void
bufferevent_socket_set_conn_address_(struct bufferevent *bev, struct sockaddr *addr, size_t addrlen);
/** Internal use: We have just successfully read data into an inbuf, so /** Internal use: We have just successfully read data into an inbuf, so
* reset the read timeout (if any). */ * reset the read timeout (if any). */
#define BEV_RESET_GENERIC_READ_TIMEOUT(bev) \ #define BEV_RESET_GENERIC_READ_TIMEOUT(bev) \

View File

@ -104,19 +104,26 @@ bufferevent_socket_get_conn_address_(struct bufferevent *bev)
return (struct sockaddr *)&bev_p->conn_address; return (struct sockaddr *)&bev_p->conn_address;
} }
static void
bufferevent_socket_set_conn_address_fd(struct bufferevent_private *bev_p, int fd) void
bufferevent_socket_set_conn_address_fd_(struct bufferevent *bev, int fd)
{ {
struct bufferevent_private *bev_p =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
socklen_t len = sizeof(bev_p->conn_address); socklen_t len = sizeof(bev_p->conn_address);
struct sockaddr *addr = (struct sockaddr *)&bev_p->conn_address; struct sockaddr *addr = (struct sockaddr *)&bev_p->conn_address;
if (addr->sa_family != AF_UNSPEC) if (addr->sa_family != AF_UNSPEC)
getpeername(fd, addr, &len); getpeername(fd, addr, &len);
} }
static void
bufferevent_socket_set_conn_address(struct bufferevent_private *bev_p, void
bufferevent_socket_set_conn_address_(struct bufferevent *bev,
struct sockaddr *addr, size_t addrlen) struct sockaddr *addr, size_t addrlen)
{ {
struct bufferevent_private *bev_p =
EVUTIL_UPCAST(bev, struct bufferevent_private, bev);
EVUTIL_ASSERT(addrlen <= sizeof(bev_p->conn_address)); EVUTIL_ASSERT(addrlen <= sizeof(bev_p->conn_address));
memcpy(&bev_p->conn_address, addr, addrlen); memcpy(&bev_p->conn_address, addr, addrlen);
} }
@ -264,7 +271,7 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
goto done; goto done;
} else { } else {
connected = 1; connected = 1;
bufferevent_socket_set_conn_address_fd(bufev_p, fd); bufferevent_socket_set_conn_address_fd_(bufev, fd);
#ifdef _WIN32 #ifdef _WIN32
if (BEV_IS_ASYNC(bufev)) { if (BEV_IS_ASYNC(bufev)) {
event_del(&bufev->ev_write); event_del(&bufev->ev_write);
@ -483,7 +490,7 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai,
} }
/* XXX use the other addrinfos? */ /* XXX use the other addrinfos? */
bufferevent_socket_set_conn_address(bev_p, ai->ai_addr, (int)ai->ai_addrlen); bufferevent_socket_set_conn_address_(bev, ai->ai_addr, (int)ai->ai_addrlen);
r = bufferevent_socket_connect(bev, ai->ai_addr, (int)ai->ai_addrlen); r = bufferevent_socket_connect(bev, ai->ai_addr, (int)ai->ai_addrlen);
if (r < 0) if (r < 0)
bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0); bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0);

1
http.c
View File

@ -4213,6 +4213,7 @@ evhttp_get_request_connection(
bufferevent_enable(evcon->bufev, EV_READ); bufferevent_enable(evcon->bufev, EV_READ);
bufferevent_disable(evcon->bufev, EV_WRITE); bufferevent_disable(evcon->bufev, EV_WRITE);
bufferevent_setfd(evcon->bufev, fd); bufferevent_setfd(evcon->bufev, fd);
bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
return (evcon); return (evcon);
} }