]> granicus.if.org Git - libevent/commitdiff
http: install timeout for read too during connect for ssl
authorAzat Khuzhin <a3at.mail@gmail.com>
Sun, 15 Nov 2015 21:55:30 +0000 (00:55 +0300)
committerAzat Khuzhin <a3at.mail@gmail.com>
Wed, 18 Nov 2015 12:42:22 +0000 (15:42 +0300)
Since during ssl handshake we can read too, and if something nasty will happens
during this handshake (because of too many events in the loop of something like
this) we can wait forever since there is no read timeout:
  (gdb) p *$2.task.connection.bufev
  $11 = {
    ...
    be_ops = 0x7f78c2864b00 <bufferevent_ops_openssl>,
    ev_read = {
      ...
      ev_ = {
        ev_io = {
          ...
          ev_timeout = { tv_sec = 0, tv_usec = 0 }
        },
        ev_signal = { ... }
      },
      ev_events = 82, ev_res = 2,
      ev_timeout = { tv_sec = 10889976, tv_usec = 418753 }
    },
    ev_write = {
      ...
      ev_ = {
        ev_io = {
          ...
          ev_timeout = { tv_sec = 20, tv_usec = 0 }
        },
        ev_signal = { ... }
      },
      ev_events = 84, ev_res = 4,
      ev_timeout = { tv_sec = 10889977, tv_usec = 598753 }
    },
    ...
    errorcb = 0x7f78c287de70 <evhttp_connection_cb>,
    ...
    timeout_read = { tv_sec = 0, tv_usec = 0 },
    timeout_write = { tv_sec = 20, tv_usec = 0 },
    enabled = 4
  }
  (gdb) bt
  #0  0x00007f78c17c3633 in __epoll_wait_nocancel () at syscall-template.S:81
  #1  0x00007f78c2aaf508 in epoll_dispatch (base=0x18f76d0, tv=<optimized out>) at epoll.c:463
  ...

Found-with: massive crawling
Tested-with: massive crawling

http.c

diff --git a/http.c b/http.c
index 75b902dc5d6e0660bcfea64951b6949a8b11d2b3..b879132a96f081de722466a48c3092d1a10d6d13 100644 (file)
--- a/http.c
+++ b/http.c
@@ -2471,9 +2471,9 @@ evhttp_connection_connect_(struct evhttp_connection *evcon)
            evcon);
        if (!evutil_timerisset(&evcon->timeout)) {
                const struct timeval conn_tv = { HTTP_CONNECT_TIMEOUT, 0 };
-               bufferevent_set_timeouts(evcon->bufev, NULL, &conn_tv);
+               bufferevent_set_timeouts(evcon->bufev, &conn_tv, &conn_tv);
        } else {
-               bufferevent_set_timeouts(evcon->bufev, NULL, &evcon->timeout);
+               bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
        }
        /* make sure that we get a write callback */
        bufferevent_enable(evcon->bufev, EV_WRITE);