| Index: net/third_party/nss/patches/nextproto.patch | 
| diff --git a/net/third_party/nss/patches/nextproto.patch b/net/third_party/nss/patches/nextproto.patch | 
| index a01f2404b15b992ae578bcd462e360ef5de5797a..46021b425f3cbed78b4aef4119069982274b9206 100644 | 
| --- a/net/third_party/nss/patches/nextproto.patch | 
| +++ b/net/third_party/nss/patches/nextproto.patch | 
| @@ -1,68 +1,89 @@ | 
| -From 6b594dc531e7a1d1d5bca2f0f78e7bc0ac3ff937 Mon Sep 17 00:00:00 2001 | 
| +From 3caa0f573d2637bfed99dcc0e5887fe3a52462ba Mon Sep 17 00:00:00 2001 | 
| From: Adam Langley <agl@chromium.org> | 
| Date: Mon, 3 Oct 2011 12:19:28 -0400 | 
| -Subject: [PATCH] nextproto.patch | 
| +Subject: [PATCH 01/15] nextproto.patch | 
|  | 
| --- | 
| - mozilla/security/nss/cmd/tstclnt/tstclnt.c |    6 ++ | 
| - mozilla/security/nss/lib/ssl/ssl.def       |    7 ++ | 
| - mozilla/security/nss/lib/ssl/ssl.h         |   12 +++ | 
| - mozilla/security/nss/lib/ssl/ssl3con.c     |   54 ++++++++++++ | 
| - mozilla/security/nss/lib/ssl/ssl3ext.c     |  122 +++++++++++++++++++++++++++- | 
| - mozilla/security/nss/lib/ssl/ssl3prot.h    |    3 +- | 
| - mozilla/security/nss/lib/ssl/sslimpl.h     |   24 ++++++ | 
| - mozilla/security/nss/lib/ssl/sslsock.c     |   74 +++++++++++++++++ | 
| - mozilla/security/nss/lib/ssl/sslt.h        |    3 +- | 
| - 9 files changed, 302 insertions(+), 3 deletions(-) | 
| + mozilla/security/nss/lib/ssl/ssl.def    |    6 ++ | 
| + mozilla/security/nss/lib/ssl/ssl.h      |   51 ++++++++++++ | 
| + mozilla/security/nss/lib/ssl/ssl3con.c  |   54 +++++++++++++ | 
| + mozilla/security/nss/lib/ssl/ssl3ext.c  |  104 ++++++++++++++++++++++++- | 
| + mozilla/security/nss/lib/ssl/ssl3prot.h |    3 +- | 
| + mozilla/security/nss/lib/ssl/sslerr.h   |    2 + | 
| + mozilla/security/nss/lib/ssl/sslimpl.h  |   21 +++++ | 
| + mozilla/security/nss/lib/ssl/sslsock.c  |  131 +++++++++++++++++++++++++++++++ | 
| + mozilla/security/nss/lib/ssl/sslt.h     |    3 +- | 
| + 9 files changed, 372 insertions(+), 3 deletions(-) | 
|  | 
| -diff --git a/mozilla/security/nss/cmd/tstclnt/tstclnt.c b/mozilla/security/nss/cmd/tstclnt/tstclnt.c | 
| -index 55684e6..d209a33 100644 | 
| ---- a/mozilla/security/nss/cmd/tstclnt/tstclnt.c | 
| -+++ b/mozilla/security/nss/cmd/tstclnt/tstclnt.c | 
| -@@ -868,6 +868,12 @@ int main(int argc, char **argv) | 
| - 	return 1; | 
| -     } | 
| - | 
| -+    rv = SSL_SetNextProtoNego(s, "\004flip\004http1.1", 10); | 
| -+    if (rv != SECSuccess) { | 
| -+	SECU_PrintError(progName, "error enabling next protocol negotiation"); | 
| -+	return 1; | 
| -+    } | 
| -+ | 
| -     /* enable false start. */ | 
| -     rv = SSL_OptionSet(s, SSL_ENABLE_FALSE_START, enableFalseStart); | 
| -     if (rv != SECSuccess) { | 
| diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def | 
| -index d3f455c..a1f4b51 100644 | 
| +index d3f455c..5256ae2 100644 | 
| --- a/mozilla/security/nss/lib/ssl/ssl.def | 
| +++ b/mozilla/security/nss/lib/ssl/ssl.def | 
| -@@ -152,3 +152,10 @@ SSL_SNISocketConfigHook; | 
| +@@ -152,3 +152,9 @@ SSL_SNISocketConfigHook; | 
| ;+    local: | 
| ;+*; | 
| ;+}; | 
| +;+NSS_CHROMIUM { | 
| +;+    global: | 
| -+SSL_GetNextProto; | 
| -+SSL_SetNextProtoNego; | 
| ++SSL_SetNextProtoCallback; | 
| +;+    local: | 
| +;+*; | 
| +;+}; | 
| diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h | 
| -index 4a9e89d..ffa973c 100644 | 
| +index 4a9e89d..2cf777d 100644 | 
| --- a/mozilla/security/nss/lib/ssl/ssl.h | 
| +++ b/mozilla/security/nss/lib/ssl/ssl.h | 
| -@@ -153,6 +153,18 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, PRBool on); | 
| +@@ -153,6 +153,57 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, PRBool on); | 
| SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on); | 
| SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle); | 
|  | 
| ++/* SSLNextProtoCallback is called, during the handshake, when the server has | 
| ++ * sent a Next Protocol Negotiation extension. |protos| and |protosLen| define | 
| ++ * a buffer which contains the server's advertisement. This data is guaranteed | 
| ++ * to be well formed per the NPN spec. |protoOut| is a buffer provided by the | 
| ++ * caller, of length 255 (the maximum allowed by the protocol). | 
| ++ * On successful return, the protocol to be announced to the server will be in | 
| ++ * |protoOut| and its length in |protoOutLen|. */ | 
| ++typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)( | 
| ++    void *arg, | 
| ++    PRFileDesc *fd, | 
| ++    const unsigned char* protos, | 
| ++    unsigned int protosLen, | 
| ++    unsigned char* protoOut, | 
| ++    unsigned int* protoOutLen); | 
| ++ | 
| ++/* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol | 
| ++ * Negotiation. It causes a client to advertise NPN. */ | 
| ++SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd, | 
| ++                                              SSLNextProtoCallback callback, | 
| ++                                              void *arg); | 
| ++ | 
| ++/* SSL_SetNextProtoNego can be used as an alternative to | 
| ++ * SSL_SetNextProtoCallback. It also causes a client to advertise NPN and | 
| ++ * installs a default callback function which selects the first supported | 
| ++ * protocol in server-preference order. If no matching protocol is found it | 
| ++ * selects the first supported protocol. | 
| ++ * | 
| ++ * The supported protocols are specified in |data| in wire-format (8-bit | 
| ++ * length-prefixed). For example: "\010http/1.1\006spdy/2". */ | 
| +SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd, | 
| +					  const unsigned char *data, | 
| -+					  unsigned short length); | 
| ++					  unsigned int length); | 
| ++/* SSL_GetNextProto can be used after a handshake on a socket where | 
| ++ * SSL_SetNextProtoNego was called to retrieve the result of the Next Protocol | 
| ++ * negotiation. | 
| ++ * | 
| ++ * state is set to one of the SSL_NEXT_PROTO_* constants. The negotiated | 
| ++ * protocol, if any, is written into buf, which must be at least buf_len bytes | 
| ++ * long. If the negotiated protocol is longer than this, it is truncated.  The | 
| ++ * number of bytes copied is written into *length. */ | 
| +SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd, | 
| +				      int *state, | 
| +				      unsigned char *buf, | 
| -+				      unsigned *length, | 
| -+				      unsigned buf_len); | 
| ++				      unsigned int *length, | 
| ++				      unsigned int buf_len); | 
| ++ | 
| ++// TODO(wtc): it may be a good idea to define these as an enum type. | 
| +#define SSL_NEXT_PROTO_NO_SUPPORT	0 /* No peer support                */ | 
| +#define SSL_NEXT_PROTO_NEGOTIATED	1 /* Mutual agreement               */ | 
| +#define SSL_NEXT_PROTO_NO_OVERLAP	2 /* No protocol overlap found      */ | 
| @@ -71,7 +92,7 @@ index 4a9e89d..ffa973c 100644 | 
| ** Control ciphers that SSL uses. If on is non-zero then the named cipher | 
| ** is enabled, otherwise it is disabled. | 
| diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c | 
| -index 8048913..e0cb4e9 100644 | 
| +index 8048913..8f860a9 100644 | 
| --- a/mozilla/security/nss/lib/ssl/ssl3con.c | 
| +++ b/mozilla/security/nss/lib/ssl/ssl3con.c | 
| @@ -81,6 +81,7 @@ static SECStatus ssl3_InitState(             sslSocket *ss); | 
| @@ -107,7 +128,7 @@ index 8048913..e0cb4e9 100644 | 
| +    int padding_len; | 
| +    static const unsigned char padding[32] = {0}; | 
| + | 
| -+    if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NO_SUPPORT) | 
| ++    if (ss->ssl3.nextProto.len == 0) | 
| +	return SECSuccess; | 
| + | 
| +    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 
| @@ -164,7 +185,7 @@ index 8048913..e0cb4e9 100644 | 
|  | 
| /* End of ssl3con.c */ | 
| diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c | 
| -index becbfe9..fbd5a91 100644 | 
| +index becbfe9..36ac4de 100644 | 
| --- a/mozilla/security/nss/lib/ssl/ssl3ext.c | 
| +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c | 
| @@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = { | 
| @@ -193,7 +214,7 @@ index becbfe9..fbd5a91 100644 | 
| /* any extra entries will appear as { 0, NULL }    */ | 
| }; | 
|  | 
| -@@ -534,6 +537,123 @@ ssl3_SendSessionTicketXtn( | 
| +@@ -534,6 +537,105 @@ ssl3_SendSessionTicketXtn( | 
| return -1; | 
| } | 
|  | 
| @@ -206,12 +227,11 @@ index becbfe9..fbd5a91 100644 | 
| +	return SECFailure; | 
| +    } | 
| + | 
| -+    ss->ssl3.hs.nextProtoNego = PR_TRUE; | 
| +    return SECSuccess; | 
| +} | 
| + | 
| +/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none | 
| -+ * of the length may be 0 and the sum of the lengths must equal the length of | 
| ++ * of the lengths may be 0 and the sum of the lengths must equal the length of | 
| + * the block. */ | 
| +SECStatus | 
| +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) | 
| @@ -220,63 +240,46 @@ index becbfe9..fbd5a91 100644 | 
| + | 
| +    while (offset < length) { | 
| +	if (data[offset] == 0) { | 
| ++	    PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); | 
| +	    return SECFailure; | 
| +	} | 
| +	offset += (unsigned int)data[offset] + 1; | 
| +    } | 
| + | 
| -+    if (offset > length) | 
| ++    if (offset > length) { | 
| ++	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); | 
| +	return SECFailure; | 
| ++    } | 
| + | 
| +    return SECSuccess; | 
| +} | 
| + | 
| +SECStatus | 
| +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, | 
| -+                                 SECItem *data) | 
| ++                                  SECItem *data) | 
| +{ | 
| -+    unsigned int i, j; | 
| +    SECStatus rv; | 
| -+    unsigned char *result; | 
| -+ | 
| -+    if (data->len == 0) { | 
| -+	/* The server supports the extension, but doesn't have any | 
| -+	 * protocols configured. In this case we request our favoured | 
| -+	 * protocol. */ | 
| -+	goto pick_first; | 
| -+    } | 
| ++    unsigned char result[255]; | 
| ++    unsigned int result_len; | 
| + | 
| +    rv = ssl3_ValidateNextProtoNego(data->data, data->len); | 
| +    if (rv != SECSuccess) | 
| +	return rv; | 
| + | 
| -+    /* For each protocol in server preference order, see if we support it. */ | 
| -+    for (i = 0; i < data->len; ) { | 
| -+	for (j = 0; j < ss->opt.nextProtoNego.len; ) { | 
| -+	    if (data->data[i] == ss->opt.nextProtoNego.data[j] && | 
| -+		memcmp(&data->data[i+1], &ss->opt.nextProtoNego.data[j+1], | 
| -+		       data->data[i]) == 0) { | 
| -+		/* We found a match */ | 
| -+		ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; | 
| -+		result = &data->data[i]; | 
| -+		goto found; | 
| -+	    } | 
| -+	    j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1; | 
| -+	} | 
| -+ | 
| -+	i += (unsigned int)data->data[i] + 1; | 
| -+    } | 
| -+ | 
| -+  pick_first: | 
| -+    ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP; | 
| -+    result = ss->opt.nextProtoNego.data; | 
| ++    rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, | 
| ++                               data->data, data->len, | 
| ++                               result, &result_len); | 
| ++    if (rv != SECSuccess) | 
| ++	return rv; | 
| ++    // If the callback wrote more than allowed to |result| it has corrupted our | 
| ++    // stack. | 
| ++    PORT_Assert(result_len <= sizeof(result)); | 
| + | 
| -+  found: | 
| +    if (ss->ssl3.nextProto.data) | 
| +	PORT_Free(ss->ssl3.nextProto.data); | 
| -+    ss->ssl3.nextProto.data = PORT_Alloc(result[0]); | 
| -+    PORT_Memcpy(ss->ssl3.nextProto.data, result + 1, result[0]); | 
| -+    ss->ssl3.nextProto.len = result[0]; | 
| ++    ss->ssl3.nextProto.data = PORT_Alloc(result_len); | 
| ++    PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len); | 
| ++    ss->ssl3.nextProto.len = result_len; | 
| +    return SECSuccess; | 
| +} | 
| + | 
| @@ -288,7 +291,7 @@ index becbfe9..fbd5a91 100644 | 
| +    PRInt32 extension_length; | 
| + | 
| +    /* Renegotiations do not send this extension. */ | 
| -+    if (ss->opt.nextProtoNego.len == 0 || ss->firstHsDone) { | 
| ++    if (!ss->nextProtoCallback || ss->firstHsDone) { | 
| +	return 0; | 
| +    } | 
| + | 
| @@ -331,48 +334,58 @@ index 4702fcc..f3c950e 100644 | 
| } SSL3HandshakeType; | 
|  | 
| typedef struct { | 
| +diff --git a/mozilla/security/nss/lib/ssl/sslerr.h b/mozilla/security/nss/lib/ssl/sslerr.h | 
| +index a2f6524..c76ffa9 100644 | 
| +--- a/mozilla/security/nss/lib/ssl/sslerr.h | 
| ++++ b/mozilla/security/nss/lib/ssl/sslerr.h | 
| +@@ -203,6 +203,8 @@ SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD	= (SSL_ERROR_BASE + 114), | 
| + | 
| + SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY  = (SSL_ERROR_BASE + 115), | 
| + | 
| ++SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID	= (SSL_ERROR_BASE + 117), | 
| ++ | 
| + SSL_ERROR_END_OF_LIST	/* let the c compiler determine the value of this. */ | 
| + } SSLErrorCodes; | 
| + #endif /* NO_SECURITY_ERROR_ENUM */ | 
| diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h | 
| -index 9af471d..d1c1181 100644 | 
| +index 9af471d..199c573 100644 | 
| --- a/mozilla/security/nss/lib/ssl/sslimpl.h | 
| +++ b/mozilla/security/nss/lib/ssl/sslimpl.h | 
| -@@ -313,6 +313,11 @@ typedef struct { | 
| +@@ -313,6 +313,10 @@ typedef struct { | 
| #endif /* NSS_ENABLE_ECC */ | 
|  | 
| typedef struct sslOptionsStr { | 
| -+    /* For clients, this is a validated list of protocols in preference order | 
| -+     * and wire format. For servers, this is the list of support protocols, | 
| -+     * also in wire format. */ | 
| ++    /* If SSL_SetNextProtoNego has been called, then this contains the | 
| ++     * list of supported protocols. */ | 
| +    SECItem      nextProtoNego; | 
| + | 
| unsigned int useSecurity		: 1;  /*  1 */ | 
| unsigned int useSocks		: 1;  /*  2 */ | 
| unsigned int requestCertificate	: 1;  /*  3 */ | 
| -@@ -786,6 +791,7 @@ const ssl3CipherSuiteDef *suite_def; | 
| - #ifdef NSS_ENABLE_ECC | 
| -     PRUint32              negotiatedECCurves; /* bit mask */ | 
| - #endif /* NSS_ENABLE_ECC */ | 
| -+    PRBool                nextProtoNego;/* Our peer has sent this extension */ | 
| - } SSL3HandshakeState; | 
| - | 
| - | 
| -@@ -827,6 +833,16 @@ struct ssl3StateStr { | 
| +@@ -827,6 +831,13 @@ struct ssl3StateStr { | 
| PRBool               initialized; | 
| SSL3HandshakeState   hs; | 
| ssl3CipherSpec       specs[2];	/* one is current, one is pending. */ | 
| + | 
| +    /* In a client: if the server supports Next Protocol Negotiation, then | 
| -+     * this is the protocol that was requested. | 
| -+     * In a server: this is the protocol that the client requested via Next | 
| -+     * Protocol Negotiation. | 
| ++     * this is the protocol that was negotiated. | 
| +     * | 
| -+     * In either case, if the data pointer is non-NULL, then it is malloced | 
| -+     * data.  */ | 
| ++     * If the data pointer is non-NULL, then it is malloced data.  */ | 
| +    SECItem		nextProto; | 
| -+    int			nextProtoState;	/* See SSL_NEXT_PROTO_* defines */ | 
| ++    int			nextProtoState; /* See NEXT_PROTO_* defines */ | 
| }; | 
|  | 
| typedef struct { | 
| -@@ -1494,8 +1510,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslSocket * ss, | 
| +@@ -1058,6 +1069,8 @@ const unsigned char *  preferredCipher; | 
| +     SSLHandshakeCallback      handshakeCallback; | 
| +     void                     *handshakeCallbackData; | 
| +     void                     *pkcs11PinArg; | 
| ++    SSLNextProtoCallback      nextProtoCallback; | 
| ++    void                     *nextProtoArg; | 
| + | 
| +     PRIntervalTime            rTimeout; /* timeout for NSPR I/O */ | 
| +     PRIntervalTime            wTimeout; /* timeout for NSPR I/O */ | 
| +@@ -1494,8 +1507,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslSocket * ss, | 
| PRUint16 ex_type, SECItem *data); | 
| extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, | 
| PRUint16 ex_type, SECItem *data); | 
| @@ -385,7 +398,7 @@ index 9af471d..d1c1181 100644 | 
|  | 
| /* ClientHello and ServerHello extension senders. | 
| * Note that not all extension senders are exposed here; only those that | 
| -@@ -1526,6 +1546,10 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss, | 
| +@@ -1526,6 +1543,10 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss, | 
| extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss, | 
| PRBool append, PRUint32 maxBytes); | 
| #endif | 
| @@ -397,7 +410,7 @@ index 9af471d..d1c1181 100644 | 
| /* call the registered extension handlers. */ | 
| extern SECStatus ssl3_HandleHelloExtensions(sslSocket *ss, | 
| diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c | 
| -index bc770a1..4c8fbfd 100644 | 
| +index bc770a1..769ea0a 100644 | 
| --- a/mozilla/security/nss/lib/ssl/sslsock.c | 
| +++ b/mozilla/security/nss/lib/ssl/sslsock.c | 
| @@ -163,6 +163,7 @@ static const sslSocketOps ssl_secure_ops = {	/* SSL. */ | 
| @@ -419,16 +432,14 @@ index bc770a1..4c8fbfd 100644 | 
| PORT_Assert(!ss->xtnData.sniNameArr); | 
| if (ss->xtnData.sniNameArr) { | 
| PORT_Free(ss->xtnData.sniNameArr); | 
| -@@ -1266,6 +1271,75 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd) | 
| +@@ -1266,6 +1271,132 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd) | 
| return fd; | 
| } | 
|  | 
| -+/* SSL_SetNextProtoNego sets the list of supported protocols for the given | 
| -+ * socket. The list is a series of 8-bit, length prefixed strings. */ | 
| +SECStatus | 
| -+SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data, | 
| -+		     unsigned short length) | 
| -+{ | 
| ++SSL_SetNextProtoCallback(PRFileDesc *fd, | 
| ++                         SSLNextProtoCallback callback, | 
| ++                         void *arg) { | 
| +    sslSocket *ss = ssl_FindSocket(fd); | 
| + | 
| +    if (!ss) { | 
| @@ -437,6 +448,74 @@ index bc770a1..4c8fbfd 100644 | 
| +	return SECFailure; | 
| +    } | 
| + | 
| ++    ssl_GetSSL3HandshakeLock(ss); | 
| ++    ss->nextProtoCallback = callback; | 
| ++    ss->nextProtoArg = arg; | 
| ++    ssl_ReleaseSSL3HandshakeLock(ss); | 
| ++} | 
| ++ | 
| ++/* NextProtoStandardCallback is set as an NPN callback for the case when the | 
| ++ * user of the sockets wants the standard selection algorithm. */ | 
| ++static SECStatus | 
| ++NextProtoStandardCallback(void *arg, | 
| ++			  PRFileDesc *fd, | 
| ++			  const unsigned char *protos, | 
| ++			  unsigned int protos_len, | 
| ++			  unsigned char *protoOut, | 
| ++			  unsigned int *protoOutLen) | 
| ++{ | 
| ++    unsigned int i, j; | 
| ++    const unsigned char *result; | 
| ++ | 
| ++    sslSocket *ss = ssl_FindSocket(fd); | 
| ++    PORT_Assert(ss); | 
| ++ | 
| ++    if (protos_len == 0) { | 
| ++	/* The server supports the extension, but doesn't have any protocols | 
| ++	 * configured. In this case we request our favoured protocol. */ | 
| ++	goto pick_first; | 
| ++    } | 
| ++ | 
| ++    /* For each protocol in server preference, see if we support it. */ | 
| ++    for (i = 0; i < protos_len; ) { | 
| ++	for (j = 0; j < ss->opt.nextProtoNego.len; ) { | 
| ++	    if (protos[i] == ss->opt.nextProtoNego.data[j] && | 
| ++		memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1], | 
| ++		       protos[i]) == 0) { | 
| ++		/* We found a match. */ | 
| ++		ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; | 
| ++		result = &protos[i]; | 
| ++		goto found; | 
| ++	    } | 
| ++	    j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1; | 
| ++	} | 
| ++	i += (unsigned int)protos[i] + 1; | 
| ++    } | 
| ++ | 
| ++pick_first: | 
| ++    ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP; | 
| ++    result = ss->opt.nextProtoNego.data; | 
| ++ | 
| ++found: | 
| ++    memcpy(protoOut, result + 1, result[0]); | 
| ++    *protoOutLen = result[0]; | 
| ++    return SECSuccess; | 
| ++} | 
| ++ | 
| ++SECStatus | 
| ++SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data, | 
| ++		     unsigned int length) | 
| ++{ | 
| ++    SECStatus rv; | 
| ++ | 
| ++    sslSocket *ss = ssl_FindSocket(fd); | 
| ++ | 
| ++    if (!ss) { | 
| ++	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", | 
| ++		 SSL_GETPID(), fd)); | 
| ++	return SECFailure; | 
| ++    } | 
| ++ | 
| +    if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess) | 
| +	return SECFailure; | 
| + | 
| @@ -453,18 +532,9 @@ index bc770a1..4c8fbfd 100644 | 
| +    ss->opt.nextProtoNego.type = siBuffer; | 
| +    ssl_ReleaseSSL3HandshakeLock(ss); | 
| + | 
| -+    return SECSuccess; | 
| ++    return SSL_SetNextProtoCallback(fd, NextProtoStandardCallback, NULL); | 
| +} | 
| + | 
| -+/* SSL_GetNextProto reads the resulting Next Protocol Negotiation result for | 
| -+ * the given socket. It's only valid to call this once the handshake has | 
| -+ * completed. | 
| -+ * | 
| -+ * state is set to one of the SSL_NEXT_PROTO_* constants. The negotiated | 
| -+ * protocol, if any, is written into buf, which must be at least buf_len | 
| -+ * bytes long. If the negotiated protocol is longer than this, it is truncated. | 
| -+ * The number of bytes copied is written into length. | 
| -+ */ | 
| +SECStatus | 
| +SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf, | 
| +		 unsigned int *length, unsigned int buf_len) | 
|  |