[Zope-Checkins] CVS: ZODB3/ZEO/zrpc - trigger.py:1.15 smac.py:1.39 server.py:1.9 connection.py:1.51 client.py:1.27

Jeremy Hylton jeremy at zope.com
Thu Oct 2 14:17:51 EDT 2003


Update of /cvs-repository/ZODB3/ZEO/zrpc
In directory cvs.zope.org:/tmp/cvs-serv18770/ZEO/zrpc

Modified Files:
	trigger.py smac.py server.py connection.py client.py 
Log Message:
Merge changes from Zope-2_7-branch to the trunk.


=== ZODB3/ZEO/zrpc/trigger.py 1.14 => 1.15 ===
--- ZODB3/ZEO/zrpc/trigger.py:1.14	Fri Jan  3 17:07:41 2003
+++ ZODB3/ZEO/zrpc/trigger.py	Thu Oct  2 14:17:20 2003
@@ -167,6 +167,15 @@
             self.lock = thread.allocate_lock()
             self.thunks = []
             self._trigger_connected = 0
+            self._closed = 0
+
+        def close(self):
+            if not self._closed:
+                self._closed = 1
+                self.del_channel()
+                # self.socket is a, self.trigger is w from __init__
+                self.socket.close()
+                self.trigger.close()
 
         def __repr__(self):
             return '<select-trigger (loopback) at %x>' % id(self)


=== ZODB3/ZEO/zrpc/smac.py 1.38 => 1.39 ===
--- ZODB3/ZEO/zrpc/smac.py:1.38	Fri May 30 15:20:56 2003
+++ ZODB3/ZEO/zrpc/smac.py	Thu Oct  2 14:17:20 2003
@@ -64,7 +64,7 @@
 # that we could pass to send() without blocking.
 SEND_SIZE = 60000
 
-MAC_BIT = 0x80000000
+MAC_BIT = 0x80000000L
 
 class SizedMessageAsyncConnection(asyncore.dispatcher):
     __super_init = asyncore.dispatcher.__init__
@@ -96,12 +96,33 @@
         self.__output_lock = threading.Lock() # Protects __output
         self.__output = []
         self.__closed = 0
-        self.__hmac = None
+        # Each side of the connection sends and receives messages.  A
+        # MAC is generated for each message and depends on each
+        # previous MAC; the state of the MAC generator depends on the
+        # history of operations it has performed.  So the MACs must be
+        # generated in the same order they are verified.
+        
+        # Each side is guaranteed to receive messages in the order
+        # they are sent, but there is no ordering constraint between
+        # message sends and receives.  If the two sides are A and B
+        # and message An indicates the nth message sent by A, then
+        # A1 A2 B1 B2 and A1 B1 B2 A2 are both legitimate total
+        # orderings of the messages.
+
+        # As a result, there must be seperate MAC generators for each
+        # side of the connection.  If not, the generator state would
+        # be different after A1 A2 B1 B2 than it would be after
+        # A1 B1 B2 A2; if the generator state was different, the MAC
+        # could not be verified.
+        self.__hmac_send = None
+        self.__hmac_recv = None
+        
         self.__super_init(sock, map)
 
     def setSessionKey(self, sesskey):
         log("set session key %r" % sesskey)
-        self.__hmac = hmac.HMAC(sesskey, digestmod=sha)
+        self.__hmac_send = hmac.HMAC(sesskey, digestmod=sha)
+        self.__hmac_recv = hmac.HMAC(sesskey, digestmod=sha)
 
     def get_addr(self):
         return self.addr
@@ -150,16 +171,18 @@
                 inp = "".join(inp)
 
             offset = 0
-            expect_mac = 0
+            has_mac = 0
             while (offset + msg_size) <= input_len:
                 msg = inp[offset:offset + msg_size]
                 offset = offset + msg_size
                 if not state:
-                    msg_size = struct.unpack(">i", msg)[0]
-                    expect_mac = msg_size & MAC_BIT
-                    if expect_mac:
+                    msg_size = struct.unpack(">I", msg)[0]
+                    has_mac = msg_size & MAC_BIT
+                    if has_mac:
                         msg_size ^= MAC_BIT
                         msg_size += 20
+                    elif self.__hmac_send:
+                        raise ValueError("Received message without MAC")
                     state = 1
                 else:
                     msg_size = 4
@@ -174,12 +197,12 @@
                     # incoming call to be handled.  During all this
                     # time, the __input_lock is held.  That's a good
                     # thing, because it serializes incoming calls.
-                    if expect_mac:
+                    if has_mac:
                         mac = msg[:20]
                         msg = msg[20:]
-                        if self.__hmac:
-                            self.__hmac.update(msg)
-                            _mac = self.__hmac.digest()
+                        if self.__hmac_recv:
+                            self.__hmac_recv.update(msg)
+                            _mac = self.__hmac_recv.digest()
                             if mac != _mac:
                                 raise ValueError("MAC failed: %r != %r"
                                                  % (_mac, mac))
@@ -245,8 +268,9 @@
     def message_output(self, message):
         if __debug__:
             if self._debug:
-                log('message_output %d bytes: %s' %
-                    (len(message), short_repr(message)),
+                log("message_output %d bytes: %s hmac=%d" %
+                    (len(message), short_repr(message),
+                    self.__hmac_send and 1 or 0),
                     level=zLOG.TRACE)
 
         if self.__closed:
@@ -255,12 +279,12 @@
         self.__output_lock.acquire()
         try:
             # do two separate appends to avoid copying the message string
-            if self.__hmac:
-                self.__output.append(struct.pack(">i", len(message) | MAC_BIT))
-                self.__hmac.update(message)
-                self.__output.append(self.__hmac.digest())
+            if self.__hmac_send:
+                self.__output.append(struct.pack(">I", len(message) | MAC_BIT))
+                self.__hmac_send.update(message)
+                self.__output.append(self.__hmac_send.digest())
             else:
-                self.__output.append(struct.pack(">i", len(message)))
+                self.__output.append(struct.pack(">I", len(message)))
             if len(message) <= SEND_SIZE:
                 self.__output.append(message)
             else:


=== ZODB3/ZEO/zrpc/server.py 1.8 => 1.9 ===
--- ZODB3/ZEO/zrpc/server.py:1.8	Thu Jan  9 16:50:19 2003
+++ ZODB3/ZEO/zrpc/server.py	Thu Oct  2 14:17:20 2003
@@ -31,7 +31,6 @@
         self.__super_init()
         self.addr = addr
         self.factory = factory
-        self.clients = []
         self._open_socket()
 
     def _open_socket(self):
@@ -58,4 +57,3 @@
             return
         c = self.factory(sock, addr)
         log("connect from %s: %s" % (repr(addr), c))
-        self.clients.append(c)


=== ZODB3/ZEO/zrpc/connection.py 1.50 => 1.51 ===
--- ZODB3/ZEO/zrpc/connection.py:1.50	Mon Sep 15 12:29:18 2003
+++ ZODB3/ZEO/zrpc/connection.py	Thu Oct  2 14:17:20 2003
@@ -126,11 +126,15 @@
 
     # Protocol history:
     #
-    # Z200 -- original ZEO 2.0 protocol
+    # Z200 -- Original ZEO 2.0 protocol
     #
-    # Z201 -- added invalidateTransaction() to client;
-    #         renamed several client methods;
-    #         added lastTransaction() to server
+    # Z201 -- Added invalidateTransaction() to client.
+    #         Renamed several client methods.
+    #         Added several sever methods:
+    #             lastTransaction()
+    #             getAuthProtocol() and scheme-specific authentication methods
+    #             getExtensionMethods().
+    #             getInvalidations().
 
     def __init__(self, sock, addr, obj=None):
         self.obj = None


=== ZODB3/ZEO/zrpc/client.py 1.26 => 1.27 ===
--- ZODB3/ZEO/zrpc/client.py:1.26	Mon Sep 15 12:29:18 2003
+++ ZODB3/ZEO/zrpc/client.py	Thu Oct  2 14:17:20 2003
@@ -105,6 +105,7 @@
         if self.trigger is not None:
             self.trigger.close()
             self.trigger = None
+        ThreadedAsync.remove_loop_callback(self.set_async)
 
     def set_async(self, map):
         # This is the callback registered with ThreadedAsync.  The
@@ -406,7 +407,7 @@
             del wrappers[wrap]
 
             # XXX should check deadline
-        
+
 
 class ConnectWrapper:
     """An object that handles the connection procedure for one socket.




More information about the Zope-Checkins mailing list