bug in the proxy module ...

Wesley Craig wes at umich.edu
Wed Jun 11 15:46:49 EDT 2008


On 10 Jun 2008, at 10:07, Ken Murchison wrote:
> Any suggestions?  I'm off thinking about other things at the moment.

The comment associated with the change is:

	make sure we send all available data, not just one buffer full.
	this solves a pipelining problem where a response to a command run  
on a proxy
	could be output in the middle of a response to a command run on a  
backend

Both versions call prot_select() once.  The old code The new code  
(attempts) to copy input to output until end of input, but since it's  
only called prot_select() once, that's a problem.  There are a couple  
of possibilities, perhaps you're more familiar with prot and it's  
byzantine usage, but here's my analysis:

	1) Instead of looping on the size of the read, we loop until  
prot_read() returns == 0 or < 0.  This assumes that pin isn't set to  
allow blocking.  I don't like this solution, since I'm not terribly  
interested in an exhaustive analysis of every possible pin that  
proxy_check_input() might get.  Maybe you know something I don't, tho.

	2) Introduce prot_select() into the read/write loop.  This will  
allow you to know that there's still input available really without  
blocking.  Of course, if it's a very large block of data, you might  
not see the next block, return control to the calling function, and  
get the same pipelining problem mentioned in the CVS log above.   
Assuming you're not worried about that scenario, it's a good solution  
because it introduces the idea that output from the backend server is  
handled prior to input from the client.

	3) Continuing on the precedence idea above, split the loop handling  
so that backend output is always handled first.  Also, always return  
control to the caller if you ever have backend output.  This way,  
you'll only ever take input from the client if the backend isn't  
sending anything.  I doubt this solves the race mentioned in (2),  
either tho.

	4) Restructure the routines calling proxy_check_input to know the  
structure of the commands being sent and the corresponding  
responses.  This is the surest way to fix the above problem, i.e.,  
don't let the proxy server respond to a command until the response to  
the command sent by the backend is done.  Of course, tho is a huge  
pain, probably involving a ton of additional code.

:wes


More information about the Cyrus-devel mailing list