Newsgroups: vmsnet.networks.tcp-ip.cmu-tek
Subject: Re:  Request for technical assistance in CMU/Tek programming
From: Jonathan Luke Hall <jlhall@ficc.ferranti.com>
Date: Thu, 19 Nov 92 13:20:49 CST
Reply-To: jlhall@ficc.ferranti.com
Organization: The Internet
Return-Path: <SYNFUL@CMUTEK.CC.CMU.EDU>
Errors-To: SYNFUL@CMUTEK.CC.CMU.EDU
X-Listname: CMU-TEK TCP/IP Mailing list <CMU-TEK-TCP@CMUTEK.CC.CMU.EDU>
CC: cmu-tek-tcp@cmutek.cc.cmu.edu
X-Mailer: ELM [version 2.2 PL13]

In response to your response to my article:

>>From TGV.COM!MILLER  Thu Nov 19 01:56:57 1992
>
>>On a generic POSIX style system with TCPIP software that has a socket
>>interface, the socket may be shared by processes that are related.  Sharing
>>a network connection "socket" does not seem to work (at least for us) for
>>the CMU/Tek interface.  We have performed a SYS$ASSIGN and NET$OPEN within
>>a parent process and have attempted to use the TCP channel with spawned
>>subprocesses, without success.  Use of the TCP channel by a process other
>>than the process that performed the original SYS$ASSIGN results in a
>>SS$_NOPRIV status error from the processes that perform the NET$SENDs and
>>NET$RECEIVEs.
>
>The problem is that you are associating sockets with channels when
>they are more analagous to UCBs (Unit Control Blocks, or devices).
>Each UCB represents an endpoint on the network and each channel
>represents a process's connection to a UCB.
>
Our original design assumed that sockets WERE analagous to UCBs.
That didn't work.  Read on.

>>Questions:
>> 1) Am I correct in assuming that not being able to share a device
>>    channel is a basic limitation within VMS?  It would appear that a
>>    device channel is only usable by the process that performed the
>>    SYS$ASSIGN.  Is there no way to share a device without effectively
>>    duplicating or cloning the device channel?  The VMS Internals and
>>    Data Structures manual indicates that the CCB is specific to a
>>    single process and is thus not usable by other processes.
>
>You need to pass the name of the device to the new process and
>$ASSIGN a channel to it.  The differance between Unix and VMS is
>that you can do the cloning any way you like under VMS but under
>Unix you need to use fork() which clones *all* of the sockets
>(and all of the files descriptors, and all of the VM pages, etc...)
>
When you perform the NET$OPEN, you don't get a new name of the device.
The only device name that you have is "IP0", which is used by all
TCP/UDP/etc connections.

The question that I was raising was whether creating a device channel
with some special attributes would make it sharable by other processes.
One possibility that I saw was creating the device channel in
either exec or kernal access mode.  We tried this out;  it didn't work.

>
>> 2) If this is a basic limitation of VMS, is there an existing
>>    workaround for CMU/Tek that allows two processes to share a TCP
>>    connection?  What comes to mind would be a "clone" device channel
>>    that would map several logical device channels to a single
>>    TCP socket.  When a second process performs the SYS$ASSIGN and
>>    NET$OPEN (our first attempt to correct this), the first TCP
>>    connection was lost and the second process created a new TCP
>>    connection.  Is there a way for a process to create a device
>>    channel link to an existing TCP connection using the CMU/Tek
>>    package?  How do other TCPIP packages handle this?
>
>Just do the $ASSIGN and you'll be talking to the same "socket".
>Forget the NET$OPEN.

We tried this out.  It didn't work.  Let me give you an example that
will explain why it cannot work.  Suppose there is a process A that
creates 3 separate TCP conections.  I give you some quick pseudocode:

  SYS$ASSIGN first link using "IP0" as device
  NET$OPEN first link to remote node #1

  SYS$ASSIGN second link using "IP0" as device
  NET$OPEN second link to remote node #2

  SYS$ASSIGN third link using "IP0" as device
  NET$OPEN third link to remote node #3

  SYS$CREPRC subprocess B

In the spawned subprocess B, the pseudocode is:

  SYS$ASSIGN link using "IP0" as device

  NET$SEND data

