Index: net/third_party/nss/ssl/sslnonce.c |
=================================================================== |
--- net/third_party/nss/ssl/sslnonce.c (revision 242942) |
+++ net/third_party/nss/ssl/sslnonce.c (working copy) |
@@ -123,18 +123,23 @@ |
SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE); |
SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE); |
} else { |
- if (sid->u.ssl3.sessionTicket.ticket.data) { |
- SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE); |
- } |
- if (sid->u.ssl3.srvName.data) { |
- SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); |
- } |
- if (sid->u.ssl3.signedCertTimestamps.data) { |
- SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE); |
- } |
- if (sid->u.ssl3.originalHandshakeHash.data) { |
- SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE); |
- } |
+ if (sid->u.ssl3.locked.sessionTicket.ticket.data) { |
+ SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket, |
+ PR_FALSE); |
+ } |
+ if (sid->u.ssl3.srvName.data) { |
+ SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); |
+ } |
+ if (sid->u.ssl3.originalHandshakeHash.data) { |
+ SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE); |
+ } |
+ if (sid->u.ssl3.signedCertTimestamps.data) { |
+ SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE); |
+ } |
+ |
+ if (sid->u.ssl3.lock) { |
+ PR_DestroyRWLock(sid->u.ssl3.lock); |
+ } |
} |
if (sid->peerID != NULL) |
@@ -156,7 +161,7 @@ |
if ( sid->localCert ) { |
CERT_DestroyCertificate(sid->localCert); |
} |
- |
+ |
PORT_ZFree(sid, sizeof(sslSessionID)); |
} |
@@ -267,6 +272,9 @@ |
CacheSID(sslSessionID *sid) |
{ |
PRUint32 expirationPeriod; |
+ |
+ PORT_Assert(sid->cached == never_cached); |
+ |
SSL_TRC(8, ("SSL: Cache: sid=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x " |
"time=%x cached=%d", |
sid, sid->cached, sid->addr.pr_s6_addr32[0], |
@@ -274,9 +282,6 @@ |
sid->addr.pr_s6_addr32[3], sid->port, sid->creationTime, |
sid->cached)); |
- if (sid->cached == in_client_cache) |
- return; |
- |
if (!sid->urlSvrName) { |
/* don't cache this SID because it can never be matched */ |
return; |
@@ -293,8 +298,9 @@ |
sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len)); |
} else { |
if (sid->u.ssl3.sessionIDLength == 0 && |
- sid->u.ssl3.sessionTicket.ticket.data == NULL) |
+ sid->u.ssl3.locked.sessionTicket.ticket.data == NULL) |
return; |
+ |
/* Client generates the SessionID if this was a stateless resume. */ |
if (sid->u.ssl3.sessionIDLength == 0) { |
SECStatus rv; |
@@ -307,6 +313,11 @@ |
expirationPeriod = ssl3_sid_timeout; |
PRINT_BUF(8, (0, "sessionID:", |
sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength)); |
+ |
+ sid->u.ssl3.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL); |
+ if (!sid->u.ssl3.lock) { |
+ return; |
+ } |
} |
PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0); |
if (!sid->creationTime) |
@@ -430,41 +441,38 @@ |
return myTime; |
} |
-SECStatus |
-ssl3_SetSIDSessionTicket(sslSessionID *sid, NewSessionTicket *session_ticket) |
+void |
+ssl3_SetSIDSessionTicket(sslSessionID *sid, |
+ /*in/out*/ NewSessionTicket *newSessionTicket) |
{ |
- SECStatus rv; |
+ PORT_Assert(sid); |
+ PORT_Assert(newSessionTicket); |
- /* We need to lock the cache, as this sid might already be in the cache. */ |
- LOCK_CACHE; |
+ /* if sid->u.ssl3.lock, we are updating an existing entry that is already |
+ * cached or was once cached, so we need to acquire and release the write |
+ * lock. Otherwise, this is a new session that isn't shared with anything |
+ * yet, so no locking is needed. |
+ */ |
+ if (sid->u.ssl3.lock) { |
+ PR_RWLock_Wlock(sid->u.ssl3.lock); |
- /* Don't modify sid if it has ever been cached. */ |
- if (sid->cached != never_cached) { |
- UNLOCK_CACHE; |
- return SECSuccess; |
+ /* A server might have sent us an empty ticket, which has the |
+ * effect of clearing the previously known ticket. |
+ */ |
+ if (sid->u.ssl3.locked.sessionTicket.ticket.data) { |
+ SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket, |
+ PR_FALSE); |
+ } |
} |
- /* A server might have sent us an empty ticket, which has the |
- * effect of clearing the previously known ticket. |
- */ |
- if (sid->u.ssl3.sessionTicket.ticket.data) |
- SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE); |
- if (session_ticket->ticket.len > 0) { |
- rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.sessionTicket.ticket, |
- &session_ticket->ticket); |
- if (rv != SECSuccess) { |
- UNLOCK_CACHE; |
- return rv; |
- } |
- } else { |
- sid->u.ssl3.sessionTicket.ticket.data = NULL; |
- sid->u.ssl3.sessionTicket.ticket.len = 0; |
+ PORT_Assert(!sid->u.ssl3.locked.sessionTicket.ticket.data); |
+ |
+ /* Do a shallow copy, moving the ticket data. */ |
+ sid->u.ssl3.locked.sessionTicket = *newSessionTicket; |
+ newSessionTicket->ticket.data = NULL; |
+ newSessionTicket->ticket.len = 0; |
+ |
+ if (sid->u.ssl3.lock) { |
+ PR_RWLock_Unlock(sid->u.ssl3.lock); |
} |
- sid->u.ssl3.sessionTicket.received_timestamp = |
- session_ticket->received_timestamp; |
- sid->u.ssl3.sessionTicket.ticket_lifetime_hint = |
- session_ticket->ticket_lifetime_hint; |
- |
- UNLOCK_CACHE; |
- return SECSuccess; |
} |