Re: Trouble with httpGate and FreeBSD 9.1 [So
Hi Alex, I've just tested app/main.l + httpGate with fresh development release, it works fine. My patches to httpGate and ssl: # diff -u httpGate.c.orig httpGate.c --- httpGate.c.orig 2012-03-20 12:46:41.0 +0600 +++ httpGate.c 2013-01-27 22:16:09.0 +0600 @@ -2,6 +2,7 @@ * (c) Software Lab. Alexander Burger */ +#include sys/socket.h #include stdio.h #include stdlib.h #include unistd.h @@ -15,6 +16,7 @@ #include sys/stat.h #include netdb.h #include arpa/inet.h +#include netinet/in.h #include openssl/pem.h #include openssl/ssl.h # diff -u ssl.c.orig ssl.c --- ssl.c.orig 2011-10-22 20:29:48.0 +0600 +++ ssl.c 2013-01-27 22:13:04.0 +0600 @@ -2,6 +2,7 @@ * (c) Software Lab. Alexander Burger */ +#include sys/socket.h #include stdio.h #include stdlib.h #include unistd.h Best regards, Mansur Hi all, finally, after hours of tracing and debugging, Mansur and I could locate the problem! We found that the socket was unexpectedly in non-blocking mode, causing the read operation to return nonsense data. It resulted from the fact that new sockets returned from accept() in BSD inherit the flags from the parent socket. From the man page: On Linux, the new socket returned by accept() does not inherit file status flags such as O_NONBLOCK and O_ASYNC from the listening socket. This behavior differs from the canonical BSD sockets implementation. Portable programs should not rely on inheritance or noninheritance of file status flags and always explicitly set all required flags on the socket returned from accept(). Because PicoLisp temporarily sets the socket to non-blocking before calling accept(), this was inherited to the new socket on FreeBSD (but not on Linux). Released a new version (3.1.1.10) to the repo, and -- as ever -- to http://software-lab.de/picoLisp.tgz ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe --
Re: Trouble with httpGate and FreeBSD 9.1 [So
Hi Mansur, I've just tested app/main.l + httpGate with fresh development release, it works fine. Again, many thanks for the help! My patches to httpGate and ssl: ... +#include sys/socket.h ... +#include netinet/in.h OK. As these are just additional include files, I've also added them to the release (same as before in src/net.c, according to your suggestion). They work like that also in Linux. ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Trouble with httpGate and FreeBSD 9.1
Hi Mansur, But your description seems to refer to the _sending_ side of httpGate. Right. Still, if the _receiving_ side of httpGate doesn't get complete data, the sending side will also fail. This was the issue with the fix from March. As I understand it, 'line' should not be concerned about TCP packets. These are on a lower level. PicoLisp reads from a socket, and should receive either correct data or EOF, but never partial data. It is a principle of TCP to handle this. I can not agree with this. TCP guarantees only : - data arrives in-order - data has minimal error (i.e. correctness) - duplicate data is discarded - lost/discarded packets are resent Yes. At the moment of calling (line) it's highly possible that there is no whole line in receive TCP buffer, Yes, but then 'line' will get some characters and wait. It will not return until it sees EOL or EOF. If this were not the case, the whole PicoLisp server would never work. There are always glitches and delays in a connection. and then application will get only arrived part of the request line and eof. No. EOF will only arrive when the connection is closed. And in our case, the connection is not closed, just some TCP packets on the lower layers were smaller. See also tcpdump listing in some of my prevous letters, which shows that pil server gets GET / piece, responds with 400 Bad request and after that arrives the large rest of the request. So taking into account the principles of TCP stream that's perfectly legal situation. No. This looks very much to me like the situation before March. The receiving side of httpGate didn't handle partial lines correctly, and then httpGate sent only a partial line to PicoLisp. I cannot imagine how this could happen now. Are you really, really very sure that it is not an old binary which is running, though httpGate.c is new? If so, perhaps you could send me part of the output of 'strace' of httpGate, so see exactly what was read and what was sent, and if and when the connection was closed by whom. ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Trouble with httpGate and FreeBSD 9.1
Hi Mansur, Below is link to httpGate trace (it seems there is no strace in FreeBSD, so I used truss): http://pastebin.com/gs3t7aDL or should I include trace log directly into the message? No, that's fine. I've downloaded it. Thanks! Looking at the output 4.13311: read(4,GET / HTTP/1.1\r\nHost: mtmlab.homedns.org\r\nUser-Agent: we see that 'httpGate' correctly fully reads the first line. So it is not the receiving side (as I suspected), and thus has nothing to do with the fix last March. Also, your observations were right in that only a parial line is sent: 10.13311: write(3,GET /,5)= 5 (0x5) 11.13311: write(3, HTTP/1.1\r\n,11) = 11 (0xb) But this is correct, it is explicitly programmed in lines 243 ff. of httpGate.c wrBytes(srv, buf, p - buf); // This writes GET / ... wrBytes(srv, q, p - q); // and this writes the rest of the line To my understanding 'httpGate' behaves correctly. It should be all right to send a single line in two chunks. So we are back at the beginning. Why does 'line' return before it received a complete line? I do not agree with you that it might be a problem on the TCP-level due to transmitting the line in two packets. 'line' only terminates when it receives either end-of-line or end-of-file. Could it be that some signal is involved, or something unexpected happens on the receiving (picolisp) side? Any ideas anybody? ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Trouble with httpGate and FreeBSD 9.1
Hi Mansur, thanks for the bug report! First of all, I'd like to ask you which version of 'httpGate' you are using. Is it the latest one, with the source date 20mar12 (i.e. picoLisp-3.1.0 or newer)? My little investigation shows, that httpGate (or TCP stack?) sends GET / in first TCP packet and the rest of request in second TCP packet. I'm asking the above, because this behavior was observed last year too, and resulted in a rewrite of some parts of 'httpGate'. ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Trouble with httpGate and FreeBSD 9.1
Hi Mansur, Maybe it's possible to use SO_RCVLOWAT/SO_SNDLOWAT socket options? As far as I understand it, this should not be necessary (see below). Or maybe server side should do some reassembly (with a little timeouts to prevent DoS attacks) to get whole line of the request Yes, this is what the change from Mar 20th does. It is the new function rdLine(), which reads from the socket until at least a full line is received. It does so on the _receiving_ side of httpGate, i.e. on the way from the browser to httpGate. But your description seems to refer to the _sending_ side of httpGate. There is no special handling on the sending side, i.e. from httpGate to the PicoLisp process, because here plain TCP (without SSL encryption) is used and thus the 'line' function should be safe to receive the complete line. 2) with httpGate ! L - (G E T /) If I understand correctly, (line) immediatly returns first TCP packet value. I'm not expert in TCP/IP programming, maybe reason is FreeBSD itself? As I understand it, 'line' should not be concerned about TCP packets. These are on a lower level. PicoLisp reads from a socket, and should receive either correct data or EOF, but never partial data. It is a principle of TCP to handle this. So I must say I have no clue at the moment ... Do you have an idea how to further debug this? ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe