Subject: Socket Streams problems - or am I just using them incorrectly?

From: Fred Cohen <[email-masked]>
Date: Sat, 17 Apr 1999 20:11:25 -0700 (PDT)

I am having several difficulties with 'Socket Streams' and I thought
list members might help me better understand what I am doing wrong.
Here they are...

I run lisp and do the following
	indented done from the Unix shell

(setq socket (socket-server 12345))                      ; setup port
(socket-wait socket)                                    ; wait for a connect
(setq sockstream (socket-accept socket))                ; accept connection
	1> lsof | grep lisp
	lisp.run  29646   fc    3r   REG        8,0     780485  987508 /u -- src/lisp.run
	lisp.run  29646   fc    4u  inet 0x0057b018        0t0     TCP *:vce (LISTEN)

	2> telnet localhost 12345
	... get test

(setq get (concatenate 'string (loop until (equal #\Return (setq tmp (read-char stream))) collect tmp)))
(write-string "test" sockstream)
	... get test
(close sockstream) (socket-server-close socket)         ; close out
	... (socket closes - session ends)

	1> lsof | grep lisp
	lisp.run  29646   fc    3r   REG        8,0     780485  987508 /u -- src/lisp.run
	lisp.run  29646   fc    4u  inet 0x0057b018        0t0     TCP *:vce (LISTEN)

OK - problem 1 - this TCP socket should be closed - but it is not. This means that...
	a) The socket can never be closed
	b) I can do (close sockstream) (socket-server-close socket)         ; close out
		repeatedly with no errors - and no effect.
	c) I can't leave LISP in the normal way...

(bye)

yields an error and I cannot leave... except sometimes... (ouch!)

Problem 2: If I do:
	...
        2> telnet localhost 12345

and then wait...  the server is stuck forever - and since there is no
"fork" function, I can only serve one request at a time.  The rest of
the world goes into an indefinate wait until the first caller decides
to make a request... which means denial of services.

Is there a way to do a fork... or an alternative?
Note that (socket-wait socket-server [seconds [microseconds]])
will not save me because - the socket wait is not where the timeout
is needed. It is in the read-char that I time out.

Any assistance would be most helpful.  Until then, I continue to serve
without using the socket interface (i.e., via inetd as stdin and stdout)
with the added complexity that any coding error and I give the extrnal
user the ability to issue commands of their chosing to the lisp
interpreter running on my server. 

FC

--
  Fred Cohen & Associates: http://all.net - [email-masked] - tel/fax:925-454-0171
				Have a great day!!!

Per the official policy of Sandia National Laboratories, the reader should be
aware that:
  - Fred Cohen of Fred Cohen & Associates is the same Fred Cohen who is a
    Principal Member of Technical Staff at Sandia National Laboratories.
  - Fred Cohen & Associates - is owned and operated by Fred Cohen and is
    separate and independent from the work done by Fred Cohen at Sandia
    National Laboratories.

---

From: Eric Marsden <[email-masked]>
Date: Mon, 19 Apr 1999 13:59:56 +0200

On Sat, Apr 17, 1999 at 08:16:17PM -0700, Fred Cohen wrote:

  [socket streams not closing properly]
  
I haven't noticed this. What platform are you using?

  [serving multiple users via sockets]
  
this is a true problem, difficult to resolve. I don't think there is a fork
in CLISP, and besides, it would be a costly way to serve multiple users. One
alternative would be to use select() trickery (assuming you're running on
Unix) and serve multiple sockets, but this too isn't implemented.

If you can formulate your requests over HTTP (this may require you
implementing session management, which isn't too difficult), perhaps the
best approach is to have CLISP run as a web server, and put it behind a web
proxy such as Squid. That way you get caching of static "pages" for free,
proper handling of HTTP/1.1 requests without having to fiddle with chunking,
and --especially-- automatic handling of multiple clients (ie the proxy will
only send the requests to the server when they have been completely issued,
and will look after serving the results back to the client at whatever speed
it likes; no more denial of service). As long as you don't have too many
users this solution should work.

-- 
Eric Marsden
emarsden @ mail.dotcom.fr
It's elephants all the way down