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 |