Re: Trouble with httpGate and FreeBSD 9.1 [So

2013-02-04 Thread Mansur Mamkin
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

2013-02-04 Thread Alexander Burger
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

2013-02-03 Thread Alexander Burger
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

2013-02-03 Thread Alexander Burger
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

2013-02-02 Thread Alexander Burger
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

2013-02-02 Thread Alexander Burger
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