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