]> granicus.if.org Git - libevent/commitdiff
Introduce new BUFFEREVENT_SSL_BATCH_WRITE flag to avoid Nagle effect in SSL
authorAzat Khuzhin <azat@libevent.org>
Sat, 31 Oct 2020 19:53:31 +0000 (22:53 +0300)
committerAzat Khuzhin <azat@libevent.org>
Sat, 31 Oct 2020 20:04:46 +0000 (23:04 +0300)
bufferevent_ssl.c
include/event2/bufferevent_ssl.h
test/regress_ssl.c

index dd013c98809dcbea77e806fa6210a8dbc6f8027f..b34af9af42e75bf8b91139963dae3327b15aa336 100644 (file)
@@ -328,6 +328,11 @@ do_write(struct bufferevent_ssl *bev_ssl, int atmost)
        else
                atmost = bufferevent_get_write_max_(&bev_ssl->bev);
 
+       if (bev_ssl->flags & BUFFEREVENT_SSL_BATCH_WRITE) {
+               /* Try to send as many as we can to avoid Nagle effect */
+               evbuffer_pullup(output, -1);
+       }
+
        n = evbuffer_peek(output, atmost, NULL, space, 8);
        if (n < 0)
                return OP_ERR | result;
@@ -1084,7 +1089,7 @@ ev_uint64_t bufferevent_ssl_set_flags(struct bufferevent *bev, ev_uint64_t flags
        ev_uint64_t old_flags = EV_UINT64_MAX;
        struct bufferevent_ssl *bev_ssl;
 
-       flags &= (BUFFEREVENT_SSL_DIRTY_SHUTDOWN);
+       flags &= (BUFFEREVENT_SSL_DIRTY_SHUTDOWN|BUFFEREVENT_SSL_BATCH_WRITE);
        if (!flags)
                return old_flags;
 
@@ -1103,7 +1108,7 @@ ev_uint64_t bufferevent_ssl_clear_flags(struct bufferevent *bev, ev_uint64_t fla
        ev_uint64_t old_flags = EV_UINT64_MAX;
        struct bufferevent_ssl *bev_ssl;
 
-       flags &= (BUFFEREVENT_SSL_DIRTY_SHUTDOWN);
+       flags &= (BUFFEREVENT_SSL_DIRTY_SHUTDOWN|BUFFEREVENT_SSL_BATCH_WRITE);
        if (!flags)
                return old_flags;
 
index 5abcb790be0d0169c91d5bc9a4afd64169995f10..355b632d354436a40c8767c11fbdbc6b1dba252f 100644 (file)
@@ -65,6 +65,18 @@ enum bufferevent_ssl_state {
     not to use SSL 2.)
 */
 #define BUFFEREVENT_SSL_DIRTY_SHUTDOWN 1
+/** Control writes in the SSL bufferevents.
+
+    By default SSL bufferevent will peek bytes from the buffer as the arrived.
+    with respect to the segment boundaries in the buffer.
+    However, by ignoring these segment boundaries number of packets to send
+    can be decreased.
+
+    This flags will ignore the segment boundaries.
+
+    Useful in conjunction with http layer.
+*/
+#define BUFFEREVENT_SSL_BATCH_WRITE 2
 
 #if defined(EVENT__HAVE_OPENSSL) || defined(EVENT_IN_DOXYGEN_)
 /* This is what openssl's SSL objects are underneath. */
index b5c37b808edfd9154a844e3900a979000029caa7..447a4c34bb6d7a6b71c4aeab25ac5b5d855fb318 100644 (file)
@@ -128,6 +128,8 @@ enum regress_openssl_type
        REGRESS_OPENSSL_CLIENT_WRITE = 2048,
 
        REGRESS_DEFERRED_CALLBACKS = 4096,
+
+       REGRESS_OPENSSL_BATCH_WRITE = 8192,
 };
 
 static void
@@ -299,6 +301,11 @@ open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out,
 
        bufferevent_ssl_set_allow_dirty_shutdown(*bev1_out, dirty_shutdown);
        bufferevent_ssl_set_allow_dirty_shutdown(*bev2_out, dirty_shutdown);
+
+       if (REGRESS_OPENSSL_BATCH_WRITE) {
+               bufferevent_ssl_set_flags(*bev1_out, BUFFEREVENT_SSL_BATCH_WRITE);
+               bufferevent_ssl_set_flags(*bev2_out, BUFFEREVENT_SSL_BATCH_WRITE);
+       }
 }
 
 static void
@@ -730,6 +737,8 @@ struct testcase_t TESTCASES_NAME[] = {
 #define T(a) ((void *)(a))
        { "bufferevent_socketpair", regress_bufferevent_openssl,
          TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR) },
+       { "bufferevent_socketpair_batch_write", regress_bufferevent_openssl,
+         TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_BATCH_WRITE) },
        { "bufferevent_socketpair_write_after_connect", regress_bufferevent_openssl,
          TT_ISOLATED, &ssl_setup,
          T(REGRESS_OPENSSL_SOCKETPAIR|REGRESS_OPENSSL_CLIENT_WRITE) },