[FIX] smac.py's handle_read is naughty, was Re: [ZODB-Dev] Problem with large transactions combined with authentication mode

Christian Robottom Reis kiko at async.com.br
Tue Dec 16 17:47:03 EST 2003


On Sat, Nov 29, 2003 at 02:09:42PM +0100, Per Sigmond wrote:
> Using ZODB3-3.2 (and other 3.2 versions as well) with ZEO I have
> problems with big transactions. It seems the problems only arise when
> I start the server with authentication protocol set (type digest). The
> problems seem to be exposed best on fast machines, and happen on both
> Linux and Windows.

I have a patch that fixes the issue for me. Comments very appreciated,
given that I'm not sure how SMAC.handle_read() is called in real life.

The issue seems to be related to state being set to 1 over runs, which
causes has_mac to never be one for that case, even when we *did* have a
mac header. Now I have no idea *why* state is 1 over runs, but I would
really like to know.

One interesting tidbit: this error shows up both on server *and* client
in certain situations; so that's why I was confused when I read your
logs. I'm a bit less confused now.

--- smac.py	Tue Dec 16 20:39:08 2003
+++ smac.py-2	Tue Dec 16 20:38:26 2003
@@ -92,6 +92,7 @@
         # The next thing read is always of length __msg_size.
         # The state alternates between 0 and 1.
         self.__state = 0
+        self.__has_mac = 0
         self.__msg_size = 4
         self.__output_lock = threading.Lock() # Protects __output
         self.__output = []
@@ -149,6 +150,7 @@
             input_len = self.__input_len + len(d)
             msg_size = self.__msg_size
             state = self.__state
+            has_mac = self.__has_mac
 
             inp = self.__inp
             if msg_size > input_len:
@@ -171,7 +173,6 @@
                 inp = "".join(inp)
 
             offset = 0
-            has_mac = 0
             while (offset + msg_size) <= input_len:
                 msg = inp[offset:offset + msg_size]
                 offset = offset + msg_size
@@ -208,9 +209,12 @@
                                                  % (_mac, mac))
                         else:
                             log("Received MAC but no session key set")
+                    elif self.__hmac_send:
+                        raise ValueError("Received message without MAC")
                     self.message_input(msg)
 
             self.__state = state
+            self.__has_mac = has_mac
             self.__msg_size = msg_size
             self.__inp = inp[offset:]
             self.__input_len = input_len - offset

This is against CVS HEAD but applies nicely to 3.2c1.

Jeremy, try hard not to drop this one, ok? :-)

Take care,
--
Christian Robottom Reis | http://async.com.br/~kiko/ | [+55 16] 261 2331



More information about the ZODB-Dev mailing list