Add an option to disable NPN on a per-SSL basis.

Right whether NPN is advertised can only be configured globally on the SSL_CTX.
Rather than adding two pointers to each SSL*, add an options bit to disable it
so we may plumb in a field trial to disable NPN.

Chromium wants to be able to route a bit in to disable NPN, but it uses SSL_CTX
incorrectly and has a global one, so it can't disconnect the callback. (That
really needs to get fixed. Although it's not clear this necessarily wants to be
lifted up to SSL_CTX as far as Chromium's SSLClientSocket is concerned since
NPN doesn't interact with the session cache.)


Change-Id: I49c86828b963eb341c6ea6a442557b7dfa190ed3
Reviewed-by: Adam Langley <>
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 01813f9..fb1e46f 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -3366,6 +3366,18 @@
 		shouldFail:    true,
 		expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
+	// Test that NPN can be disabled with SSL_OP_DISABLE_NPN.
+	testCases = append(testCases, testCase{
+		name: "DisableNPN",
+		config: Config{
+			NextProtos: []string{"foo"},
+		},
+		flags: []string{
+			"-select-next-proto", "foo",
+			"-disable-npn",
+		},
+		expectNoNextProto: true,
+	})
 	// Resume with a corrupt ticket.
 	testCases = append(testCases, testCase{
 		testType: serverTest,