]> granicus.if.org Git - libevent/commitdiff
Fix ipv6 support for http. When URL contain domain, not IP address.
authorAzat Khuzhin <a3at.mail@gmail.com>
Tue, 22 Jan 2013 22:45:32 +0000 (02:45 +0400)
committerAzat Khuzhin <a3at.mail@gmail.com>
Tue, 22 Jan 2013 22:45:32 +0000 (02:45 +0400)
Before this patch socket created before domain was resolved, and it
always create with AF_INET (ipv4), but we must create socket only after
domain was resolved to understad which protocol family have domain
address.

Thank to Patrick Pelletier, who found this bug.

http.c

diff --git a/http.c b/http.c
index 0976e045f8106033be3e0f16f2e349becb9bff88..eb4a0786f66edacd2d6e265a55b852ec0384bbc6 100644 (file)
--- a/http.c
+++ b/http.c
@@ -1327,6 +1327,9 @@ evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
        struct evhttp_connection *evcon = arg;
        struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
 
+       if (evcon->fd == -1)
+               evcon->fd = bufferevent_getfd(bufev);
+
        switch (evcon->state) {
        case EVCON_CONNECTING:
                if (what & BEV_EVENT_TIMEOUT) {
@@ -1393,6 +1396,9 @@ evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
        int error;
        ev_socklen_t errsz = sizeof(error);
 
+       if (evcon->fd == -1)
+               evcon->fd = bufferevent_getfd(bufev);
+
        if (!(what & BEV_EVENT_CONNECTED)) {
                /* some operating systems return ECONNREFUSED immediately
                 * when connecting to a local address.  the cleanup is going
@@ -2332,16 +2338,21 @@ evhttp_connection_connect_(struct evhttp_connection *evcon)
        EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
        evcon->flags |= EVHTTP_CON_OUTGOING;
 
-       evcon->fd = bind_socket(
-               evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
-       if (evcon->fd == -1) {
-               event_debug(("%s: failed to bind to \"%s\"",
-                       __func__, evcon->bind_address));
-               return (-1);
+       if (evcon->bind_address || evcon->bind_port) {
+               evcon->fd = bind_socket(
+                       evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
+               if (evcon->fd == -1) {
+                       event_debug(("%s: failed to bind to \"%s\"",
+                               __func__, evcon->bind_address));
+                       return (-1);
+               }
+
+               bufferevent_setfd(evcon->bufev, evcon->fd);
+       } else {
+               bufferevent_setfd(evcon->bufev, -1);
        }
 
        /* Set up a callback for successful connection setup */
-       bufferevent_setfd(evcon->bufev, evcon->fd);
        bufferevent_setcb(evcon->bufev,
            NULL /* evhttp_read_cb */,
            NULL /* evhttp_write_cb */,