• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * nghttp2 - HTTP/2 C Library
3  *
4  * Copyright (c) 2015 Tatsuhiro Tsujikawa
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 #include "shrpx_connection.h"
26 
27 #ifdef HAVE_UNISTD_H
28 #  include <unistd.h>
29 #endif // HAVE_UNISTD_H
30 #include <netinet/tcp.h>
31 
32 #include <limits>
33 
34 #include "ssl_compat.h"
35 
36 #ifdef NGHTTP2_OPENSSL_IS_WOLFSSL
37 #  include <wolfssl/options.h>
38 #  include <wolfssl/openssl/err.h>
39 #else // !NGHTTP2_OPENSSL_IS_WOLFSSL
40 #  include <openssl/err.h>
41 #endif // !NGHTTP2_OPENSSL_IS_WOLFSSL
42 
43 #include "shrpx_tls.h"
44 #include "shrpx_memcached_request.h"
45 #include "shrpx_log.h"
46 #include "memchunk.h"
47 #include "util.h"
48 
49 using namespace nghttp2;
50 using namespace std::chrono_literals;
51 
52 namespace shrpx {
53 
Connection(struct ev_loop * loop,int fd,SSL * ssl,MemchunkPool * mcpool,ev_tstamp write_timeout,ev_tstamp read_timeout,const RateLimitConfig & write_limit,const RateLimitConfig & read_limit,IOCb writecb,IOCb readcb,TimerCb timeoutcb,void * data,size_t tls_dyn_rec_warmup_threshold,ev_tstamp tls_dyn_rec_idle_timeout,Proto proto)54 Connection::Connection(struct ev_loop *loop, int fd, SSL *ssl,
55                        MemchunkPool *mcpool, ev_tstamp write_timeout,
56                        ev_tstamp read_timeout,
57                        const RateLimitConfig &write_limit,
58                        const RateLimitConfig &read_limit, IOCb writecb,
59                        IOCb readcb, TimerCb timeoutcb, void *data,
60                        size_t tls_dyn_rec_warmup_threshold,
61                        ev_tstamp tls_dyn_rec_idle_timeout, Proto proto)
62   :
63 #ifdef ENABLE_HTTP3
64     conn_ref{nullptr, this},
65 #endif // ENABLE_HTTP3
66     tls{DefaultMemchunks(mcpool), DefaultPeekMemchunks(mcpool),
67         DefaultMemchunks(mcpool)},
68     wlimit(loop, &wev, write_limit.rate, write_limit.burst),
69     rlimit(loop, &rev, read_limit.rate, read_limit.burst, this),
70     loop(loop),
71     data(data),
72     fd(fd),
73     tls_dyn_rec_warmup_threshold(tls_dyn_rec_warmup_threshold),
74     tls_dyn_rec_idle_timeout(util::duration_from(tls_dyn_rec_idle_timeout)),
75     proto(proto),
76     read_timeout(read_timeout) {
77 
78   ev_io_init(&wev, writecb, fd, EV_WRITE);
79   ev_io_init(&rev, readcb, proto == Proto::HTTP3 ? 0 : fd, EV_READ);
80 
81   wev.data = this;
82   rev.data = this;
83 
84   ev_timer_init(&wt, timeoutcb, 0., write_timeout);
85   ev_timer_init(&rt, timeoutcb, 0., read_timeout);
86 
87   wt.data = this;
88   rt.data = this;
89 
90   if (ssl) {
91     set_ssl(ssl);
92   }
93 }
94 
~Connection()95 Connection::~Connection() { disconnect(); }
96 
disconnect()97 void Connection::disconnect() {
98   if (tls.ssl) {
99     if (proto != Proto::HTTP3) {
100       SSL_set_shutdown(tls.ssl,
101                        SSL_get_shutdown(tls.ssl) | SSL_RECEIVED_SHUTDOWN);
102       ERR_clear_error();
103 
104       if (tls.cached_session) {
105         SSL_SESSION_free(tls.cached_session);
106         tls.cached_session = nullptr;
107       }
108 
109       if (tls.cached_session_lookup_req) {
110         tls.cached_session_lookup_req->canceled = true;
111         tls.cached_session_lookup_req = nullptr;
112       }
113 
114       SSL_shutdown(tls.ssl);
115     }
116 
117     SSL_free(tls.ssl);
118     tls.ssl = nullptr;
119 
120     tls.wbuf.reset();
121     tls.rbuf.reset();
122     tls.last_write_idle = {};
123     tls.warmup_writelen = 0;
124     tls.last_writelen = 0;
125     tls.last_readlen = 0;
126     tls.handshake_state = TLSHandshakeState::NORMAL;
127     tls.initial_handshake_done = false;
128     tls.reneg_started = false;
129     tls.sct_requested = false;
130     tls.early_data_finish = false;
131   }
132 
133   if (proto != Proto::HTTP3 && fd != -1) {
134     shutdown(fd, SHUT_WR);
135     close(fd);
136     fd = -1;
137   }
138 
139   // Stop watchers here because they could be activated in
140   // SSL_shutdown().
141   ev_timer_stop(loop, &rt);
142   ev_timer_stop(loop, &wt);
143 
144   rlimit.stopw();
145   wlimit.stopw();
146 }
147 
prepare_client_handshake()148 void Connection::prepare_client_handshake() {
149   SSL_set_connect_state(tls.ssl);
150   // This prevents SSL_read_early_data from being called.
151   tls.early_data_finish = true;
152 }
153 
prepare_server_handshake()154 void Connection::prepare_server_handshake() {
155 #if defined(NGHTTP2_GENUINE_OPENSSL) ||                                        \
156   defined(NGHTTP2_OPENSSL_IS_BORINGSSL) ||                                     \
157   defined(NGHTTP2_OPENSSL_IS_LIBRESSL)
158   auto &tlsconf = get_config()->tls;
159   if (proto != Proto::HTTP3 && !tlsconf.session_cache.memcached.host.empty()) {
160     auto bio = BIO_new(tlsconf.bio_method);
161     BIO_set_data(bio, this);
162     SSL_set_bio(tls.ssl, bio, bio);
163   }
164 #endif // NGHTTP2_GENUINE_OPENSSL || NGHTTP2_OPENSSL_IS_BORINGSSL ||
165        // NGHTTP2_OPENSSL_IS_LIBRESSL
166 
167   SSL_set_accept_state(tls.ssl);
168   tls.server_handshake = true;
169 }
170 
171 #if defined(NGHTTP2_GENUINE_OPENSSL) ||                                        \
172   defined(NGHTTP2_OPENSSL_IS_BORINGSSL) ||                                     \
173   defined(NGHTTP2_OPENSSL_IS_LIBRESSL)
174 // BIO implementation is inspired by openldap implementation:
175 // http://www.openldap.org/devel/cvsweb.cgi/~checkout~/libraries/libldap/tls_o.c
176 namespace {
shrpx_bio_write(BIO * b,const char * buf,int len)177 int shrpx_bio_write(BIO *b, const char *buf, int len) {
178   if (buf == nullptr || len <= 0) {
179     return 0;
180   }
181 
182   auto conn = static_cast<Connection *>(BIO_get_data(b));
183   auto &wbuf = conn->tls.wbuf;
184 
185   BIO_clear_retry_flags(b);
186 
187   if (conn->tls.initial_handshake_done) {
188     // After handshake finished, send |buf| of length |len| to the
189     // socket directly.
190 
191     // Only when TLS session was prematurely ended before server sent
192     // all handshake message, this condition is true.  This could be
193     // alert from SSL_shutdown().  Since connection is already down,
194     // just return error.
195     if (wbuf.rleft()) {
196       return -1;
197     }
198     auto nwrite = conn->write_clear(buf, len);
199     if (nwrite < 0) {
200       return -1;
201     }
202 
203     if (nwrite == 0) {
204       BIO_set_retry_write(b);
205       return -1;
206     }
207 
208     return nwrite;
209   }
210 
211   wbuf.append(buf, len);
212 
213   return len;
214 }
215 } // namespace
216 
217 namespace {
shrpx_bio_read(BIO * b,char * buf,int len)218 int shrpx_bio_read(BIO *b, char *buf, int len) {
219   if (buf == nullptr || len <= 0) {
220     return 0;
221   }
222 
223   auto conn = static_cast<Connection *>(BIO_get_data(b));
224   auto &rbuf = conn->tls.rbuf;
225 
226   BIO_clear_retry_flags(b);
227 
228   if (conn->tls.initial_handshake_done && rbuf.rleft() == 0) {
229     auto nread = conn->read_clear(buf, len);
230     if (nread < 0) {
231       return -1;
232     }
233     if (nread == 0) {
234       BIO_set_retry_read(b);
235       return -1;
236     }
237     return nread;
238   }
239 
240   if (rbuf.rleft() == 0) {
241     BIO_set_retry_read(b);
242     return -1;
243   }
244 
245   return rbuf.remove(buf, len);
246 }
247 } // namespace
248 
249 namespace {
shrpx_bio_puts(BIO * b,const char * str)250 int shrpx_bio_puts(BIO *b, const char *str) {
251   return shrpx_bio_write(b, str, strlen(str));
252 }
253 } // namespace
254 
255 namespace {
shrpx_bio_gets(BIO * b,char * buf,int len)256 int shrpx_bio_gets(BIO *b, char *buf, int len) { return -1; }
257 } // namespace
258 
259 namespace {
shrpx_bio_ctrl(BIO * b,int cmd,long num,void * ptr)260 long shrpx_bio_ctrl(BIO *b, int cmd, long num, void *ptr) {
261   switch (cmd) {
262   case BIO_CTRL_FLUSH:
263     return 1;
264   }
265 
266   return 0;
267 }
268 } // namespace
269 
270 namespace {
shrpx_bio_create(BIO * b)271 int shrpx_bio_create(BIO *b) {
272   BIO_set_init(b, 1);
273 
274   return 1;
275 }
276 } // namespace
277 
278 namespace {
shrpx_bio_destroy(BIO * b)279 int shrpx_bio_destroy(BIO *b) {
280   if (b == nullptr) {
281     return 0;
282   }
283 
284   return 1;
285 }
286 } // namespace
287 
create_bio_method()288 BIO_METHOD *create_bio_method() {
289   auto meth = BIO_meth_new(BIO_TYPE_FD, "nghttpx-bio");
290   BIO_meth_set_write(meth, shrpx_bio_write);
291   BIO_meth_set_read(meth, shrpx_bio_read);
292   BIO_meth_set_puts(meth, shrpx_bio_puts);
293   BIO_meth_set_gets(meth, shrpx_bio_gets);
294   BIO_meth_set_ctrl(meth, shrpx_bio_ctrl);
295   BIO_meth_set_create(meth, shrpx_bio_create);
296   BIO_meth_set_destroy(meth, shrpx_bio_destroy);
297 
298   return meth;
299 }
300 #endif // NGHTTP2_GENUINE_OPENSSL || NGHTTP2_OPENSSL_IS_BORINGSSL ||
301        // NGHTTP2_OPENSSL_IS_LIBRESSL
302 
set_ssl(SSL * ssl)303 void Connection::set_ssl(SSL *ssl) {
304   tls.ssl = ssl;
305 
306   SSL_set_app_data(tls.ssl, this);
307 }
308 
309 namespace {
310 // We should buffer at least full encrypted TLS record here.
311 // Theoretically, peer can send client hello in several TLS records,
312 // which could exceed this limit, but it is not portable, and we don't
313 // have to handle such exotic behaviour.
read_buffer_full(DefaultPeekMemchunks & rbuf)314 bool read_buffer_full(DefaultPeekMemchunks &rbuf) {
315   return rbuf.rleft_buffered() >= 20_k;
316 }
317 } // namespace
318 
tls_handshake()319 int Connection::tls_handshake() {
320   wlimit.stopw();
321   ev_timer_stop(loop, &wt);
322 
323 #ifdef NGHTTP2_OPENSSL_IS_WOLFSSL
324   return tls_handshake_simple();
325 #else // !NGHTTP2_OPENSSL_IS_WOLFSSL
326   auto &tlsconf = get_config()->tls;
327 
328   if (!tls.server_handshake || tlsconf.session_cache.memcached.host.empty()) {
329     return tls_handshake_simple();
330   }
331 
332   std::array<uint8_t, 16_k> buf;
333 
334   if (ev_is_active(&rev)) {
335     auto nread = read_clear(buf.data(), buf.size());
336     if (nread < 0) {
337       if (LOG_ENABLED(INFO)) {
338         LOG(INFO) << "tls: handshake read error";
339       }
340       return -1;
341     }
342     tls.rbuf.append(buf.data(), nread);
343     if (read_buffer_full(tls.rbuf)) {
344       rlimit.stopw();
345     }
346   }
347 
348   if (tls.initial_handshake_done) {
349     return write_tls_pending_handshake();
350   }
351 
352   switch (tls.handshake_state) {
353   case TLSHandshakeState::WAIT_FOR_SESSION_CACHE:
354     return SHRPX_ERR_INPROGRESS;
355   case TLSHandshakeState::GOT_SESSION_CACHE: {
356     // Use the same trick invented by @kazuho in h2o project.
357 
358     // Discard all outgoing data.
359     tls.wbuf.reset();
360     // Rewind buffered incoming data to replay client hello.
361     tls.rbuf.disable_peek(false);
362 
363     auto ssl_ctx = SSL_get_SSL_CTX(tls.ssl);
364     auto ssl_opts = SSL_get_options(tls.ssl);
365     SSL_free(tls.ssl);
366 
367     auto ssl = tls::create_ssl(ssl_ctx);
368     if (!ssl) {
369       return -1;
370     }
371     if (ssl_opts & SSL_OP_NO_TICKET) {
372       SSL_set_options(ssl, SSL_OP_NO_TICKET);
373     }
374 
375     set_ssl(ssl);
376 
377     prepare_server_handshake();
378 
379     tls.handshake_state = TLSHandshakeState::NORMAL;
380     break;
381   }
382   case TLSHandshakeState::CANCEL_SESSION_CACHE:
383     tls.handshake_state = TLSHandshakeState::NORMAL;
384     break;
385   default:
386     break;
387   }
388 
389   int rv;
390 
391   ERR_clear_error();
392 
393 #  ifdef NGHTTP2_GENUINE_OPENSSL
394   if (!tls.server_handshake || tls.early_data_finish) {
395     rv = SSL_do_handshake(tls.ssl);
396   } else {
397     for (;;) {
398       size_t nread;
399 
400       rv = SSL_read_early_data(tls.ssl, buf.data(), buf.size(), &nread);
401       if (rv == SSL_READ_EARLY_DATA_ERROR) {
402         // If we have early data, and server sends ServerHello, assume
403         // that handshake is completed in server side, and start
404         // processing request.  If we don't exit handshake code here,
405         // server waits for EndOfEarlyData and Finished message from
406         // client, which voids the purpose of 0-RTT data.  The left
407         // over of handshake is done through write_tls or read_tls.
408         if (tlsconf.no_postpone_early_data &&
409             (tls.handshake_state == TLSHandshakeState::WRITE_STARTED ||
410              tls.wbuf.rleft()) &&
411             tls.earlybuf.rleft()) {
412           rv = 1;
413         }
414 
415         break;
416       }
417 
418       if (LOG_ENABLED(INFO)) {
419         LOG(INFO) << "tls: read early data " << nread << " bytes";
420       }
421 
422       tls.earlybuf.append(buf.data(), nread);
423 
424       if (rv == SSL_READ_EARLY_DATA_FINISH) {
425         if (LOG_ENABLED(INFO)) {
426           LOG(INFO) << "tls: read all early data; total "
427                     << tls.earlybuf.rleft() << " bytes";
428         }
429         tls.early_data_finish = true;
430         // The same reason stated above.
431         if (tlsconf.no_postpone_early_data &&
432             (tls.handshake_state == TLSHandshakeState::WRITE_STARTED ||
433              tls.wbuf.rleft()) &&
434             tls.earlybuf.rleft()) {
435           rv = 1;
436         } else {
437           ERR_clear_error();
438           rv = SSL_do_handshake(tls.ssl);
439         }
440         break;
441       }
442     }
443   }
444 #  else  // !NGHTTP2_GENUINE_OPENSSL
445   rv = SSL_do_handshake(tls.ssl);
446 #  endif // !NGHTTP2_GENUINE_OPENSSL
447 
448   if (rv <= 0) {
449     auto err = SSL_get_error(tls.ssl, rv);
450     switch (err) {
451     case SSL_ERROR_WANT_READ:
452       if (read_buffer_full(tls.rbuf)) {
453         if (LOG_ENABLED(INFO)) {
454           LOG(INFO) << "tls: handshake message is too large";
455         }
456         return -1;
457       }
458       break;
459     case SSL_ERROR_WANT_WRITE:
460       break;
461     case SSL_ERROR_SSL: {
462       if (LOG_ENABLED(INFO)) {
463         LOG(INFO) << "tls: handshake libssl error: "
464                   << ERR_error_string(ERR_get_error(), nullptr);
465       }
466 
467       struct iovec iov[1];
468       auto iovcnt = tls.wbuf.riovec(iov, 1);
469       auto nwrite = writev_clear(iov, iovcnt);
470       if (nwrite > 0) {
471         tls.wbuf.drain(nwrite);
472       }
473 
474       return SHRPX_ERR_NETWORK;
475     }
476     default:
477       if (LOG_ENABLED(INFO)) {
478         LOG(INFO) << "tls: handshake libssl error " << err;
479       }
480       return SHRPX_ERR_NETWORK;
481     }
482   }
483 
484   if (tls.handshake_state == TLSHandshakeState::WAIT_FOR_SESSION_CACHE) {
485     if (LOG_ENABLED(INFO)) {
486       LOG(INFO) << "tls: handshake is still in progress";
487     }
488     return SHRPX_ERR_INPROGRESS;
489   }
490 
491   // Don't send handshake data if handshake was completed in OpenSSL
492   // routine.  We have to check HTTP/2 requirement if HTTP/2 was
493   // negotiated before sending finished message to the peer.
494   if ((rv != 1
495 #  ifdef NGHTTP2_OPENSSL_IS_BORINGSSL
496        || SSL_in_init(tls.ssl)
497 #  endif // NGHTTP2_OPENSSL_IS_BORINGSSL
498          ) &&
499       tls.wbuf.rleft()) {
500     // First write indicates that resumption stuff has done.
501     if (tls.handshake_state != TLSHandshakeState::WRITE_STARTED) {
502       tls.handshake_state = TLSHandshakeState::WRITE_STARTED;
503       // If peek has already disabled, this is noop.
504       tls.rbuf.disable_peek(true);
505     }
506     std::array<struct iovec, 4> iov;
507     auto iovcnt = tls.wbuf.riovec(iov.data(), iov.size());
508     auto nwrite = writev_clear(iov.data(), iovcnt);
509     if (nwrite < 0) {
510       if (LOG_ENABLED(INFO)) {
511         LOG(INFO) << "tls: handshake write error";
512       }
513       return -1;
514     }
515     tls.wbuf.drain(nwrite);
516 
517     if (tls.wbuf.rleft()) {
518       wlimit.startw();
519       ev_timer_again(loop, &wt);
520     }
521   }
522 
523   if (!read_buffer_full(tls.rbuf)) {
524     // We may have stopped reading
525     rlimit.startw();
526   }
527 
528   if (rv != 1) {
529     if (LOG_ENABLED(INFO)) {
530       LOG(INFO) << "tls: handshake is still in progress";
531     }
532     return SHRPX_ERR_INPROGRESS;
533   }
534 
535 #  ifdef NGHTTP2_OPENSSL_IS_BORINGSSL
536   if (!tlsconf.no_postpone_early_data && SSL_in_early_data(tls.ssl) &&
537       SSL_in_init(tls.ssl)) {
538     auto nread = SSL_read(tls.ssl, buf.data(), buf.size());
539     if (nread <= 0) {
540       auto err = SSL_get_error(tls.ssl, nread);
541       switch (err) {
542       case SSL_ERROR_WANT_READ:
543       case SSL_ERROR_WANT_WRITE:
544         break;
545       case SSL_ERROR_ZERO_RETURN:
546         return SHRPX_ERR_EOF;
547       case SSL_ERROR_SSL:
548         if (LOG_ENABLED(INFO)) {
549           LOG(INFO) << "SSL_read: "
550                     << ERR_error_string(ERR_get_error(), nullptr);
551         }
552         return SHRPX_ERR_NETWORK;
553       default:
554         if (LOG_ENABLED(INFO)) {
555           LOG(INFO) << "SSL_read: SSL_get_error returned " << err;
556         }
557         return SHRPX_ERR_NETWORK;
558       }
559     } else {
560       tls.earlybuf.append(buf.data(), nread);
561     }
562 
563     if (SSL_in_init(tls.ssl)) {
564       return SHRPX_ERR_INPROGRESS;
565     }
566   }
567 #  endif // NGHTTP2_OPENSSL_IS_BORINGSSL
568 
569   // Handshake was done
570 
571   rv = check_http2_requirement();
572   if (rv != 0) {
573     return -1;
574   }
575 
576   // Just in case
577   tls.rbuf.disable_peek(true);
578 
579   tls.initial_handshake_done = true;
580 
581   return write_tls_pending_handshake();
582 #endif   // !NGHTTP2_OPENSSL_IS_WOLFSSL
583 }
584 
tls_handshake_simple()585 int Connection::tls_handshake_simple() {
586   wlimit.stopw();
587   ev_timer_stop(loop, &wt);
588 
589   if (tls.initial_handshake_done) {
590     return write_tls_pending_handshake();
591   }
592 
593   if (SSL_get_fd(tls.ssl) == -1) {
594     SSL_set_fd(tls.ssl, fd);
595   }
596 
597   int rv;
598 #if defined(NGHTTP2_GENUINE_OPENSSL) ||                                        \
599   defined(NGHTTP2_OPENSSL_IS_BORINGSSL) ||                                     \
600   (defined(NGHTTP2_OPENSSL_IS_WOLFSSL) && defined(WOLFSSL_EARLY_DATA))
601   auto &tlsconf = get_config()->tls;
602   std::array<uint8_t, 16_k> buf;
603 #endif // NGHTTP2_GENUINE_OPENSSL || NGHTTP2_OPENSSL_IS_BORINGSSL ||
604        // (NGHTTP2_OPENSSL_IS_WOLFSSL && WOLFSSL_EARLY_DATA)
605 
606   ERR_clear_error();
607 
608 #ifdef NGHTTP2_GENUINE_OPENSSL
609   if (!tls.server_handshake || tls.early_data_finish) {
610     rv = SSL_do_handshake(tls.ssl);
611   } else {
612     for (;;) {
613       size_t nread;
614 
615       rv = SSL_read_early_data(tls.ssl, buf.data(), buf.size(), &nread);
616       if (rv == SSL_READ_EARLY_DATA_ERROR) {
617         // If we have early data, and server sends ServerHello, assume
618         // that handshake is completed in server side, and start
619         // processing request.  If we don't exit handshake code here,
620         // server waits for EndOfEarlyData and Finished message from
621         // client, which voids the purpose of 0-RTT data.  The left
622         // over of handshake is done through write_tls or read_tls.
623         if (tlsconf.no_postpone_early_data && tls.earlybuf.rleft()) {
624           rv = 1;
625         }
626 
627         break;
628       }
629 
630       if (LOG_ENABLED(INFO)) {
631         LOG(INFO) << "tls: read early data " << nread << " bytes";
632       }
633 
634       tls.earlybuf.append(buf.data(), nread);
635 
636       if (rv == SSL_READ_EARLY_DATA_FINISH) {
637         if (LOG_ENABLED(INFO)) {
638           LOG(INFO) << "tls: read all early data; total "
639                     << tls.earlybuf.rleft() << " bytes";
640         }
641         tls.early_data_finish = true;
642         // The same reason stated above.
643         if (tlsconf.no_postpone_early_data && tls.earlybuf.rleft()) {
644           rv = 1;
645         } else {
646           ERR_clear_error();
647           rv = SSL_do_handshake(tls.ssl);
648         }
649         break;
650       }
651     }
652   }
653 #elif defined(NGHTTP2_OPENSSL_IS_WOLFSSL) && defined(WOLFSSL_EARLY_DATA)
654   if (!tls.server_handshake || tls.early_data_finish) {
655     rv = SSL_do_handshake(tls.ssl);
656   } else {
657     for (;;) {
658       size_t nread = 0;
659 
660       rv = SSL_read_early_data(tls.ssl, buf.data(), buf.size(), &nread);
661       if (rv < 0) {
662         if (SSL_get_error(tls.ssl, rv) == SSL_ERROR_WANT_READ) {
663           if (tlsconf.no_postpone_early_data && tls.earlybuf.rleft()) {
664             rv = 1;
665           }
666 
667           break;
668         }
669 
670         /* It looks like we are here if there is no early data. */
671         tls.early_data_finish = true;
672 
673         ERR_clear_error();
674         rv = SSL_do_handshake(tls.ssl);
675 
676         break;
677       }
678 
679       if (LOG_ENABLED(INFO)) {
680         LOG(INFO) << "tls: read early data " << nread << " bytes";
681       }
682 
683       tls.earlybuf.append(buf.data(), nread);
684 
685       if (rv == 0) {
686         if (LOG_ENABLED(INFO)) {
687           LOG(INFO) << "tls: read all early data; total "
688                     << tls.earlybuf.rleft() << " bytes";
689         }
690         tls.early_data_finish = true;
691         // The same reason stated above.
692         if (tlsconf.no_postpone_early_data && tls.earlybuf.rleft()) {
693           rv = 1;
694         } else {
695           ERR_clear_error();
696           rv = SSL_do_handshake(tls.ssl);
697         }
698         break;
699       }
700     }
701   }
702 #else  // !NGHTTP2_GENUINE_OPENSSL && !(NGHTTP2_OPENSSL_IS_WOLFSSL &&
703        // WOLFSSL_EARLY_DATA)
704   rv = SSL_do_handshake(tls.ssl);
705 #endif // !NGHTTP2_GENUINE_OPENSSL && !(NGHTTP2_OPENSSL_IS_WOLFSSL &&
706        // WOLFSSL_EARLY_DATA)
707 
708   if (rv <= 0) {
709     auto err = SSL_get_error(tls.ssl, rv);
710     switch (err) {
711     case SSL_ERROR_WANT_READ:
712       if (read_buffer_full(tls.rbuf)) {
713         if (LOG_ENABLED(INFO)) {
714           LOG(INFO) << "tls: handshake message is too large";
715         }
716         return -1;
717       }
718       break;
719     case SSL_ERROR_WANT_WRITE:
720       wlimit.startw();
721       ev_timer_again(loop, &wt);
722       break;
723     case SSL_ERROR_SSL: {
724       if (LOG_ENABLED(INFO)) {
725         LOG(INFO) << "tls: handshake libssl error: "
726                   << ERR_error_string(ERR_get_error(), nullptr);
727       }
728       return SHRPX_ERR_NETWORK;
729     }
730     default:
731       if (LOG_ENABLED(INFO)) {
732         LOG(INFO) << "tls: handshake libssl error " << err;
733       }
734       return SHRPX_ERR_NETWORK;
735     }
736   }
737 
738   if (rv != 1) {
739     if (LOG_ENABLED(INFO)) {
740       LOG(INFO) << "tls: handshake is still in progress";
741     }
742     return SHRPX_ERR_INPROGRESS;
743   }
744 
745 #ifdef NGHTTP2_OPENSSL_IS_BORINGSSL
746   if (!tlsconf.no_postpone_early_data && SSL_in_early_data(tls.ssl) &&
747       SSL_in_init(tls.ssl)) {
748     auto nread = SSL_read(tls.ssl, buf.data(), buf.size());
749     if (nread <= 0) {
750       auto err = SSL_get_error(tls.ssl, nread);
751       switch (err) {
752       case SSL_ERROR_WANT_READ:
753       case SSL_ERROR_WANT_WRITE:
754         break;
755       case SSL_ERROR_ZERO_RETURN:
756         return SHRPX_ERR_EOF;
757       case SSL_ERROR_SSL:
758         if (LOG_ENABLED(INFO)) {
759           LOG(INFO) << "SSL_read: "
760                     << ERR_error_string(ERR_get_error(), nullptr);
761         }
762         return SHRPX_ERR_NETWORK;
763       default:
764         if (LOG_ENABLED(INFO)) {
765           LOG(INFO) << "SSL_read: SSL_get_error returned " << err;
766         }
767         return SHRPX_ERR_NETWORK;
768       }
769     } else {
770       tls.earlybuf.append(buf.data(), nread);
771     }
772 
773     if (SSL_in_init(tls.ssl)) {
774       return SHRPX_ERR_INPROGRESS;
775     }
776   }
777 #endif // NGHTTP2_OPENSSL_IS_BORINGSSL
778 
779   // Handshake was done
780 
781   rv = check_http2_requirement();
782   if (rv != 0) {
783     return -1;
784   }
785 
786   tls.initial_handshake_done = true;
787 
788   return write_tls_pending_handshake();
789 }
790 
write_tls_pending_handshake()791 int Connection::write_tls_pending_handshake() {
792   // Send handshake data left in the buffer
793   while (tls.wbuf.rleft()) {
794     std::array<struct iovec, 4> iov;
795     auto iovcnt = tls.wbuf.riovec(iov.data(), iov.size());
796     auto nwrite = writev_clear(iov.data(), iovcnt);
797     if (nwrite < 0) {
798       if (LOG_ENABLED(INFO)) {
799         LOG(INFO) << "tls: handshake write error";
800       }
801       return -1;
802     }
803     if (nwrite == 0) {
804       wlimit.startw();
805       ev_timer_again(loop, &wt);
806 
807       return SHRPX_ERR_INPROGRESS;
808     }
809     tls.wbuf.drain(nwrite);
810   }
811 
812 #ifdef NGHTTP2_OPENSSL_IS_BORINGSSL
813   if (!SSL_in_init(tls.ssl)) {
814     // This will send a session ticket.
815     auto nwrite = SSL_write(tls.ssl, "", 0);
816     if (nwrite < 0) {
817       auto err = SSL_get_error(tls.ssl, nwrite);
818       switch (err) {
819       case SSL_ERROR_WANT_READ:
820         if (LOG_ENABLED(INFO)) {
821           LOG(INFO) << "Close connection due to TLS renegotiation";
822         }
823         return SHRPX_ERR_NETWORK;
824       case SSL_ERROR_WANT_WRITE:
825         break;
826       case SSL_ERROR_SSL:
827         if (LOG_ENABLED(INFO)) {
828           LOG(INFO) << "SSL_write: "
829                     << ERR_error_string(ERR_get_error(), nullptr);
830         }
831         return SHRPX_ERR_NETWORK;
832       default:
833         if (LOG_ENABLED(INFO)) {
834           LOG(INFO) << "SSL_write: SSL_get_error returned " << err;
835         }
836         return SHRPX_ERR_NETWORK;
837       }
838     }
839   }
840 #endif // NGHTTP2_OPENSSL_IS_BORINGSSL
841 
842   // We have to start read watcher, since later stage of code expects
843   // this.
844   rlimit.startw();
845 
846   // We may have whole request in tls.rbuf.  This means that we don't
847   // get notified further read event.  This is especially true for
848   // HTTP/1.1.
849   handle_tls_pending_read();
850 
851   if (LOG_ENABLED(INFO)) {
852     LOG(INFO) << "SSL/TLS handshake completed";
853     nghttp2::tls::TLSSessionInfo tls_info{};
854     if (nghttp2::tls::get_tls_session_info(&tls_info, tls.ssl)) {
855       LOG(INFO) << "cipher=" << tls_info.cipher
856                 << " protocol=" << tls_info.protocol
857                 << " resumption=" << (tls_info.session_reused ? "yes" : "no")
858                 << " session_id="
859                 << util::format_hex(std::span{tls_info.session_id,
860                                               tls_info.session_id_length});
861     }
862   }
863 
864   return 0;
865 }
866 
check_http2_requirement()867 int Connection::check_http2_requirement() {
868   const unsigned char *next_proto = nullptr;
869   unsigned int next_proto_len;
870 
871   SSL_get0_alpn_selected(tls.ssl, &next_proto, &next_proto_len);
872   if (next_proto == nullptr ||
873       !util::check_h2_is_selected(StringRef{next_proto, next_proto_len})) {
874     return 0;
875   }
876   if (!nghttp2::tls::check_http2_tls_version(tls.ssl)) {
877     if (LOG_ENABLED(INFO)) {
878       LOG(INFO) << "TLSv1.2 was not negotiated.  HTTP/2 must not be used.";
879     }
880     return -1;
881   }
882 
883   auto check_block_list = false;
884   if (tls.server_handshake) {
885     check_block_list = !get_config()->tls.no_http2_cipher_block_list;
886   } else {
887     check_block_list = !get_config()->tls.client.no_http2_cipher_block_list;
888   }
889 
890   if (check_block_list &&
891       nghttp2::tls::check_http2_cipher_block_list(tls.ssl)) {
892     if (LOG_ENABLED(INFO)) {
893       LOG(INFO) << "The negotiated cipher suite is in HTTP/2 cipher suite "
894                    "block list.  HTTP/2 must not be used.";
895     }
896     return -1;
897   }
898 
899   return 0;
900 }
901 
902 namespace {
903 constexpr size_t SHRPX_SMALL_WRITE_LIMIT = 1300;
904 } // namespace
905 
get_tls_write_limit()906 size_t Connection::get_tls_write_limit() {
907   if (tls_dyn_rec_warmup_threshold == 0) {
908     return std::numeric_limits<ssize_t>::max();
909   }
910 
911   auto t = std::chrono::steady_clock::now();
912 
913   if (tls.last_write_idle.time_since_epoch().count() >= 0 &&
914       t - tls.last_write_idle > tls_dyn_rec_idle_timeout) {
915     // Time out, use small record size
916     tls.warmup_writelen = 0;
917     return SHRPX_SMALL_WRITE_LIMIT;
918   }
919 
920   if (tls.warmup_writelen >= tls_dyn_rec_warmup_threshold) {
921     return std::numeric_limits<ssize_t>::max();
922   }
923 
924   return SHRPX_SMALL_WRITE_LIMIT;
925 }
926 
update_tls_warmup_writelen(size_t n)927 void Connection::update_tls_warmup_writelen(size_t n) {
928   if (tls.warmup_writelen < tls_dyn_rec_warmup_threshold) {
929     tls.warmup_writelen += n;
930   }
931 }
932 
start_tls_write_idle()933 void Connection::start_tls_write_idle() {
934   if (tls.last_write_idle.time_since_epoch().count() < 0) {
935     tls.last_write_idle = std::chrono::steady_clock::now();
936   }
937 }
938 
write_tls(const void * data,size_t len)939 nghttp2_ssize Connection::write_tls(const void *data, size_t len) {
940   // SSL_write requires the same arguments (buf pointer and its
941   // length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.
942   // get_write_limit() may return smaller length than previously
943   // passed to SSL_write, which violates OpenSSL assumption.  To avoid
944   // this, we keep last length passed to SSL_write to
945   // tls.last_writelen if SSL_write indicated I/O blocking.
946   if (tls.last_writelen == 0) {
947     len = std::min(len, wlimit.avail());
948     len = std::min(len, get_tls_write_limit());
949     if (len == 0) {
950       return 0;
951     }
952   } else {
953     len = tls.last_writelen;
954     tls.last_writelen = 0;
955   }
956 
957   tls.last_write_idle = std::chrono::steady_clock::time_point(-1s);
958 
959   auto &tlsconf = get_config()->tls;
960   auto via_bio =
961     tls.server_handshake && !tlsconf.session_cache.memcached.host.empty();
962 
963   ERR_clear_error();
964 
965 #ifdef NGHTTP2_GENUINE_OPENSSL
966   int rv;
967   if (SSL_is_init_finished(tls.ssl)) {
968     rv = SSL_write(tls.ssl, data, len);
969   } else {
970     size_t nwrite;
971     rv = SSL_write_early_data(tls.ssl, data, len, &nwrite);
972     // Use the same semantics with SSL_write.
973     if (rv == 1) {
974       rv = nwrite;
975     }
976   }
977 #else  // !NGHTTP2_GENUINE_OPENSSL
978   auto rv = SSL_write(tls.ssl, data, len);
979 #endif // !NGHTTP2_GENUINE_OPENSSL
980 
981   if (rv <= 0) {
982     auto err = SSL_get_error(tls.ssl, rv);
983     switch (err) {
984     case SSL_ERROR_WANT_READ:
985       if (LOG_ENABLED(INFO)) {
986         LOG(INFO) << "Close connection due to TLS renegotiation";
987       }
988       return SHRPX_ERR_NETWORK;
989     case SSL_ERROR_WANT_WRITE:
990       tls.last_writelen = len;
991       // starting write watcher and timer is done in write_clear via
992       // bio otherwise.
993       if (!via_bio) {
994         wlimit.startw();
995         ev_timer_again(loop, &wt);
996       }
997 
998       return 0;
999     case SSL_ERROR_SSL:
1000       if (LOG_ENABLED(INFO)) {
1001         LOG(INFO) << "SSL_write: "
1002                   << ERR_error_string(ERR_get_error(), nullptr);
1003       }
1004       return SHRPX_ERR_NETWORK;
1005     default:
1006       if (LOG_ENABLED(INFO)) {
1007         LOG(INFO) << "SSL_write: SSL_get_error returned " << err;
1008       }
1009       return SHRPX_ERR_NETWORK;
1010     }
1011   }
1012 
1013   if (!via_bio) {
1014     wlimit.drain(rv);
1015 
1016     if (ev_is_active(&wt)) {
1017       ev_timer_again(loop, &wt);
1018     }
1019   }
1020 
1021   update_tls_warmup_writelen(rv);
1022 
1023   return rv;
1024 }
1025 
read_tls(void * data,size_t len)1026 nghttp2_ssize Connection::read_tls(void *data, size_t len) {
1027   ERR_clear_error();
1028 
1029 #if defined(NGHTTP2_GENUINE_OPENSSL) ||                                        \
1030   defined(NGHTTP2_OPENSSL_IS_BORINGSSL) || defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
1031   if (tls.earlybuf.rleft()) {
1032     return tls.earlybuf.remove(data, len);
1033   }
1034 #endif // NGHTTP2_GENUINE_OPENSSL || NGHTTP2_OPENSSL_IS_BORINGSSL ||
1035        // defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
1036 
1037   // SSL_read requires the same arguments (buf pointer and its
1038   // length) on SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE.
1039   // rlimit_.avail() or rlimit_.avail() may return different length
1040   // than the length previously passed to SSL_read, which violates
1041   // OpenSSL assumption.  To avoid this, we keep last length passed
1042   // to SSL_read to tls_last_readlen_ if SSL_read indicated I/O
1043   // blocking.
1044   if (tls.last_readlen == 0) {
1045     len = std::min(len, rlimit.avail());
1046     if (len == 0) {
1047       return 0;
1048     }
1049   } else {
1050     len = tls.last_readlen;
1051     tls.last_readlen = 0;
1052   }
1053 
1054   auto &tlsconf = get_config()->tls;
1055   auto via_bio =
1056     tls.server_handshake && !tlsconf.session_cache.memcached.host.empty();
1057 
1058 #ifdef NGHTTP2_GENUINE_OPENSSL
1059   if (!tls.early_data_finish) {
1060     // TLSv1.3 handshake is still going on.
1061     size_t nread;
1062     auto rv = SSL_read_early_data(tls.ssl, data, len, &nread);
1063     if (rv == SSL_READ_EARLY_DATA_ERROR) {
1064       auto err = SSL_get_error(tls.ssl, rv);
1065       switch (err) {
1066       case SSL_ERROR_WANT_READ:
1067         tls.last_readlen = len;
1068         return 0;
1069       case SSL_ERROR_SSL:
1070         if (LOG_ENABLED(INFO)) {
1071           LOG(INFO) << "SSL_read: "
1072                     << ERR_error_string(ERR_get_error(), nullptr);
1073         }
1074         return SHRPX_ERR_NETWORK;
1075       default:
1076         if (LOG_ENABLED(INFO)) {
1077           LOG(INFO) << "SSL_read: SSL_get_error returned " << err;
1078         }
1079         return SHRPX_ERR_NETWORK;
1080       }
1081     }
1082 
1083     if (LOG_ENABLED(INFO)) {
1084       LOG(INFO) << "tls: read early data " << nread << " bytes";
1085     }
1086 
1087     if (rv == SSL_READ_EARLY_DATA_FINISH) {
1088       if (LOG_ENABLED(INFO)) {
1089         LOG(INFO) << "tls: read all early data";
1090       }
1091       tls.early_data_finish = true;
1092       // We may have stopped write watcher in write_tls.
1093       wlimit.startw();
1094     }
1095 
1096     if (!via_bio) {
1097       rlimit.drain(nread);
1098     }
1099 
1100     return nread;
1101   }
1102 #endif // NGHTTP2_GENUINE_OPENSSL
1103 
1104 #if defined(NGHTTP2_OPENSSL_IS_WOLFSSL) && defined(WOLFSSL_EARLY_DATA)
1105   if (!tls.early_data_finish) {
1106     // TLSv1.3 handshake is still going on.
1107     size_t nread = 0;
1108     auto rv = SSL_read_early_data(tls.ssl, data, len, &nread);
1109     if (rv < 0) {
1110       auto err = SSL_get_error(tls.ssl, rv);
1111       switch (err) {
1112       case SSL_ERROR_WANT_READ:
1113         tls.last_readlen = len;
1114         return 0;
1115       case SSL_ERROR_SSL:
1116         if (LOG_ENABLED(INFO)) {
1117           LOG(INFO) << "SSL_read: "
1118                     << ERR_error_string(ERR_get_error(), nullptr);
1119         }
1120         return SHRPX_ERR_NETWORK;
1121       default:
1122         if (LOG_ENABLED(INFO)) {
1123           LOG(INFO) << "SSL_read: SSL_get_error returned " << err;
1124         }
1125         return SHRPX_ERR_NETWORK;
1126       }
1127     }
1128 
1129     if (LOG_ENABLED(INFO)) {
1130       LOG(INFO) << "tls: read early data " << nread << " bytes";
1131     }
1132 
1133     if (rv == 0) {
1134       if (LOG_ENABLED(INFO)) {
1135         LOG(INFO) << "tls: read all early data";
1136       }
1137       tls.early_data_finish = true;
1138       // We may have stopped write watcher in write_tls.
1139       wlimit.startw();
1140     }
1141 
1142     if (!via_bio) {
1143       rlimit.drain(nread);
1144     }
1145 
1146     return nread;
1147   }
1148 #endif // NGHTTP2_OPENSSL_IS_WOLFSSL && WOLFSSL_EARLY_DATA
1149 
1150   auto rv = SSL_read(tls.ssl, data, len);
1151 
1152   if (rv <= 0) {
1153     auto err = SSL_get_error(tls.ssl, rv);
1154     switch (err) {
1155     case SSL_ERROR_WANT_READ:
1156       tls.last_readlen = len;
1157       return 0;
1158     case SSL_ERROR_WANT_WRITE:
1159       if (LOG_ENABLED(INFO)) {
1160         LOG(INFO) << "Close connection due to TLS renegotiation";
1161       }
1162       return SHRPX_ERR_NETWORK;
1163     case SSL_ERROR_ZERO_RETURN:
1164       return SHRPX_ERR_EOF;
1165     case SSL_ERROR_SSL:
1166       if (LOG_ENABLED(INFO)) {
1167         LOG(INFO) << "SSL_read: " << ERR_error_string(ERR_get_error(), nullptr);
1168       }
1169       return SHRPX_ERR_NETWORK;
1170     default:
1171       if (LOG_ENABLED(INFO)) {
1172         LOG(INFO) << "SSL_read: SSL_get_error returned " << err;
1173       }
1174       return SHRPX_ERR_NETWORK;
1175     }
1176   }
1177 
1178   if (!via_bio) {
1179     rlimit.drain(rv);
1180   }
1181 
1182   return rv;
1183 }
1184 
write_clear(const void * data,size_t len)1185 nghttp2_ssize Connection::write_clear(const void *data, size_t len) {
1186   len = std::min(len, wlimit.avail());
1187   if (len == 0) {
1188     return 0;
1189   }
1190 
1191   ssize_t nwrite;
1192   while ((nwrite = write(fd, data, len)) == -1 && errno == EINTR)
1193     ;
1194   if (nwrite == -1) {
1195     if (errno == EAGAIN || errno == EWOULDBLOCK) {
1196       wlimit.startw();
1197       ev_timer_again(loop, &wt);
1198       return 0;
1199     }
1200     return SHRPX_ERR_NETWORK;
1201   }
1202 
1203   wlimit.drain(nwrite);
1204 
1205   if (ev_is_active(&wt)) {
1206     ev_timer_again(loop, &wt);
1207   }
1208 
1209   return nwrite;
1210 }
1211 
writev_clear(struct iovec * iov,int iovcnt)1212 nghttp2_ssize Connection::writev_clear(struct iovec *iov, int iovcnt) {
1213   iovcnt = limit_iovec(iov, iovcnt, wlimit.avail());
1214   if (iovcnt == 0) {
1215     return 0;
1216   }
1217 
1218   ssize_t nwrite;
1219   while ((nwrite = writev(fd, iov, iovcnt)) == -1 && errno == EINTR)
1220     ;
1221   if (nwrite == -1) {
1222     if (errno == EAGAIN || errno == EWOULDBLOCK) {
1223       wlimit.startw();
1224       ev_timer_again(loop, &wt);
1225       return 0;
1226     }
1227     return SHRPX_ERR_NETWORK;
1228   }
1229 
1230   wlimit.drain(nwrite);
1231 
1232   if (ev_is_active(&wt)) {
1233     ev_timer_again(loop, &wt);
1234   }
1235 
1236   return nwrite;
1237 }
1238 
read_clear(void * data,size_t len)1239 nghttp2_ssize Connection::read_clear(void *data, size_t len) {
1240   len = std::min(len, rlimit.avail());
1241   if (len == 0) {
1242     return 0;
1243   }
1244 
1245   ssize_t nread;
1246   while ((nread = read(fd, data, len)) == -1 && errno == EINTR)
1247     ;
1248   if (nread == -1) {
1249     if (errno == EAGAIN || errno == EWOULDBLOCK) {
1250       return 0;
1251     }
1252     return SHRPX_ERR_NETWORK;
1253   }
1254 
1255   if (nread == 0) {
1256     return SHRPX_ERR_EOF;
1257   }
1258 
1259   rlimit.drain(nread);
1260 
1261   return nread;
1262 }
1263 
read_nolim_clear(void * data,size_t len)1264 nghttp2_ssize Connection::read_nolim_clear(void *data, size_t len) {
1265   ssize_t nread;
1266   while ((nread = read(fd, data, len)) == -1 && errno == EINTR)
1267     ;
1268   if (nread == -1) {
1269     if (errno == EAGAIN || errno == EWOULDBLOCK) {
1270       return 0;
1271     }
1272     return SHRPX_ERR_NETWORK;
1273   }
1274 
1275   if (nread == 0) {
1276     return SHRPX_ERR_EOF;
1277   }
1278 
1279   return nread;
1280 }
1281 
peek_clear(void * data,size_t len)1282 nghttp2_ssize Connection::peek_clear(void *data, size_t len) {
1283   ssize_t nread;
1284   while ((nread = recv(fd, data, len, MSG_PEEK)) == -1 && errno == EINTR)
1285     ;
1286   if (nread == -1) {
1287     if (errno == EAGAIN || errno == EWOULDBLOCK) {
1288       return 0;
1289     }
1290     return SHRPX_ERR_NETWORK;
1291   }
1292 
1293   if (nread == 0) {
1294     return SHRPX_ERR_EOF;
1295   }
1296 
1297   return nread;
1298 }
1299 
handle_tls_pending_read()1300 void Connection::handle_tls_pending_read() {
1301   if (!ev_is_active(&rev)) {
1302     return;
1303   }
1304   rlimit.handle_tls_pending_read();
1305 }
1306 
get_tcp_hint(TCPHint * hint) const1307 int Connection::get_tcp_hint(TCPHint *hint) const {
1308 #if defined(TCP_INFO) && defined(TCP_NOTSENT_LOWAT)
1309   struct tcp_info tcp_info;
1310   socklen_t tcp_info_len = sizeof(tcp_info);
1311   int rv;
1312 
1313   rv = getsockopt(fd, IPPROTO_TCP, TCP_INFO, &tcp_info, &tcp_info_len);
1314 
1315   if (rv != 0) {
1316     return -1;
1317   }
1318 
1319   auto avail_packets = tcp_info.tcpi_snd_cwnd > tcp_info.tcpi_unacked
1320                          ? tcp_info.tcpi_snd_cwnd - tcp_info.tcpi_unacked
1321                          : 0;
1322 
1323   // http://www.slideshare.net/kazuho/programming-tcp-for-responsiveness
1324 
1325   // TODO 29 (5 (header) + 8 (explicit nonce) + 16 (tag)) is TLS
1326   // overhead for AES-GCM.  For CHACHA20_POLY1305, it is 21 since it
1327   // does not need 8 bytes explicit nonce.
1328   //
1329   // For TLSv1.3, AES-GCM and CHACHA20_POLY1305 overhead are now 22
1330   // bytes (5 (header) + 1 (ContentType) + 16 (tag)).
1331   size_t tls_overhead;
1332 #  ifdef TLS1_3_VERSION
1333   if (SSL_version(tls.ssl) == TLS1_3_VERSION) {
1334     tls_overhead = 22;
1335   } else
1336 #  endif // TLS1_3_VERSION
1337   {
1338     tls_overhead = 29;
1339   }
1340 
1341   auto writable_size =
1342     (avail_packets + 2) * (tcp_info.tcpi_snd_mss - tls_overhead);
1343   if (writable_size > 16_k) {
1344     writable_size = writable_size & ~(16_k - 1);
1345   } else {
1346     if (writable_size < 536) {
1347       LOG(INFO) << "writable_size is too small: " << writable_size;
1348     }
1349     // TODO is this required?
1350     writable_size = std::max(writable_size, static_cast<size_t>(536 * 2));
1351   }
1352 
1353   // if (LOG_ENABLED(INFO)) {
1354   //   LOG(INFO) << "snd_cwnd=" << tcp_info.tcpi_snd_cwnd
1355   //             << ", unacked=" << tcp_info.tcpi_unacked
1356   //             << ", snd_mss=" << tcp_info.tcpi_snd_mss
1357   //             << ", rtt=" << tcp_info.tcpi_rtt << "us"
1358   //             << ", rcv_space=" << tcp_info.tcpi_rcv_space
1359   //             << ", writable=" << writable_size;
1360   // }
1361 
1362   hint->write_buffer_size = writable_size;
1363   // TODO tcpi_rcv_space is considered as rwin, is that correct?
1364   hint->rwin = tcp_info.tcpi_rcv_space;
1365 
1366   return 0;
1367 #else  // !defined(TCP_INFO) || !defined(TCP_NOTSENT_LOWAT)
1368   return -1;
1369 #endif // !defined(TCP_INFO) || !defined(TCP_NOTSENT_LOWAT)
1370 }
1371 
again_rt(ev_tstamp t)1372 void Connection::again_rt(ev_tstamp t) {
1373   read_timeout = t;
1374   rt.repeat = t;
1375   ev_timer_again(loop, &rt);
1376   last_read = std::chrono::steady_clock::now();
1377 }
1378 
again_rt()1379 void Connection::again_rt() {
1380   rt.repeat = read_timeout;
1381   ev_timer_again(loop, &rt);
1382   last_read = std::chrono::steady_clock::now();
1383 }
1384 
expired_rt()1385 bool Connection::expired_rt() {
1386   auto delta = read_timeout - util::ev_tstamp_from(
1387                                 std::chrono::steady_clock::now() - last_read);
1388   if (delta < 1e-9) {
1389     return true;
1390   }
1391   rt.repeat = delta;
1392   ev_timer_again(loop, &rt);
1393   return false;
1394 }
1395 
1396 } // namespace shrpx
1397