jgh@root.co.uk (Jeremy G Harris) (08/25/88)
The BSD listen(2) syscall (on a socket) provides for the specification of a queue of pending connection requests. So does the TLI T_LISTEN function. What are the pros and cons of this functionality? Is it merely a matter of the cost of copying a protocol control block versus the cost of opening and initialising one? Or is there also a functional benefit? Jeremy. -- Jeremy Harris jgh@root.co.uk
romkey@asylum.UUCP (John Romkey) (08/28/88)
jgh@root.co.uk asked about why listen(2) allows a queue of pending connection requests. Under the BSD networking model, when you want to listen() for a connection, you first get a socket and then listen() on it. When a connection is opened, you do an accept() (which gets you a new socket) to actually get ahold of the connection. A server which wants to be able to handle more than one connection at a time normally fork()s, and the child process does the actual work while the parent goes back to listen()ing. If you don't allow a queue of pending requests, then from the time when the listen() completes to the time when the server issues a new listen(), there is no one listening. Any incoming requests will then get a reset. The window of time is probably pretty small, on the order of milliseconds, but you want it to be 0. So you need listen() to be able to handle more than one incoming request. And you have to tell listen() how many to handle so that the kernel can allocate appropriate resources. - john romkey
CLYNN@G.BBN.COM (08/29/88)
Jeremy, As John pointed out, the call queueing is used to reduce the probability that a SYN arrives during a window where there is no listening connection to bind it to, thus causing a RESET to be returned. Queueing can only reduce it, since it is always possible for there to be more arriving SYNs than there are remaining free queue slots. However, I reguard specifying the size to the kernel to be more for the purpose of "limiting" resources (such as processes [from the forks] and cpu cycles) than for "allocating" them. As with all implementations, tradeoffs have been made. I feel that one of the "minuses" with the BSD implementation is that not only does the listen cause the arriving SYN to be accepted and bound to a new TCP connection block, but that the protocol machine is also started. Thus a connection may proceed to the ESTABLISHED state and accept/ACKnowledge (usually 4K bytes of) data before the application-level peer (process) is even created. This prevents the process from: 1) examining the IP-address identity of the caller before deciding ACKnowledge the SYN vs. send a RESET, What if X were to place a "collect" call to such an implementation and send 4K data; then the receiver process start up and decides it doesn't want to accept the call. Who pays for the 4K bytes? (The receiver COULD make the 4K available to the appliaction.) 2) checking its routing tables and applying administratively specified per IP-address source routing, etc., 3) selecting initialization parters based on IP-level parameters such as TOS and options, or Maybe local system has a method for setting the TCP MSS (which the spec says has to be in the SYN packet). 4) specifying initial TCP-level options, etc. Charlie
dougm@violet.ICO.ISC.COM ("Doug McCallum") (08/29/88)
In reply to your message of 25 Aug 88 16:10:01 GMT ------- > The BSD listen(2) syscall (on a socket) provides for the specification > of a queue of pending connection requests. So does the TLI T_LISTEN function. > What are the pros and cons of this functionality? Is it merely a matter > of the cost of copying a protocol control block versus the cost of opening > and initialising one? Or is there also a functional benefit? The reason you want to allow for queueing of incoming connection requests is that you want to buffer them while an application is processing a previous one. The alternative is to reject the connections until the application is ready again. Even with minimal overhead tin getting the appliation started there will be cases where multiple connection requests arrive back-to-back from the network. You don't want to reject these so you queue them until there is time to properly respond. In the BSD systems, the queued connection requests get accepted automatically. In the TLI mechanism, it is possible that the connection request has not been responded to giving the application final say on whether to accept or reject the request. One minor clarification, the TLI indication to queue connection requests is in the t_bind call and not the t_listen. T_listen is not the same as the socket listen. t_listen waits for an incoming connection request and returns that to the application. The information in the connection request is then given to the t_accept call if the connection is to be accepted or the t_snddis call if the connection is to be rejected.
mouse@mcgill-vision.UUCP (der Mouse) (09/02/88)
> [A disadvantage of the BSD networking model is that] a connection may > proceed to the ESTABLISHED state and accept/ACKnowledge (usually 4K > bytes of) data before the application-level peer (process) is even > created. [...] What if X were to place a "collect" call to such an > implementation and send data; then the receiver process start up and > decides it doesn't want to accept the call. Who pays for the bytes? Presumably in an environment where the notion of a "collect" call makes sense, one doesn't use this model. It would be fairly easy to add such capability to BSD. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu
jgh@root.co.uk (Jeremy G Harris) (09/02/88)
I asked: > The BSD listen(2) syscall (on a socket) provides for the specification > of a queue of pending connection requests. So does the TLI T_LISTEN function. > What are the pros and cons of this functionality? Is it merely a matter > of the cost of copying a protocol control block versus the cost of opening > and initialising one? Or is there also a functional benefit? My thanks to everybody who replied, both here and by mail. Several people pointed out that I said t_listen when I should have said t_bind - sorry, my fingers were running faster than my brain.... However, nobody has answered the question that I was trying to ask. I can't have made a good job of the question :-) Why does this connection queue have to be handled by the kernel? Why couldn't the application just open and initialise for listening (not in the BSD syscall sense) as many transport endpoints as it's queue needs to be long? Opinions, anybody? Jeremy -- Jeremy Harris jgh@root.co.uk
dannyb@kulcs.uucp (Danny Backx) (09/08/88)
In article <628@root44.co.uk> jgh@root44.UUCP (Jeremy G Harris) writes: >I asked: >> The BSD listen(2) syscall (on a socket) provides for the specification >> of a queue of pending connection requests. So does the TLI T_LISTEN function. > >> What are the pros and cons of this functionality? Is it merely a matter >> of the cost of copying a protocol control block versus the cost of opening >> and initialising one? Or is there also a functional benefit? > >Why does this connection queue have to be handled by the kernel? Why couldn't >the application just open and initialise for listening (not in the BSD syscall >sense) as many transport endpoints as it's queue needs to be long? How about this: A server process S is doing accept. It implements a highly available server. For speeding things up, it forks of a process for every client. A client A connects to the socket, and while S is forking, closing the second socket, and doing the next accept, two client processes B and C have attempted to connect. Without a queue, what would happen ? One of the connects could be remembered, while the second one certainly is forgotten by the kernel that the server runs on. Since we're talking about TCP, which is supposed to be reliable, the client which was forgotten will retry the attempt to connect (after a LONG timeout), and then probably the connection will be made. The time interval between the two accept in S is probably small. Therefore, this situation will not happen very frequently. Still, adding a small queuing function in the kernel on the accepting side would remove the problem alltogether. How about letting the server do a new system call? (Let's call it `listen') This should eliminate the problem completely. Disclaimer : I can't claim that this is really the way the listen system call was invented. I only think this is its only use. Danny Backx -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Danny Backx | mail: Danny Backx Tel: +32 16 200656 x 3544 | Katholieke Universiteit Leuven Fax: +32 16 205308 | Dept. Computer Science E-mail: dannyb@kulcs.UUCP | Celestijnenlaan 200 A ... mcvax!prlb2!kulcs!dannyb | B-3030 Leuven dannyb@blekul60.BITNET | Belgium
art@ACC.ARPA (09/09/88)
>Why does this connection queue have to be handled by the kernel? Why couldn't >the application just open and initialise for listening (not in the BSD syscall >sense) as many transport endpoints as it's queue needs to be long? > >Opinions, anybody? At least for BSD, the kernel will not allow more than one listening socket to be bound to a particular local endpoint address, but the server wants to be able to open multiple connections which refer to the same local endpoint address. To deal with this, the kernel accepts multiple connections and queues them at the listening socket. When an accept system call is issued, an open connection is associated with a new socket which is then returned to the user. One can think of the new socket a "clone" of the listening socket. To allow multiple listening sockets to be bound to the same endpoint address opens up a bunch of ambiguity problems. (TCP doesn't know if identical services are available on all those sockets) Art Berggreen art@acc.arpa ------