From abcdca91ba6dc438aa30e63e164a073aed6d60f2 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 16 May 2017 23:32:57 +0900 Subject: [PATCH] nghttpx: Postpone early data processing if CH replay detected --- src/shrpx_connection.cc | 7 +++++-- src/shrpx_connection.h | 3 +++ src/shrpx_tls.cc | 7 ++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/shrpx_connection.cc b/src/shrpx_connection.cc index 162ca266..a98958cf 100644 --- a/src/shrpx_connection.cc +++ b/src/shrpx_connection.cc @@ -145,6 +145,7 @@ void Connection::disconnect() { tls.sct_requested = false; tls.early_data_finish = false; tls.early_cb_called = false; + tls.postpone_early_data = false; } if (fd != -1) { @@ -456,7 +457,8 @@ int Connection::tls_handshake() { // server waits for EndOfEarlyData and Finished message from // client, which voids the purpose of 0-RTT data. The left // over of handshake is done through write_tls or read_tls. - if ((tls.handshake_state == TLS_CONN_WRITE_STARTED || + if (!tls.postpone_early_data && + (tls.handshake_state == TLS_CONN_WRITE_STARTED || tls.wbuf.rleft()) && tls.earlybuf.rleft()) { rv = 1; @@ -478,7 +480,8 @@ int Connection::tls_handshake() { } tls.early_data_finish = true; // The same reason stated above. - if ((tls.handshake_state == TLS_CONN_WRITE_STARTED || + if (!tls.postpone_early_data && + (tls.handshake_state == TLS_CONN_WRITE_STARTED || tls.wbuf.rleft()) && tls.earlybuf.rleft()) { rv = 1; diff --git a/src/shrpx_connection.h b/src/shrpx_connection.h index 9bba780d..a71f1c6e 100644 --- a/src/shrpx_connection.h +++ b/src/shrpx_connection.h @@ -94,6 +94,9 @@ struct TLSConnection { bool early_data_finish; // true if early_cb gets called. bool early_cb_called; + // true if processing early data should be postponed until handshake + // finishes. + bool postpone_early_data; }; struct TCPHint { diff --git a/src/shrpx_tls.cc b/src/shrpx_tls.cc index 723b5e8b..89648b13 100644 --- a/src/shrpx_tls.cc +++ b/src/shrpx_tls.cc @@ -613,9 +613,10 @@ int early_cb(SSL *ssl, int *al, void *arg) { conn->tls.anti_replay_req = nullptr; if (res.status_code != 0) { - // If we cannot add key/value, just disable 0-RTT early data. - // Note that memcached atomically adds key/value. - conn->tls.early_data_finish = true; + // If we cannot add key/value, just postpone processing 0-RTT + // early data until handshake finishes. Note that memcached + // atomically adds key/value. + conn->tls.postpone_early_data = true; } conn->tls.handshake_state = TLS_CONN_NORMAL;