Package tlslite :: Module sessioncache
[hide private]
[frames] | no frames]

Source Code for Module tlslite.sessioncache

  1  # Authors:  
  2  #   Trevor Perrin 
  3  #   Martin von Loewis - python 3 port 
  4  #   Mirko Dziadzka - bugfix 
  5  # 
  6  # See the LICENSE file for legal information regarding use of this file. 
  7   
  8  """Class for caching TLS sessions.""" 
  9   
 10  import threading 
 11  import time 
 12   
13 -class SessionCache(object):
14 """This class is used by the server to cache TLS sessions. 15 16 Caching sessions allows the client to use TLS session resumption 17 and avoid the expense of a full handshake. To use this class, 18 simply pass a SessionCache instance into the server handshake 19 function. 20 21 This class is thread-safe. 22 """ 23 24 #References to these instances 25 #are also held by the caller, who may change the 'resumable' 26 #flag, so the SessionCache must return the same instances 27 #it was passed in. 28
29 - def __init__(self, maxEntries=10000, maxAge=14400):
30 """Create a new SessionCache. 31 32 @type maxEntries: int 33 @param maxEntries: The maximum size of the cache. When this 34 limit is reached, the oldest sessions will be deleted as 35 necessary to make room for new ones. The default is 10000. 36 37 @type maxAge: int 38 @param maxAge: The number of seconds before a session expires 39 from the cache. The default is 14400 (i.e. 4 hours).""" 40 41 self.lock = threading.Lock() 42 43 # Maps sessionIDs to sessions 44 self.entriesDict = {} 45 46 #Circular list of (sessionID, timestamp) pairs 47 self.entriesList = [(None,None)] * maxEntries 48 49 self.firstIndex = 0 50 self.lastIndex = 0 51 self.maxAge = maxAge
52
53 - def __getitem__(self, sessionID):
54 self.lock.acquire() 55 try: 56 self._purge() #Delete old items, so we're assured of a new one 57 session = self.entriesDict[bytes(sessionID)] 58 59 #When we add sessions they're resumable, but it's possible 60 #for the session to be invalidated later on (if a fatal alert 61 #is returned), so we have to check for resumability before 62 #returning the session. 63 64 if session.valid(): 65 return session 66 else: 67 raise KeyError() 68 finally: 69 self.lock.release()
70 71
72 - def __setitem__(self, sessionID, session):
73 self.lock.acquire() 74 try: 75 #Add the new element 76 self.entriesDict[bytes(sessionID)] = session 77 self.entriesList[self.lastIndex] = (bytes(sessionID), time.time()) 78 self.lastIndex = (self.lastIndex+1) % len(self.entriesList) 79 80 #If the cache is full, we delete the oldest element to make an 81 #empty space 82 if self.lastIndex == self.firstIndex: 83 del(self.entriesDict[self.entriesList[self.firstIndex][0]]) 84 self.firstIndex = (self.firstIndex+1) % len(self.entriesList) 85 finally: 86 self.lock.release()
87 88 #Delete expired items
89 - def _purge(self):
90 currentTime = time.time() 91 92 #Search through the circular list, deleting expired elements until 93 #we reach a non-expired element. Since elements in list are 94 #ordered in time, we can break once we reach the first non-expired 95 #element 96 index = self.firstIndex 97 while index != self.lastIndex: 98 if currentTime - self.entriesList[index][1] > self.maxAge: 99 del(self.entriesDict[self.entriesList[index][0]]) 100 index = (index+1) % len(self.entriesList) 101 else: 102 break 103 self.firstIndex = index
104