| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file implements the CLIENT Session ID cache. | 2 * This file implements the CLIENT Session ID cache. |
| 3 * | 3 * |
| 4 * ***** BEGIN LICENSE BLOCK ***** | 4 * ***** BEGIN LICENSE BLOCK ***** |
| 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 6 * | 6 * |
| 7 * The contents of this file are subject to the Mozilla Public License Version | 7 * The contents of this file are subject to the Mozilla Public License Version |
| 8 * 1.1 (the "License"); you may not use this file except in compliance with | 8 * 1.1 (the "License"); you may not use this file except in compliance with |
| 9 * the License. You may obtain a copy of the License at | 9 * the License. You may obtain a copy of the License at |
| 10 * http://www.mozilla.org/MPL/ | 10 * http://www.mozilla.org/MPL/ |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 static PZLock * cacheLock = NULL; | 58 static PZLock * cacheLock = NULL; |
| 59 | 59 |
| 60 /* sids can be in one of 4 states: | 60 /* sids can be in one of 4 states: |
| 61 * | 61 * |
| 62 * never_cached, created, but not yet put into cache. | 62 * never_cached, created, but not yet put into cache. |
| 63 * in_client_cache, in the client cache's linked list. | 63 * in_client_cache, in the client cache's linked list. |
| 64 * in_server_cache, entry came from the server's cache file. | 64 * in_server_cache, entry came from the server's cache file. |
| 65 * invalid_cache has been removed from the cache. | 65 * invalid_cache has been removed from the cache. |
| 66 */ | 66 */ |
| 67 | 67 |
| 68 #define LOCK_CACHE » lock_cache() | 68 #define LOCK_CACHE » PZ_Lock(cacheLock) |
| 69 #define UNLOCK_CACHE PZ_Unlock(cacheLock) | 69 #define UNLOCK_CACHE PZ_Unlock(cacheLock) |
| 70 | 70 |
| 71 static SECStatus | 71 static SECStatus |
| 72 ssl_InitClientSessionCacheLock(void) | 72 ssl_InitClientSessionCacheLock(void) |
| 73 { | 73 { |
| 74 cacheLock = PZ_NewLock(nssILockCache); | 74 cacheLock = PZ_NewLock(nssILockCache); |
| 75 return cacheLock ? SECSuccess : SECFailure; | 75 return cacheLock ? SECSuccess : SECFailure; |
| 76 } | 76 } |
| 77 | 77 |
| 78 static SECStatus | 78 static SECStatus |
| 79 ssl_FreeClientSessionCacheLock(void) | 79 ssl_FreeClientSessionCacheLock(void) |
| 80 { | 80 { |
| 81 if (cacheLock) { | 81 if (cacheLock) { |
| 82 PZ_DestroyLock(cacheLock); | 82 PZ_DestroyLock(cacheLock); |
| 83 cacheLock = NULL; | 83 cacheLock = NULL; |
| 84 return SECSuccess; | 84 return SECSuccess; |
| 85 } | 85 } |
| 86 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | 86 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); |
| 87 return SECFailure; | 87 return SECFailure; |
| 88 } | 88 } |
| 89 | 89 |
| 90 static PRBool LocksInitializedEarly = PR_FALSE; | |
| 91 | |
| 92 static SECStatus | 90 static SECStatus |
| 93 FreeSessionCacheLocks() | 91 FreeSessionCacheLocks() |
| 94 { | 92 { |
| 95 SECStatus rv1, rv2; | 93 SECStatus rv1, rv2; |
| 96 rv1 = ssl_FreeSymWrapKeysLock(); | 94 rv1 = ssl_FreeSymWrapKeysLock(); |
| 97 rv2 = ssl_FreeClientSessionCacheLock(); | 95 rv2 = ssl_FreeClientSessionCacheLock(); |
| 98 if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { | 96 if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { |
| 99 return SECSuccess; | 97 return SECSuccess; |
| 100 } | 98 } |
| 101 return SECFailure; | 99 return SECFailure; |
| 102 } | 100 } |
| 103 | 101 |
| 104 static SECStatus | 102 static SECStatus |
| 105 InitSessionCacheLocks(void) | 103 InitSessionCacheLocks(void) |
| 106 { | 104 { |
| 107 SECStatus rv1, rv2; | 105 SECStatus rv1, rv2; |
| 108 PRErrorCode rc; | 106 PRErrorCode rc; |
| 109 rv1 = ssl_InitSymWrapKeysLock(); | 107 rv1 = ssl_InitSymWrapKeysLock(); |
| 110 rv2 = ssl_InitClientSessionCacheLock(); | 108 rv2 = ssl_InitClientSessionCacheLock(); |
| 111 if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { | 109 if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) { |
| 112 return SECSuccess; | 110 return SECSuccess; |
| 113 } | 111 } |
| 114 rc = PORT_GetError(); | 112 rc = PORT_GetError(); |
| 115 FreeSessionCacheLocks(); | 113 FreeSessionCacheLocks(); |
| 116 PORT_SetError(rc); | 114 PORT_SetError(rc); |
| 117 return SECFailure; | 115 return SECFailure; |
| 118 } | 116 } |
| 119 | 117 |
| 120 /* free the session cache locks if they were initialized early */ | |
| 121 SECStatus | |
| 122 ssl_FreeSessionCacheLocks() | |
| 123 { | |
| 124 PORT_Assert(PR_TRUE == LocksInitializedEarly); | |
| 125 if (!LocksInitializedEarly) { | |
| 126 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | |
| 127 return SECFailure; | |
| 128 } | |
| 129 FreeSessionCacheLocks(); | |
| 130 LocksInitializedEarly = PR_FALSE; | |
| 131 return SECSuccess; | |
| 132 } | |
| 133 | |
| 134 static PRCallOnceType lockOnce; | 118 static PRCallOnceType lockOnce; |
| 135 | 119 |
| 136 /* free the session cache locks if they were initialized lazily */ | 120 /* free the session cache locks if they were initialized lazily */ |
| 137 static SECStatus ssl_ShutdownLocks(void* appData, void* nssData) | 121 static SECStatus ssl_ShutdownLocks(void* appData, void* nssData) |
| 138 { | 122 { |
| 139 PORT_Assert(PR_FALSE == LocksInitializedEarly); | |
| 140 if (LocksInitializedEarly) { | |
| 141 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | |
| 142 return SECFailure; | |
| 143 } | |
| 144 FreeSessionCacheLocks(); | 123 FreeSessionCacheLocks(); |
| 145 memset(&lockOnce, 0, sizeof(lockOnce)); | 124 memset(&lockOnce, 0, sizeof(lockOnce)); |
| 146 return SECSuccess; | 125 return SECSuccess; |
| 147 } | 126 } |
| 148 | 127 |
| 149 static PRStatus initSessionCacheLocksLazily(void) | 128 static PRStatus initSessionCacheLocksLazily(void) |
| 150 { | 129 { |
| 151 SECStatus rv = InitSessionCacheLocks(); | 130 SECStatus rv = InitSessionCacheLocks(); |
| 152 if (SECSuccess != rv) { | 131 if (SECSuccess != rv) { |
| 153 return PR_FAILURE; | 132 return PR_FAILURE; |
| 154 } | 133 } |
| 155 rv = NSS_RegisterShutdown(ssl_ShutdownLocks, NULL); | 134 rv = NSS_RegisterShutdown(ssl_ShutdownLocks, NULL); |
| 156 PORT_Assert(SECSuccess == rv); | 135 PORT_Assert(SECSuccess == rv); |
| 157 if (SECSuccess != rv) { | 136 if (SECSuccess != rv) { |
| 158 return PR_FAILURE; | 137 return PR_FAILURE; |
| 159 } | 138 } |
| 160 return PR_SUCCESS; | 139 return PR_SUCCESS; |
| 161 } | 140 } |
| 162 | 141 |
| 163 /* lazyInit means that the call is not happening during a 1-time | 142 /* the call is happening during dynamic, lazy initialization */ |
| 164 * initialization function, but rather during dynamic, lazy initialization | |
| 165 */ | |
| 166 SECStatus | 143 SECStatus |
| 167 ssl_InitSessionCacheLocks(PRBool lazyInit) | 144 ssl_InitSessionCacheLocks() |
| 168 { | 145 { |
| 169 if (LocksInitializedEarly) { | 146 return (PR_SUCCESS == |
| 170 return SECSuccess; | 147 PR_CallOnce(&lockOnce, initSessionCacheLocksLazily)) ? |
| 171 } | 148 SECSuccess : SECFailure; |
| 172 | |
| 173 if (lazyInit) { | |
| 174 return (PR_SUCCESS == | |
| 175 PR_CallOnce(&lockOnce, initSessionCacheLocksLazily)) ? | |
| 176 SECSuccess : SECFailure; | |
| 177 } | |
| 178 | |
| 179 if (SECSuccess == InitSessionCacheLocks()) { | |
| 180 LocksInitializedEarly = PR_TRUE; | |
| 181 return SECSuccess; | |
| 182 } | |
| 183 | |
| 184 return SECFailure; | |
| 185 } | |
| 186 | |
| 187 static void | |
| 188 lock_cache(void) | |
| 189 { | |
| 190 ssl_InitSessionCacheLocks(PR_TRUE); | |
| 191 PZ_Lock(cacheLock); | |
| 192 } | 149 } |
| 193 | 150 |
| 194 /* BEWARE: This function gets called for both client and server SIDs !! | 151 /* BEWARE: This function gets called for both client and server SIDs !! |
| 195 * If the unreferenced sid is not in the cache, Free sid and its contents. | 152 * If the unreferenced sid is not in the cache, Free sid and its contents. |
| 196 */ | 153 */ |
| 197 static void | 154 static void |
| 198 ssl_DestroySID(sslSessionID *sid) | 155 ssl_DestroySID(sslSessionID *sid) |
| 199 { | 156 { |
| 200 int i; | 157 int i; |
| 201 SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached)); | 158 SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached)); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 } else { | 427 } else { |
| 471 sec->cache = CacheSID; | 428 sec->cache = CacheSID; |
| 472 sec->uncache = LockAndUncacheSID; | 429 sec->uncache = LockAndUncacheSID; |
| 473 } | 430 } |
| 474 } | 431 } |
| 475 | 432 |
| 476 /* wipe out the entire client session cache. */ | 433 /* wipe out the entire client session cache. */ |
| 477 void | 434 void |
| 478 SSL_ClearSessionCache(void) | 435 SSL_ClearSessionCache(void) |
| 479 { | 436 { |
| 437 if (!cacheLock) |
| 438 return; /* lock was never initialized */ |
| 480 LOCK_CACHE; | 439 LOCK_CACHE; |
| 481 while(cache != NULL) | 440 while(cache != NULL) |
| 482 UncacheSID(cache); | 441 UncacheSID(cache); |
| 483 UNLOCK_CACHE; | 442 UNLOCK_CACHE; |
| 484 } | 443 } |
| 485 | 444 |
| 486 /* returns an unsigned int containing the number of seconds in PR_Now() */ | 445 /* returns an unsigned int containing the number of seconds in PR_Now() */ |
| 487 PRUint32 | 446 PRUint32 |
| 488 ssl_Time(void) | 447 ssl_Time(void) |
| 489 { | 448 { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 sid->u.ssl3.sessionTicket.ticket.len = 0; | 487 sid->u.ssl3.sessionTicket.ticket.len = 0; |
| 529 } | 488 } |
| 530 sid->u.ssl3.sessionTicket.received_timestamp = | 489 sid->u.ssl3.sessionTicket.received_timestamp = |
| 531 session_ticket->received_timestamp; | 490 session_ticket->received_timestamp; |
| 532 sid->u.ssl3.sessionTicket.ticket_lifetime_hint = | 491 sid->u.ssl3.sessionTicket.ticket_lifetime_hint = |
| 533 session_ticket->ticket_lifetime_hint; | 492 session_ticket->ticket_lifetime_hint; |
| 534 | 493 |
| 535 UNLOCK_CACHE; | 494 UNLOCK_CACHE; |
| 536 return SECSuccess; | 495 return SECSuccess; |
| 537 } | 496 } |
| OLD | NEW |