read_timeout(read_timeout) {
ev_io_init(&wev, writecb, fd, EV_WRITE);
- ev_io_init(&rev, readcb, fd, EV_READ);
+ ev_io_init(&rev, readcb, proto == Proto::HTTP3 ? 0 : fd, EV_READ);
wev.data = this;
rev.data = this;
tls.early_data_finish = false;
}
- if (fd != -1) {
+ if (proto != Proto::HTTP3 && fd != -1) {
shutdown(fd, SHUT_WR);
close(fd);
fd = -1;
void Connection::set_ssl(SSL *ssl) {
tls.ssl = ssl;
- auto &tlsconf = get_config()->tls;
- auto bio = BIO_new(tlsconf.bio_method);
- BIO_set_data(bio, this);
- SSL_set_bio(tls.ssl, bio, bio);
+ if (proto != Proto::HTTP3) {
+ auto &tlsconf = get_config()->tls;
+ auto bio = BIO_new(tlsconf.bio_method);
+ BIO_set_data(bio, this);
+ SSL_set_bio(tls.ssl, bio, bio);
+ }
+
SSL_set_app_data(tls.ssl, this);
}
ERR_clear_error();
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API || defined(OPENSSL_IS_BORINGSSL)
+ auto &tlsconf = get_config()->tls;
+#endif // OPENSSL_1_1_1_API || defined(OPENSSL_IS_BORINGSSL)
+
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
if (!tls.server_handshake || tls.early_data_finish) {
rv = SSL_do_handshake(tls.ssl);
} else {
- auto &tlsconf = get_config()->tls;
for (;;) {
size_t nread;
}
}
}
-#else // !OPENSSL_1_1_1_API
+#else // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
rv = SSL_do_handshake(tls.ssl);
-#endif // !OPENSSL_1_1_1_API
+#endif // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
if (rv <= 0) {
auto err = SSL_get_error(tls.ssl, rv);
// Don't send handshake data if handshake was completed in OpenSSL
// routine. We have to check HTTP/2 requirement if HTTP/2 was
// negotiated before sending finished message to the peer.
- if (rv != 1 && tls.wbuf.rleft()) {
+ if ((rv != 1
+#ifdef OPENSSL_IS_BORINGSSL
+ || SSL_in_init(tls.ssl)
+#endif // OPENSSL_IS_BORINGSSL
+ ) &&
+ tls.wbuf.rleft()) {
// First write indicates that resumption stuff has done.
if (tls.handshake_state != TLSHandshakeState::WRITE_STARTED) {
tls.handshake_state = TLSHandshakeState::WRITE_STARTED;
return SHRPX_ERR_INPROGRESS;
}
+#ifdef OPENSSL_IS_BORINGSSL
+ if (!tlsconf.no_postpone_early_data && SSL_in_early_data(tls.ssl) &&
+ SSL_in_init(tls.ssl)) {
+ auto nread = SSL_read(tls.ssl, buf.data(), buf.size());
+ if (nread <= 0) {
+ auto err = SSL_get_error(tls.ssl, nread);
+ switch (err) {
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ return SHRPX_ERR_EOF;
+ case SSL_ERROR_SSL:
+ if (LOG_ENABLED(INFO)) {
+ LOG(INFO) << "SSL_read: "
+ << ERR_error_string(ERR_get_error(), nullptr);
+ }
+ return SHRPX_ERR_NETWORK;
+ default:
+ if (LOG_ENABLED(INFO)) {
+ LOG(INFO) << "SSL_read: SSL_get_error returned " << err;
+ }
+ return SHRPX_ERR_NETWORK;
+ }
+ } else {
+ tls.earlybuf.append(buf.data(), nread);
+ }
+
+ if (SSL_in_init(tls.ssl)) {
+ return SHRPX_ERR_INPROGRESS;
+ }
+ }
+#endif // OPENSSL_IS_BORINGSSL
+
// Handshake was done
rv = check_http2_requirement();
tls.wbuf.drain(nwrite);
}
+#ifdef OPENSSL_IS_BORINGSSL
+ if (!SSL_in_init(tls.ssl)) {
+ // This will send a session ticket.
+ auto nwrite = SSL_write(tls.ssl, "", 0);
+ if (nwrite < 0) {
+ auto err = SSL_get_error(tls.ssl, nwrite);
+ switch (err) {
+ case SSL_ERROR_WANT_READ:
+ if (LOG_ENABLED(INFO)) {
+ LOG(INFO) << "Close connection due to TLS renegotiation";
+ }
+ return SHRPX_ERR_NETWORK;
+ case SSL_ERROR_WANT_WRITE:
+ break;
+ case SSL_ERROR_SSL:
+ if (LOG_ENABLED(INFO)) {
+ LOG(INFO) << "SSL_write: "
+ << ERR_error_string(ERR_get_error(), nullptr);
+ }
+ return SHRPX_ERR_NETWORK;
+ default:
+ if (LOG_ENABLED(INFO)) {
+ LOG(INFO) << "SSL_write: SSL_get_error returned " << err;
+ }
+ return SHRPX_ERR_NETWORK;
+ }
+ }
+ }
+#endif // OPENSSL_IS_BORINGSSL
+
// We have to start read watcher, since later stage of code expects
// this.
rlimit.startw();
return -1;
}
- auto check_black_list = false;
+ auto check_block_list = false;
if (tls.server_handshake) {
- check_black_list = !get_config()->tls.no_http2_cipher_black_list;
+ check_block_list = !get_config()->tls.no_http2_cipher_block_list;
} else {
- check_black_list = !get_config()->tls.client.no_http2_cipher_black_list;
+ check_block_list = !get_config()->tls.client.no_http2_cipher_block_list;
}
- if (check_black_list &&
- nghttp2::tls::check_http2_cipher_black_list(tls.ssl)) {
+ if (check_block_list &&
+ nghttp2::tls::check_http2_cipher_block_list(tls.ssl)) {
if (LOG_ENABLED(INFO)) {
LOG(INFO) << "The negotiated cipher suite is in HTTP/2 cipher suite "
- "black list. HTTP/2 must not be used.";
+ "block list. HTTP/2 must not be used.";
}
return -1;
}
ERR_clear_error();
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
int rv;
if (SSL_is_init_finished(tls.ssl)) {
rv = SSL_write(tls.ssl, data, len);
rv = nwrite;
}
}
-#else // !OPENSSL_1_1_1_API
+#else // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
auto rv = SSL_write(tls.ssl, data, len);
-#endif // !OPENSSL_1_1_1_API
+#endif // !(OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL))
if (rv <= 0) {
auto err = SSL_get_error(tls.ssl, rv);
tls.last_readlen = 0;
}
-#if OPENSSL_1_1_1_API
+#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
if (!tls.early_data_finish) {
// TLSv1.3 handshake is still going on.
size_t nread;
}
return nread;
}
-#endif // OPENSSL_1_1_1_API
+#endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
auto rv = SSL_read(tls.ssl, data, len);