1
2
3
4
5
6
7 """Class for caching TLS sessions."""
8
9 import threading
10 import time
11
13 """This class is used by the server to cache TLS sessions.
14
15 Caching sessions allows the client to use TLS session resumption
16 and avoid the expense of a full handshake. To use this class,
17 simply pass a SessionCache instance into the server handshake
18 function.
19
20 This class is thread-safe.
21 """
22
23
24
25
26
27
28 - def __init__(self, maxEntries=10000, maxAge=14400):
29 """Create a new SessionCache.
30
31 @type maxEntries: int
32 @param maxEntries: The maximum size of the cache. When this
33 limit is reached, the oldest sessions will be deleted as
34 necessary to make room for new ones. The default is 10000.
35
36 @type maxAge: int
37 @param maxAge: The number of seconds before a session expires
38 from the cache. The default is 14400 (i.e. 4 hours)."""
39
40 self.lock = threading.Lock()
41
42
43 self.entriesDict = {}
44
45
46 self.entriesList = [(None,None)] * maxEntries
47
48 self.firstIndex = 0
49 self.lastIndex = 0
50 self.maxAge = maxAge
51
53 self.lock.acquire()
54 try:
55 self._purge()
56 session = self.entriesDict[bytes(sessionID)]
57
58
59
60
61
62
63 if session.valid():
64 return session
65 else:
66 raise KeyError()
67 finally:
68 self.lock.release()
69
70
72 self.lock.acquire()
73 try:
74
75 self.entriesDict[bytes(sessionID)] = session
76 self.entriesList[self.lastIndex] = (sessionID, time.time())
77 self.lastIndex = (self.lastIndex+1) % len(self.entriesList)
78
79
80
81 if self.lastIndex == self.firstIndex:
82 del(self.entriesDict[self.entriesList[self.firstIndex][0]])
83 self.firstIndex = (self.firstIndex+1) % len(self.entriesList)
84 finally:
85 self.lock.release()
86
87
89 currentTime = time.time()
90
91
92
93
94
95 index = self.firstIndex
96 while index != self.lastIndex:
97 if currentTime - self.entriesList[index][1] > self.maxAge:
98 del(self.entriesDict[self.entriesList[index][0]])
99 index = (index+1) % len(self.entriesList)
100 else:
101 break
102 self.firstIndex = index
103
107
108 if __name__ == "__main__":
109 _test()
110