The question is this:  which remote location does the data go
to?  The answer is this:  nowhere.  VMS and CMU/Tek doesn't allow
this because this cannot be automatically performed by VMS or
CMU/Tek without ambiguity.

If you having WORKING code to prove me wrong, send it to me and I
will read it (and eat my words).  I have working code to perform
QIO reads and writes for a passive TCP connection, an active TCP
connection, a UDP reader task, and a UDP writer task (inspite of
the fact that the documentation on the NET$OPEN for UDP NET$OPENs
was incorrect).

>
>>We need the ability to perform both reads and writes asynchronously
>>to a TCP connection.  The plan had been to perform the NET$OPEN in
>>the parent process and to spawn a process that handled the writes
>>only and to spawn another process to only handle the reads.  There
>>is synchronization logic between senders and the process that is
>>the output funnel.  Similar synchronization exists between processes
>>that are to receive data and the process that handles the reads.
>
>You can do that and QIO reads in one process while you QIO writes to
>another.
>
See example above.  We performed the following tests:

Test #1:

Process A

   SYS$ASSIGN link
   NET$OPEN link
   SYS$CREPRC subprocess B
   SYS$CREPRC subprocess C

Process B

   NET$SEND to channel id from process A (SS$_NOPRIV error)

Process C

   NET$RECEIVE to channel id from process A (SS$_NOPRIV error)

Test #2:

Process A

   SYS$ASSIGN link
   NET$OPEN link
   SYS$CREPRC subprocess B
   SYS$CREPRC subprocess C

Process B

   SYS$ASSIGN link
   NET$SEND to new channel id (error about channel not being opened)

Process C

   SYS$ASSIGN link
   NET$RECEIVE to new channel id (error about channel not being opened)

Test #3:

Process A

   SYS$ASSIGN link
   NET$OPEN link
   SYS$CREPRC subprocess B
   SYS$CREPRC subprocess C

Process B

   SYS$ASSIGN link
   NET$OPEN link              (CMU/Tek disconnects process A link, and
                               establishes a new link to remote node)
   NET$SEND to new channel id

   On subsequent NET$SENDs we get errors

Process C

   SYS$ASSIGN link
   NET$OPEN link              (CMU/Tek disconnects process B link, and
                               establishes a new link to remote node)
   NET$RECEIVE to new channel id

>>If the only answer is to use ASTs within a single process, we are
>>aware of that "solution" and are prepared to implement it.  An AST
>>solution does have its drawbacks, as we have found out.  VMS does not
>>allow the use of locks to force single thread access when one of
>>the contenders for the lock resource is an AST thread of a process
>>that has the lock resource.  The solution to this is to use event
>>flags, but this requires more code changes.  The "easy" solution of
>>ASTs is not so "easy" in our environment.  Basically, we need the "No,
>>you can't do that on VMS..." documentaion for our management to
>>explain the change in design and schedules for our implementation.
>
>I mainly work with kernel code and so I prefer the multi-level queue
>driven design of VMS processes.  I have trouble understanding why
>people would rather cling to select() and "non-blocking" I/O; something
>that may have been appropriate in the early seventies.  You want
>locking, then disable ASTs, or use $DCLAST().  How do you "lock"
>under POSIX?

When you disable ASTs, you stop new ASTs from arriving.  You DON'T
suspend an AST that is currently executing.

I work with an application that involves a hundred or more processes
that call common routines that may or may not already have
routines in them invoke ASTs.  I have to synchonize between not only
each of the processes for certain select portions of code that
update data structures but I have to synchonize between a mainline
thread and an already executing AST that might be calling the same
routines.  I try to reuse as much code as I can without writing new
code.

I do have an appreciation for people that work in the kernal.  I
was an operating system internalist (not unix) on another plaform
before I started work on the VAX.  I now prefer the VAX.  However,
my customers will demand of me that I convert to POSIX down the road,
because they do not wish to get "locked into" a specific vendor.
Don't try to convince me...

Oh, and by the way, I AM NOT A UNIX/POSIX programmer.  But I need to
feed my wife and kids and I expect that I will be a UNIX/POSIX programmer
within the next 7 years.  If you think that this is silly, you need to
convince not only my management, but the customers of my employer.
Don't try to convince me;  I really like VMS.

>
>-bruce
>

--
Cheers,
  Jonathan Luke Hall (jlhall@ficc.ferranti.com)