This is a proposal to solve the possible dead lock in proxy. The problem was : if the length of the last packet received by the proxy from one back process is 4096 bytes, the proxy expects to receive data and the back process waits for commands.
I propose you a shortcut : if the proxy receives 4096 bytes the proxy puts back the last byte into the buffer and it sends the first 4095 bytes through the outputstream (the last byte will be read at the next loop). if the proxy receives less than 4096 bytes it works like previously. The initial code could be modified from : <quote> if (pout) { const char *err; char buf[4096]; int c; do { c = prot_read(pin, buf, sizeof(buf)); if (c == 0 || c < 0) break; prot_write(pout, buf, c); } while (c == sizeof(buf)); if ((err = prot_error(pin)) != NULL) { </quote> into <quote> if (pout) { const char *err; char buf[4096]; int c; do { c = prot_read(pin, buf, sizeof(buf)); if (c == 0 || c < 0) break; if (c == sizeof(buf)) { prot_ungetc(buf[sizeof(buf) - 1], pin); prot_write(pout, buf, c - 1); } else { prot_write(pout, buf, c); } } while (c == sizeof(buf)); if ((err = prot_error(pin)) != NULL) { </quote> -----Message d'origine----- De : [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] De la part de Wesley Craig Envoyé : mercredi 11 juin 2008 21:47 À : Ken Murchison Cc : cyrus-devel@lists.andrew.cmu.edu Objet : Re: bug in the proxy module ... 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 Ce message et les pièces jointes sont confidentiels et réservés à l'usage exclusif de ses destinataires. Il peut également être protégé par le secret professionnel. Si vous recevez ce message par erreur, merci d'en avertir immédiatement l'expéditeur et de le détruire. L'intégrité du message ne pouvant être assurée sur Internet, la responsabilité du groupe Atos Origin ne pourra être recherchée quant au contenu de ce message. Bien que les meilleurs efforts soient faits pour maintenir cette transmission exempte de tout virus, l'expéditeur ne donne aucune garantie à cet égard et sa responsabilité ne saurait être recherchée pour tout dommage résultant d'un virus transmis. This e-mail and the documents attached are confidential and intended solely for the addressee; it may also be privileged. If you receive this e-mail in error, please notify the sender immediately and destroy it. As its integrity cannot be secured on the Internet, the Atos Origin group liability cannot be triggered for the message content. Although the sender endeavours to maintain a computer virus-free network, the sender does not warrant that this transmission is virus-free and will not be liable for any damages resulting from any virus transmitted.