diff options
author | bnc <bnc@chromium.org> | 2015-10-21 16:24:22 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-21 23:25:02 +0000 |
commit | 1f295377e8de70ba03ce73d9f7929e614d23df68 (patch) | |
tree | f2c91aa3bc4f18ea27fe5da3331ceb2525ea575d /net | |
parent | 7a55b51459fbcba769f8248cfcff739fb474b4f5 (diff) | |
download | chromium_src-1f295377e8de70ba03ce73d9f7929e614d23df68.zip chromium_src-1f295377e8de70ba03ce73d9f7929e614d23df68.tar.gz chromium_src-1f295377e8de70ba03ce73d9f7929e614d23df68.tar.bz2 |
Disable HTTP/2 over NPN (with OpenSSL).
* Split SSLConfig.next_proto into two members: one for ALPN, one for NPN.
* Remove HTTP/2 from NPN.
* In OpenSSL, use alpn_protos for |ALPN|, and npn_protos for |NPN|.
* In NSS, use |alpn_protos| for both.
* In NSS, disable NPN if |npn_protos| is empty.
BUG=527066
Review URL: https://codereview.chromium.org/1387363004
Cr-Commit-Position: refs/heads/master@{#355427}
Diffstat (limited to 'net')
-rw-r--r-- | net/http/http_network_session.cc | 15 | ||||
-rw-r--r-- | net/http/http_network_session.h | 7 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 3 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 3 | ||||
-rw-r--r-- | net/http/http_server_properties.cc | 6 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_job.cc | 3 | ||||
-rw-r--r-- | net/log/net_log_util.cc | 22 | ||||
-rw-r--r-- | net/socket/socket_test_util.cc | 4 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 21 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_openssl.cc | 14 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_unittest.cc | 71 | ||||
-rw-r--r-- | net/spdy/spdy_network_transaction_unittest.cc | 3 | ||||
-rw-r--r-- | net/ssl/ssl_config.h | 21 |
13 files changed, 138 insertions, 55 deletions
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 61bce84..c7770c3 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -319,11 +319,20 @@ bool HttpNetworkSession::IsProtocolEnabled(AlternateProtocol protocol) const { protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION]; } -void HttpNetworkSession::GetNextProtos(NextProtoVector* next_protos) const { +void HttpNetworkSession::GetAlpnProtos(NextProtoVector* alpn_protos) const { if (HttpStreamFactory::spdy_enabled()) { - *next_protos = next_protos_; + *alpn_protos = next_protos_; } else { - next_protos->clear(); + alpn_protos->clear(); + } +} + +void HttpNetworkSession::GetNpnProtos(NextProtoVector* npn_protos) const { + if (HttpStreamFactory::spdy_enabled()) { + *npn_protos = next_protos_; + DisableHTTP2(npn_protos); + } else { + npn_protos->clear(); } } diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index 5353c47..c11afc3 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h @@ -243,8 +243,11 @@ class NET_EXPORT HttpNetworkSession bool IsProtocolEnabled(AlternateProtocol protocol) const; - // Populates |*next_protos| with protocols. - void GetNextProtos(NextProtoVector* next_protos) const; + // Populates |*alpn_protos| with protocols to be used with ALPN. + void GetAlpnProtos(NextProtoVector* alpn_protos) const; + + // Populates |*npn_protos| with protocols to be used with NPN. + void GetNpnProtos(NextProtoVector* npn_protos) const; // Convenience function for searching through |params_| for // |forced_spdy_exclusions|. diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index a665595..e0c4100 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -154,7 +154,8 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, establishing_tunnel_(false), websocket_handshake_stream_base_create_helper_(NULL) { session->ssl_config_service()->GetSSLConfig(&server_ssl_config_); - session->GetNextProtos(&server_ssl_config_.next_protos); + session->GetAlpnProtos(&server_ssl_config_.alpn_protos); + session->GetNpnProtos(&server_ssl_config_.npn_protos); proxy_ssl_config_ = server_ssl_config_; } diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index c9014a4..56f3bb3 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -1466,7 +1466,8 @@ void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest( // Preconnect a socket. SSLConfig ssl_config; session->ssl_config_service()->GetSSLConfig(&ssl_config); - session->GetNextProtos(&ssl_config.next_protos); + session->GetAlpnProtos(&ssl_config.alpn_protos); + session->GetNpnProtos(&ssl_config.npn_protos); session->http_stream_factory()->PreconnectStreams(1, request, ssl_config, ssl_config); // Wait for the preconnect to complete. diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc index 1e3ccd2..408ced8 100644 --- a/net/http/http_server_properties.cc +++ b/net/http/http_server_properties.cc @@ -109,8 +109,10 @@ std::string AlternativeServiceInfo::ToString() const { // static void HttpServerProperties::ForceHTTP11(SSLConfig* ssl_config) { - ssl_config->next_protos.clear(); - ssl_config->next_protos.push_back(kProtoHTTP11); + ssl_config->alpn_protos.clear(); + ssl_config->alpn_protos.push_back(kProtoHTTP11); + ssl_config->npn_protos.clear(); + ssl_config->npn_protos.push_back(kProtoHTTP11); } } // namespace net diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index 33476a0..eabbed0 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc @@ -947,7 +947,8 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { if (stream_factory_->for_websockets_) { // TODO(ricea): Re-enable NPN when WebSockets over SPDY is supported. SSLConfig websocket_server_ssl_config = server_ssl_config_; - websocket_server_ssl_config.next_protos.clear(); + websocket_server_ssl_config.alpn_protos.clear(); + websocket_server_ssl_config.npn_protos.clear(); return InitSocketHandleForWebSocketRequest( GetSocketGroup(), server_, request_info_.extra_headers, request_info_.load_flags, priority_, session_, proxy_info_, expect_spdy, diff --git a/net/log/net_log_util.cc b/net/log/net_log_util.cc index 46282f7..43805a8 100644 --- a/net/log/net_log_util.cc +++ b/net/log/net_log_util.cc @@ -420,16 +420,28 @@ NET_EXPORT scoped_ptr<base::DictionaryValue> GetNetInfo( "use_alternative_services", http_network_session->params().use_alternative_services); - NextProtoVector next_protos; - http_network_session->GetNextProtos(&next_protos); - if (!next_protos.empty()) { + NextProtoVector alpn_protos; + http_network_session->GetAlpnProtos(&alpn_protos); + if (!alpn_protos.empty()) { std::string next_protos_string; - for (const NextProto proto : next_protos) { + for (NextProto proto : alpn_protos) { if (!next_protos_string.empty()) next_protos_string.append(","); next_protos_string.append(SSLClientSocket::NextProtoToString(proto)); } - status_dict->SetString("next_protos", next_protos_string); + status_dict->SetString("alpn_protos", next_protos_string); + } + + NextProtoVector npn_protos; + http_network_session->GetNpnProtos(&npn_protos); + if (!npn_protos.empty()) { + std::string next_protos_string; + for (NextProto proto : npn_protos) { + if (!next_protos_string.empty()) + next_protos_string.append(","); + next_protos_string.append(SSLClientSocket::NextProtoToString(proto)); + } + status_dict->SetString("npn_protos", next_protos_string); } net_info_dict->Set(NetInfoSourceToString(NET_INFO_SPDY_STATUS), diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index 36bbeca..ddb4c6d 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc @@ -802,11 +802,11 @@ scoped_ptr<SSLClientSocket> MockClientSocketFactory::CreateSSLClientSocket( SSLSocketDataProvider* next_ssl_data = mock_ssl_data_.GetNext(); if (!next_ssl_data->next_protos_expected_in_ssl_config.empty()) { EXPECT_EQ(next_ssl_data->next_protos_expected_in_ssl_config.size(), - ssl_config.next_protos.size()); + ssl_config.alpn_protos.size()); EXPECT_TRUE( std::equal(next_ssl_data->next_protos_expected_in_ssl_config.begin(), next_ssl_data->next_protos_expected_in_ssl_config.end(), - ssl_config.next_protos.begin())); + ssl_config.alpn_protos.begin())); } return scoped_ptr<SSLClientSocket>(new MockSSLClientSocket( transport_socket.Pass(), host_and_port, ssl_config, next_ssl_data)); diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index 540d65b..514c43b 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -841,15 +841,18 @@ bool SSLClientSocketNSS::Core::Init(PRFileDesc* socket, SECStatus rv = SECSuccess; - if (!ssl_config_.next_protos.empty()) { - NextProtoVector next_protos = ssl_config_.next_protos; + if (!ssl_config_.alpn_protos.empty()) { + NextProtoVector alpn_protos = ssl_config_.alpn_protos; // TODO(bnc): Check ssl_config_.disabled_cipher_suites. if (!IsTLSVersionAdequateForHTTP2(ssl_config_)) - DisableHTTP2(&next_protos); + DisableHTTP2(&alpn_protos); // |ssl_config_| has fallback protocol at the end of the list, but NSS // expects fallback at the first place, thus protocols need to be reordered. - ReorderNextProtos(&next_protos); - std::vector<uint8_t> wire_protos = SerializeNextProtos(next_protos); + ReorderNextProtos(&alpn_protos); + // NSS only supports a single protocol vector to be used with ALPN and NPN. + // Because of this limitation, |alpn_prototos| will be used for both. + // However, it is possible to enable ALPN and NPN separately. + std::vector<uint8_t> wire_protos = SerializeNextProtos(alpn_protos); rv = SSL_SetNextProtoNego( nss_fd_, wire_protos.empty() ? NULL : &wire_protos[0], wire_protos.size()); @@ -858,9 +861,11 @@ bool SSLClientSocketNSS::Core::Init(PRFileDesc* socket, rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_ALPN, PR_TRUE); if (rv != SECSuccess) LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_ALPN"); - rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_NPN, PR_TRUE); - if (rv != SECSuccess) - LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_NPN"); + if (!ssl_config_.npn_protos.empty()) { + rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_NPN, PR_TRUE); + if (rv != SECSuccess) + LogFailedNSSFunction(*weak_net_log_, "SSL_OptionSet", "SSL_ENABLE_NPN"); + } } rv = SSL_AuthCertificateHook( diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc index 4dee74a..812871d 100644 --- a/net/socket/ssl_client_socket_openssl.cc +++ b/net/socket/ssl_client_socket_openssl.cc @@ -928,7 +928,7 @@ int SSLClientSocketOpenSSL::Init() { SSL_enable_tls_channel_id(ssl_); } - if (!ssl_config_.next_protos.empty()) { + if (!ssl_config_.alpn_protos.empty()) { // Get list of ciphers that are enabled. STACK_OF(SSL_CIPHER)* enabled_ciphers = SSL_get_ciphers(ssl_); DCHECK(enabled_ciphers); @@ -939,12 +939,12 @@ int SSLClientSocketOpenSSL::Init() { enabled_ciphers_vector.push_back(id); } - NextProtoVector next_protos = ssl_config_.next_protos; + NextProtoVector alpn_protos = ssl_config_.alpn_protos; if (!HasCipherAdequateForHTTP2(enabled_ciphers_vector) || !IsTLSVersionAdequateForHTTP2(ssl_config_)) { - DisableHTTP2(&next_protos); + DisableHTTP2(&alpn_protos); } - std::vector<uint8_t> wire_protos = SerializeNextProtos(next_protos); + std::vector<uint8_t> wire_protos = SerializeNextProtos(alpn_protos); SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0], wire_protos.size()); } @@ -1893,7 +1893,7 @@ int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out, unsigned char* outlen, const unsigned char* in, unsigned int inlen) { - if (ssl_config_.next_protos.empty()) { + if (ssl_config_.npn_protos.empty()) { *out = reinterpret_cast<uint8*>( const_cast<char*>(kDefaultSupportedNPNProtocol)); *outlen = arraysize(kDefaultSupportedNPNProtocol) - 1; @@ -1906,7 +1906,7 @@ int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out, // For each protocol in server preference order, see if we support it. for (unsigned int i = 0; i < inlen; i += in[i] + 1) { - for (NextProto next_proto : ssl_config_.next_protos) { + for (NextProto next_proto : ssl_config_.npn_protos) { const std::string proto = NextProtoToString(next_proto); if (in[i] == proto.size() && memcmp(&in[i + 1], proto.data(), in[i]) == 0) { @@ -1924,7 +1924,7 @@ int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out, // If we didn't find a protocol, we select the last one from our list. if (npn_status_ == kNextProtoNoOverlap) { // NextProtoToString returns a pointer to a static string. - const char* proto = NextProtoToString(ssl_config_.next_protos.back()); + const char* proto = NextProtoToString(ssl_config_.npn_protos.back()); *out = reinterpret_cast<unsigned char*>(const_cast<char*>(proto)); *outlen = strlen(proto); } diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index a1a4655..9f0525a 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc @@ -2584,6 +2584,10 @@ TEST_F(SSLClientSocketTest, RequireECDHE) { EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv); } +// In tests requiring NPN, client_config.alpn_protos and +// client_config.npn_protos both need to be set when using NSS, otherwise NPN is +// disabled due to quirks of the implementation. + TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) { // False Start requires NPN/ALPN, ECDHE, and an AEAD. SpawnedTestServer::SSLOptions server_options; @@ -2593,7 +2597,10 @@ TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) { SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM; server_options.npn_protocols.push_back(std::string("http/1.1")); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP11); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP11); +#endif + client_config.npn_protos.push_back(kProtoHTTP11); ASSERT_NO_FATAL_FAILURE( TestFalseStart(server_options, client_config, true)); } @@ -2606,7 +2613,8 @@ TEST_F(SSLClientSocketFalseStartTest, NoNPN) { server_options.bulk_ciphers = SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM; SSLConfig client_config; - client_config.next_protos.clear(); + client_config.alpn_protos.clear(); + client_config.npn_protos.clear(); ASSERT_NO_FATAL_FAILURE( TestFalseStart(server_options, client_config, false)); } @@ -2620,7 +2628,10 @@ TEST_F(SSLClientSocketFalseStartTest, RSA) { SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM; server_options.npn_protocols.push_back(std::string("http/1.1")); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP11); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP11); +#endif + client_config.npn_protos.push_back(kProtoHTTP11); ASSERT_NO_FATAL_FAILURE( TestFalseStart(server_options, client_config, false)); } @@ -2634,7 +2645,10 @@ TEST_F(SSLClientSocketFalseStartTest, DHE_RSA) { SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM; server_options.npn_protocols.push_back(std::string("http/1.1")); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP11); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP11); +#endif + client_config.npn_protos.push_back(kProtoHTTP11); ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_options, client_config, false)); } @@ -2647,7 +2661,10 @@ TEST_F(SSLClientSocketFalseStartTest, NoAEAD) { SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128; server_options.npn_protocols.push_back(std::string("http/1.1")); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP11); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP11); +#endif + client_config.npn_protos.push_back(kProtoHTTP11); ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_options, client_config, false)); } @@ -2661,7 +2678,10 @@ TEST_F(SSLClientSocketFalseStartTest, SessionResumption) { SpawnedTestServer::SSLOptions::BULK_CIPHER_AES128GCM; server_options.npn_protocols.push_back(std::string("http/1.1")); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP11); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP11); +#endif + client_config.npn_protos.push_back(kProtoHTTP11); // Let a full handshake complete with False Start. ASSERT_NO_FATAL_FAILURE( @@ -2691,7 +2711,10 @@ TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBeforeFinished) { ASSERT_TRUE(StartTestServer(server_options)); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP11); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP11); +#endif + client_config.npn_protos.push_back(kProtoHTTP11); // Start a handshake up to the server Finished message. TestCompletionCallback callback; @@ -2745,7 +2768,10 @@ TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBadFinished) { ASSERT_TRUE(StartTestServer(server_options)); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP11); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP11); +#endif + client_config.npn_protos.push_back(kProtoHTTP11); // Start a handshake up to the server Finished message. TestCompletionCallback callback; @@ -2891,8 +2917,12 @@ TEST_F(SSLClientSocketTest, NPN) { ASSERT_TRUE(StartTestServer(server_options)); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP2); - client_config.next_protos.push_back(kProtoHTTP11); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP2); + client_config.alpn_protos.push_back(kProtoHTTP11); +#endif + client_config.npn_protos.push_back(kProtoHTTP2); + client_config.npn_protos.push_back(kProtoHTTP11); int rv; ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv)); @@ -2911,8 +2941,12 @@ TEST_F(SSLClientSocketTest, NPNNoOverlap) { ASSERT_TRUE(StartTestServer(server_options)); SSLConfig client_config; - client_config.next_protos.push_back(kProtoSPDY31); - client_config.next_protos.push_back(kProtoHTTP2); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoSPDY31); + client_config.alpn_protos.push_back(kProtoHTTP2); +#endif + client_config.npn_protos.push_back(kProtoSPDY31); + client_config.npn_protos.push_back(kProtoHTTP2); int rv; ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv)); @@ -2932,8 +2966,12 @@ TEST_F(SSLClientSocketTest, NPNServerPreference) { ASSERT_TRUE(StartTestServer(server_options)); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP2); - client_config.next_protos.push_back(kProtoSPDY31); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP2); + client_config.alpn_protos.push_back(kProtoSPDY31); +#endif + client_config.npn_protos.push_back(kProtoHTTP2); + client_config.npn_protos.push_back(kProtoSPDY31); int rv; ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv)); @@ -2965,7 +3003,10 @@ TEST_F(SSLClientSocketTest, NPNServerDisabled) { ASSERT_TRUE(StartTestServer(server_options)); SSLConfig client_config; - client_config.next_protos.push_back(kProtoHTTP11); +#if !defined(USE_OPENSSL) + client_config.alpn_protos.push_back(kProtoHTTP11); +#endif + client_config.npn_protos.push_back(kProtoHTTP11); int rv; ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv)); diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index f54a89e..bb63d96 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -1076,7 +1076,8 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config); HttpStreamFactory* http_stream_factory = helper.session()->http_stream_factory(); - helper.session()->GetNextProtos(&preconnect_ssl_config.next_protos); + helper.session()->GetAlpnProtos(&preconnect_ssl_config.alpn_protos); + helper.session()->GetNpnProtos(&preconnect_ssl_config.npn_protos); http_stream_factory->PreconnectStreams(1, httpreq, preconnect_ssl_config, preconnect_ssl_config); diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h index 9a73f41..cd83ea5 100644 --- a/net/ssl/ssl_config.h +++ b/net/ssl/ssl_config.h @@ -154,13 +154,20 @@ struct NET_EXPORT SSLConfig { // NOTE: Only used by NSS. bool cert_io_enabled; - // The list of supported application level protocols supported in decreasing - // order of preference. For ALPN (Application Layer Protocol Negotation), - // protocols will be advertised in this order. For NPN (Next Protocol - // Negotiation), the last item on the list is selected if there is no overlap - // between |next_protos| and the protocols supported by the server, otherwise - // server preference is observed and the order of |next_protos| is irrelevant. - NextProtoVector next_protos; + // The list of application level protocols supported with ALPN (Application + // Layer Protocol Negotation), in decreasing order of preference. Protocols + // will be advertised in this order during TLS handshake. + NextProtoVector alpn_protos; + + // The list of application level protocols supported with NPN (Next Protocol + // Negotiation). The last item on the list is selected if there is no overlap + // between |npn_protos| and the protocols supported by the server, otherwise + // server preference is observed and the order of |npn_protos| is irrelevant. + // Note that due to NSS limitations, ports which use NSS will use + // |alpn_protos| for both ALPN and NPN. However, if |npn_protos| is empty, NPN + // will still be disabled. + // TODO(bnc): Deprecate NPN, see https://crbug.com/526713. + NextProtoVector npn_protos; // True if renegotiation should be allowed for the default application-level // protocol when the peer negotiates neither ALPN nor NPN. |