+#ifndef OPENSSL_NO_NPN
+/* Note that this code assumes that this is only a one element list: */
+static const char NEXT_PROTO_STRING[] = "\x09testproto";
+int npn_client = 0;
+int npn_server = 0;
+int npn_server_reject = 0;
+
+static int cb_client_npn(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
+ {
+ /* This callback only returns the protocol string, rather than a length
+ prefixed set. We assume that NEXT_PROTO_STRING is a one element list and
+ remove the first byte to chop off the length prefix. */
+ *out = (unsigned char*) NEXT_PROTO_STRING + 1;
+ *outlen = sizeof(NEXT_PROTO_STRING) - 2;
+ return SSL_TLSEXT_ERR_OK;
+ }
+
+static int cb_server_npn(SSL *s, const unsigned char **data, unsigned int *len, void *arg)
+ {
+ *data = (const unsigned char *) NEXT_PROTO_STRING;
+ *len = sizeof(NEXT_PROTO_STRING) - 1;
+ return SSL_TLSEXT_ERR_OK;
+ }
+
+static int cb_server_rejects_npn(SSL *s, const unsigned char **data, unsigned int *len, void *arg)
+ {
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+
+static int verify_npn(SSL *client, SSL *server)
+ {
+ const unsigned char *client_s;
+ unsigned client_len;
+ const unsigned char *server_s;
+ unsigned server_len;
+
+ SSL_get0_next_proto_negotiated(client, &client_s, &client_len);
+ SSL_get0_next_proto_negotiated(server, &server_s, &server_len);
+
+ if (client_len)
+ {
+ BIO_printf(bio_stdout, "Client NPN: ");
+ BIO_write(bio_stdout, client_s, client_len);
+ BIO_printf(bio_stdout, "\n");
+ }
+
+ if (server_len)
+ {
+ BIO_printf(bio_stdout, "Server NPN: ");
+ BIO_write(bio_stdout, server_s, server_len);
+ BIO_printf(bio_stdout, "\n");
+ }
+
+ /* If an NPN string was returned, it must be the protocol that we
+ * expected to negotiate. */
+ if (client_len && (client_len != sizeof(NEXT_PROTO_STRING) - 2 ||
+ memcmp(client_s, NEXT_PROTO_STRING + 1, client_len)))
+ return -1;
+ if (server_len && (server_len != sizeof(NEXT_PROTO_STRING) - 2 ||
+ memcmp(server_s, NEXT_PROTO_STRING + 1, server_len)))
+ return -1;
+
+ if (!npn_client && client_len)
+ return -1;
+ if (!npn_server && server_len)
+ return -1;
+ if (npn_server_reject && server_len)
+ return -1;
+ if (npn_client && npn_server && (!client_len || !server_len))
+ return -1;
+
+ return 0;
+ }
+#endif
+