[comp.unix.wizards] STREAMS: problem of listen connect.ind in module

yarran@ccicpg.UUCP (Yarran A Lu) (10/22/88)

In implementing connection-oriented protocol module there is a problem when
the next downstream module/driver is also a connection-oriented protocol.
The listening queue which is connected to the next downstream module/driver is 
used to receive connect.indication primitives and seems it is better to be 
always kept in the listening state.  When the module gets the connect.ind
primitive, it responds back to the lower layer module/driver with a connect.
response primitive in order to accept the call.  The problem arises on whether 
the listening module should accept the call on the listening queue or create
a new queue to accept the call.  In the former case, the listening queue will
be changed into data transfer state and no more connect.indication primitives
can be put into the queue anymore, until the user process finally receives the
call and create a second queue to accept the call (by using ioctl I_FDINSERT).
During this period, all the following connect.indications have to be either
queued in the lower layer module/driver or be discarded. In the latter case,
unfortunately, AT&T did not supply any STREAMS function call  for creating
a queue between modules.  Of course, you can probably avoid this case by
implementing it as a mux driver and pre-allocate all the queues. But this  
approach is undocumented and seems violate the original intent of mux driver.

Is there any STREAMS guru or AT&T STREAMS architect knowing the answer?

yarran@ccicpg.UUCP (Yarran A Lu) (10/29/88)

Reading the responses to my question, I feel that it is necessary to explain
this question in more detail again.  The responses so far all misunderstood
what I was asking for.

>In implementing connection-oriented protocol module there is a problem when
>the next downstream module/driver is also a connection-oriented protocol.
>The listening queue which is connected to the next downstream module/driver is 
>used to receive connect.indication primitives and seems it is better to be 
>always kept in the listening state.  When the module gets the connect.ind
>primitive, it responds back to the lower layer module/driver with a connect.
>response primitive in order to accept the call.  The problem arises on whether 
>the listening module should accept the call on the listening queue or create
>a new queue to accept the call.  In the former case, the listening queue will
>be changed into data transfer state and no more connect.indication primitives
>can be put into the queue anymore, until the user process finally receives the
>call and create a second queue to accept the call (by using ioctl I_FDINSERT).
>During this period, all the following connect.indications have to be either
>queued in the lower layer module/driver or be discarded. In the latter case,
>unfortunately, AT&T did not supply any STREAMS function call  for creating
>a queue between modules.  Of course, you can probably avoid this case by
>implementing it as a mux driver and pre-allocate all the queues. But this  
>approach is undocumented and seems violate the original intent of mux driver.

Let's see the following figure:
			________________
			| user process |
			----------------
	user space	    | |      queues 1
        _______________________________________________
		        |  head   |
	kernel space	-----------
			    | |      queues 2
                        ----------------
			| module X     |        layer N
			----------------
			    | |      queues 3
                        ----------------
			| module Y or  |
			| driver Y     |	layer N-1
			----------------
Assumption: user process, module X and module Y all handle connection oriented
	    protocols.
The scenario is as follows:
1) User process has done open and bind.  The bind primitive also indicated it
   wants to receive multiple connect.indication in read queue 1. 
2) Module Y receives (N-1) peer-to-peer connect.indication PDU and sends the
   connect.indication primitive to module X.
3) If module X accepts the (N-1)connect.indication primitive, it would have to
   send downstream a (N-1) connect.response primitive to module Y.  If queue 3
   is used to accept the call, queue 3 will enter into data transfer state and
   it will no longer be available for module Y or X to receive further incoming
   (N-1)connect.indication.  Let's assume now that queue 3 enters into data 
   transfer state.
4) The remote layer (N) sends a connect.indication PDU embeded in layer N-1 data
   PDU.  Module Y receives (N-1) data PDU and sends the (N-1)data.indication
   primitive to module X upstream.
5) Module X receives the (N-1)data.indication which contains (N)connect.ind
   PDU. Module X in turn sends a (N)connect.indication primitive upstream to
   user process through read queue 1.
6) User process will open and bind a new stream and accept the call by sending
   downstream a connect.response primitive to module X.  In which, it tells
   the module X that it really wants to accept the call on the new stream,
   not queue 1.  This way, queue 1 can always be in listening state being
   able to receive multiple connect.indications.  The new queue of course will
   enter into data transfer state.

Now let's see what my question really is:
After step 3, if there is another (N-1)connect.indication PDU arrives at  
module Y, there will be no upstream queue in listening state to take the
(N-1)connect.indication primitive.  One may suggest that the new stream
created after step 6 may be used to replace the old stream. But there is
no guaranty that after the (N-1)layer connection is established, when the (N)
layer connect.indication will come (sometime a connection is always 
maintained alive and can be reused again by the upper layer).  The ideal
solution, I think, is that the module should have the same ability, like
the user process has, to create a new queue when it accepts the lower layer
connect.indication.  However, there is no STREAMS functions provided by
AT&T to manipulate the queues.

I hope this will clarify the question now. Thanks for all the good will. 

bae@unisoft.UUCP (Hwa Jin Bae) (10/31/88)

Yarran A Lu's question was:
"......
After step 3, if there is another (N-1)connect.indication PDU arrives at  
module Y, there will be no upstream queue in listening state to take the
(N-1)connect.indication primitive.  One may suggest that the new stream
created after step 6 may be used to replace the old stream. But there is
no guaranty that after the (N-1)layer connection is established, when the (N)
layer connect.indication will come (sometime a connection is always 
maintained alive and can be reused again by the upper layer).  The ideal
solution, I think, is that the module should have the same ability, like
the user process has, to create a new queue when it accepts the lower layer
connect.indication.  However, there is no STREAMS functions provided by
AT&T to manipulate the queues.
....."

This is a good point.  However, you don't need a STREAMS function to solve
this problem.  What's needed is some extra data structure and code within
module X to take care of the multiple connections.  Usually when
implementing TCP, a pool of TCB's and sockets are allocated in the beginning.
The number of connections that a socket is willing to accept is recorded
in socket data structure when the user makes a 'listen()' call.  Then
module X is sent a T_BIND_REQ message with CONIND_number field equal to
that number.  With an extra function (call it "listen_one_at_a_time()")
that will go through TCB's and make up a new TCB (which has a pointer
to the socket queue; we are talking about a socket as implemented as
a STREAM head here) and change the state of this TCB to T_WCON_IND.
That is, instead of one-to-one correspondence between socket and TCB,
you can utilize the same queue (allocated to a socket) for multiple
TCB's which may be in various states.

/hjb


-- 
----------- "I am no Jack Kennedy."  ------------------------------
 Hwa Jin Bae               bae@tis.llnl.gov       (Internet)
 UniSoft                   bae@unisoft.UniSoft    (smail uucp)
 Emeryville, CA            ...!uunet!unisoft!bae  (plain uucp)