HP OpenVMS Systems Documentation

Content starts here

VMS DECwindows Transport Manual


Previous Contents Index

  1. Test the status from the IO$_ACCESS $QIO. If the network is shutting down, call DECW$XPORT_ATTACH_LOST to report that the transport shut down and then call DETACH_AND_POLL to poll for its return. If it was successful, continue processing to construct a full connection context.
  2. Start a named block of code that attempts to allocate and initialize the resources needed to maintain a connection. If any part of this setup fails, the code block is exited and failure processing recovers any allocated resources.
  3. Allocate an IXTCC and XTPB for this connection. Store the address of the XTPB in the IXTCC.
  4. Increment the connection reference count and store the IXTCC on the XTDB so that it can be found in case of image rundown before the connection is fully established.
  5. Call the transport-common DECW$XPORT_ALLOC_INIT_QUEUES routine to allocate and initialize the communication queues. DECW$XPORT_ALLOC_INIT_QUEUES allocates a block of storage for an XTCC, XTCQ, and all of the XTCBs for a connection. DECW$XPORT_ALLOC_INIT_QUEUES must allocate at least an XTCC; the other structures are optional. DECW$XPORT_ALLOC_INIT_QUEUES places all of the XTCBs on the appropriate free queues.
  6. Convert the Network Standard Format Internet address of the connection client, which is returned by the IO$_ACCESS $QIO in the XTDB$T_ACC_INADDR field of the XTDB, into a dot-format Internet address. For example, the longword value 2C28B48216 would be converted to the ASCII string 130.180.40.44.
  7. Attempt to perform address-to-nodename translation of the dot-format Internet address to get the textual name of the client node. The arguments of the IO$_ACPCONTROL $QIO system service are as follows:
    • P1 is the address of a 2-longword descriptor of a longword containing the function code INETACP_FUNC$C_GETHOSTBYADDR.
    • P2 is the address of the descriptor of the dot-format Internet address to be translated.
    • P3 is the address of a word to receive the length of the resultant string.
    • P4 is the address of a descriptor of an area of memory to receive the result of the translation.
  8. The address-to-nodename translation failed with the status of SS$_ENDOFFILE. This indicates that the dot-address could not be found in the local host database. The dot-address form of the client's node address will be used as the node name of the client.
  9. The address-to-nodename translation succeeded. Check if the returned node name matches the local node name. If it does, use the string "0" as the client's node name; otherwise use the string returned by the translation operation.
  10. The Internet protocols do not support the concept of a remote user name. Synthesize this information by identifying the remote user with the string "?".
  11. Point the XTCC to the remote-user name and node fields.
  12. Copy the channel assigned to the client connection into the IXTCC and zero this field in the XTDB.
  13. Mark the connection as active by setting the flags longword of the XTCC to the constant XTCC$M_ACTIVE and the connection mode as a remote server (these two operations should be performed in this order because the mode field is a subfield of the flags longword).
    Initialize the pointer to the XTDB in the IXTCC and the pointer to the transport function table in the IXTCC. Inherit the event flag for I/O operations from the XTDB.
  14. Deliver a user-mode AST to the TRANSPORT_OPEN_CALLBACK routine (with the IXTCC as the argument) to complete the connection acceptance in user mode.
    TRANSPORT_OPEN_CALLBACK performs the callback to the transport caller and starts I/O on the connection.
  15. Executive-mode connection setup completed.
  16. If any step of the connection setup in the connect block failed, resource recovery operations are performed here: channels are deassigned, memory is deallocated, connection structures are disassociated, reference counts are decremented, and so on.
  17. Call the transport common DECW$XPORT_ACCEPT_FAILED routine to generate a report describing the cause of the failure.
  18. This is the common exit point. Invoke TRANSPORT_READ_QUEUE to issue another IO$_ACCESS $QIO to receive another client connection request.

8.2.19 Sample TRANSPORT_OPEN_CALLBACK Routine

TRANSPORT_OPEN_CALLBACK is invoked as a user-mode AST procedure by TRANSPORT_READ_AST to complete the creation of a connection. It performs a callback to the server's connect-request routine and, depending on the value returned by that routine, completes the connection by starting the initial read operation.

Example 8-19 shows a sample implementation of the TRANSPORT_OPEN_CALLBACK routine.

Example 8-19 Sample TRANSPORT_OPEN_CALLBACK Routine

   .
   .
   .
ROUTINE transport_open_callback( itcc : REF $BBLOCK ) : NOVALUE =
BEGIN
BUILTIN
     REMQTI ;
LOCAL
    tcc:        REF $BBLOCK INITIAL ( .itcc [ixtcc$a_tcc] ),
    free_queue: REF VECTOR[2],
    status ;

LABEL
    start_reading ;

start_reading:
        BEGIN
        (1)IF NOT (status = (.tcpip_tdb [xtdb$a_connect_request])( .tcc ))
        THEN
            LEAVE start_reading ;


        (2)xport_in_state_srp( tcc ) ;
        xport_out_state_srp( tcc ) ;
        xport_in_free_disable( tcc, decw$c_xport_buffer_lrp ) ;

        (3)free_queue = .tcc [xtcc$a_ifs_queue] ;
        IF .free_queue[0] EQLA 0
        THEN
            BEGIN
            free_queue = .tcc [xtcc$a_ifl_queue] ;
            IF .free_queue[0] EQLA 0
            THEN
                BEGIN
                status = DECW$_BADQUEUE ;
                LEAVE start_reading ;
                END ;
            END ;

        (4)status = DECW$$TCPIP_EXECUTE_FREE
                     ( .tcc, 0, decw$c_xport_buffer_srp, .free_queue ) ;
        IF .status
        THEN
            RETURN ;
        END ;

        (5)DECW$XPORT_CLOSE( .tcc ) ;

        (6)DECW$XPORT_REFUSED_BY_SERVER ( .status ) ;
 RETURN ;
 END ;

   .
   .
   .
  1. Invoke the server's connect-request routine with the address of the XTCC for the connection.
  2. The transport user accepted the connection. Force the input and output operations to use small request packets for startup and disable free-input operations on the input large request packet free queue.
  3. Check the small input free queue and, if it is empty, the large input free queue. If both are empty, the transport cannot perform a read operation, so return a bad queue status.
  4. Call the XTFT$A_EXECUTE_FREE routine to put the buffers on the free queue and return.
  5. This code is entered only if the callback procedure returned a failure status. Invoke the transport-common DECW$XPORT_CLOSE routine to complete the destruction of the connection.
  6. Call DECW$XPORT_REFUSED_BY_SERVER to format and deliver a message vector to describe the reason for the connection refusal. This is constructed on the status code returned by the callback procedure.

8.2.20 Sample DETACH_AND_POLL Routine

DETACH_AND_POLL starts polling for a transport restart.

Example 8-20 shows a sample implementation of the DETACH_AND_POLL routine.

Example 8-20 Sample DETACH_AND_POLL Routine

   .
   .
   .
ROUTINE detach_and_poll( tdb : REF $BBLOCK ) : NOVALUE =

BEGIN
BUILTIN
    EMUL ;

LOCAL
    status ;

(1)IF .tdb [xtdb$v_dying]
THEN
    RETURN ;

(2)IF .tdb [xtdb$w_chan] NEQ 0
THEN
    BEGIN
    $CANCEL( CHAN = .tdb [xtdb$w_chan] ) ;
    $DASSGN( CHAN = .tdb [xtdb$w_chan] ) ;
    tdb [xtdb$w_chan] = 0 ;
    END ;

(3)IF .tdb [xtdb$w_acc_chan] NEQ 0
THEN
    BEGIN
    $CANCEL( CHAN = .tdb [xtdb$w_acc_chan] ) ;
    $DASSGN( CHAN = .tdb [xtdb$w_acc_chan] ) ;
    tdb [xtdb$w_acc_chan] = 0 ;
    END ;

(4)IF .reattach_timer_id EQL 0
THEN
    BEGIN
    reattach_timer_id = .tdb ;
    EMUL( %REF( REATTACH_INTERVAL_SECS ), %REF( -10000000 ), %REF( 0 ),
              reattach_timer_delta ) ;
    END ;

(5)IF .tcpip_tdb [xtdb$v_dying]
THEN
    RETURN ;

(6)status = $SETIMR(
             EFN = 31,
             DAYTIM = reattach_timer_delta,
             ASTADR = reattach_ast,
             REQIDT = .reattach_timer_id ) ;

(7)IF NOT .status
THEN
   DECW$XPORT_REATTACH_FAILED( .tdb, .status ) ;
RETURN ;
END ;
   .
   .
   .
  1. If the XTDB$V_DYING bit is set, there is no need to continue.
  2. Release the channel to the Internet device.
  3. Release the connection-accept channel.
  4. If the timer is not identified, associate the timer with the address of the XTDB.
  5. Make sure that the transport is still alive.
  6. Start polling for a network restart at reattach_timer_delta intervals. (The REATTACH_AST routine is described in Section 8.2.21.)
  7. If unable to poll for the restart, report that the reattach failed.

8.2.21 Sample REATTACH_AST Routine

REATTACH_AST calls DECW$$TCPIP_ATTACH_TRANSPORT to reattach the transport when the reattach_timer_delta interval has expired.

Example 8-21 shows a sample implementation of the REATTACH_AST routine.

Example 8-21 Sample REATTACH_AST Routine

   .
   .
   .
ROUTINE reattach_ast( tdb : REF $BBLOCK ) : NOVALUE =

BEGIN

LOCAL
    status;

(1)status = DECW$$TCPIP_ATTACH_TRANSPORT( .tdb ) ;

RETURN ;
END ;
   .
   .
   .
  1. Call DECW$$TCPIP_ATTACH_TRANSPORT to reattach the transport.

8.2.22 Sample XTFT$A_RUNDOWN Routine

XTFT$A_RUNDOWN is invoked by the common transport when the image in which the transport is running exits. It is the responsibility of each transport's rundown procedure to release any resources that might survive the image exit. ASTs are disabled while XTFT$A_RUNDOWN is executing.

Example 8-22 shows a sample implementation of the XTFT$A_RUNDOWN routine.

Example 8-22 Sample XTFT$A_RUNDOWN Routine

   .
   .
   .
GLOBAL ROUTINE DECW$$TCPIP_RUNDOWN(   tdb : REF $BBLOCK ) : NOVALUE =

BEGIN
BIND
    iosb = tdb [xtdb$w_iosb] : VECTOR [4,WORD],
    xtpb = .tdb [xtdb$a_tpb] : $BBLOCK ;

LOCAL
    itcc : REF $BBLOCK INITIAL( .tdb [xtdb$a_itcc_flink] ),
    status ;


(1)tdb [xtdb$v_dying] = 1 ;

(2)WHILE .itcc NEQA tdb [xtdb$a_itcc_flink] DO
    BEGIN
    BIND
       xtcc = .itcc [ixtcc$a_tcc] : $BBLOCK ;

    xtcc [xtcc$v_dying] = 1 ;
    $CANCEL(    CHAN = .itcc [ixtcc$w_chan] ) ;
    $DASSGN(    CHAN = .itcc [ixtcc$w_chan] ) ;
    itcc [ixtcc$w_chan] = 0 ;
    itcc = .itcc [xtcc$a_flink] ;
    END ;

(3)IF ( .tdb [xtdb$v_mode] AND DECW$M_XPORT_CLIENT ) NEQ 0
THEN
    RETURN ;

(4)$CANCEL(   CHAN = .tdb [xtdb$w_chan] ) ;
$CANCEL(   CHAN = .tdb [xtdb$w_acc_chan] ) ;

$DASSGN(   CHAN = .tdb [xtdb$w_acc_chan] ) ;
tdb [xtdb$w_acc_chan] = 0 ;
$DASSGN(   CHAN = .tdb [xtdb$w_chan] ) ;
tdb [xtdb$w_chan] = 0 ;

IF .reattach_timer_id NEQ 0
THEN
    $CANTIM( REQIDT = .reattach_timer_id ) ;

RETURN ;

END ;
   .
   .
   .
  1. Mark this transport as dying to prevent any of the routines, such as TRANSPORT_READ_QUEUE, from performing additional operations.
  2. Locate each connection known to this transport and perform any rundown operations necessary. For TCP/IP, the connection is marked as dying to prevent any per-connection routine from operating on the connection. Any I/O operation in progress on the connection is canceled and the communication channel is deassigned.
  3. If the caller is a client, no more processing is needed for rundown.
  4. For servers, cancel any I/O operation on the listening and accepting channels and deassign the channels.

8.2.23 Sample DECW$TRANSPORT_INIT Routine

The DECW$TRANSPORT_INIT routine initializes and returns the address of the XTFT. Each specific transport has a global symbol named DECW$TRANSPORT_INIT. This is the address of the first procedure invoked in the specific transport during the common transport DECW$XPORT_ATTACH_TRANSPORT routine and it is responsible for initializing the fields in the XTFT structure.

The DECW$EXAMPLES:XPORT_EXAMPLE_XFER.MAR module and DECW$EXAMPLES:DEMO_BUILD.COM procedure ensure that the transfer vector to the DECW$TRANSPORT_INIT routine is found at the beginning of the transport-specific shareable image.

Unlike the other transport-specific functions, DECW$TRANSPORT_INIT returns the address of the XTFT structure as its return value instead of a VMS condition code.

Example 8-23 shows a sample implementation of the DECW$TRANSPORT_INIT routine.

Example 8-23 Sample DECW$TRANSPORT_INIT Routine

   .
   .
   .
GLOBAL ROUTINE DECW$TRANSPORT_INIT =

BEGIN
LOCAL
    tft:      REF $BBLOCK ;

tft = tcpip_tft ;
tft[xtft$l_required0] = xtft$k_required0 ;
tft[xtft$l_reserved0] = 0 ;
tft[xtft$a_execute_write] = decw$$tcpip_execute_write ;
tft[xtft$a_write] = decw$$tcpip_write ;
tft[xtft$a_write_user] = decw$$tcpip_write_user ;
tft[xtft$a_execute_free] = decw$$tcpip_execute_free ;
tft[xtft$a_free_input_buffer] = decw$$tcpip_free_input_buffer ;
tft[xtft$a_close] = decw$$tcpip_close ;
tft[xtft$a_open] = decw$$tcpip_open ;
tft[xtft$a_attach_transport] = decw$$tcpip_attach_transport ;
tft[xtft$a_rundown] = decw$$tcpip_rundown ;
tft[xtft$l_xtcc_length] = xtcc$c_tcpip_length ;
tft[xtft$l_xtpb_length] = xtpb$c_tcpip_length ;
tft[xtft$l_xtdb_length] = xtdb$c_tcpip_length ;
tft[xtft$l_ixtcc_length] = ixtcc$c_tcpip_length ;
tft[xtft$l_required1] = xtft$k_required1 ;
.tft
END ;
   .
   .
   .

DECW$EXAMPLES:XPORT_EXAMPLE_XFER.MAR generates transfer vectors for the sample transport. A portion of the XPORT_EXAMPLE_XFER.MAR code follows:


   .
   .
   .
.PSECT $TRANSFER$    PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT,QUAD

TRANSFER DECW$TRANSPORT_INIT

.END
   .
   .
   .

The $TRANSFER$ program section points to a program unit, in this case DECW$TRANSPORT_INIT. The DEMO_BUILD.COM procedure then creates a cluster and collects the $TRANSFER$ program section in it, as described in Example 8-24.

8.3 Compiling and Linking Options for the Transport

The DECW$EXAMPLES:DEMO_BUILD.COM procedure supplied with the DECwindows kit builds the VMS DECwindows example programs, including the sample TCP/IP transport layer described in this chapter. You can refer to this procedure for suggestions on compiling and linking a transport layer in the DECwindows environment.

Example 8-24 shows the transport-specific portion of the DEMO_BUILD.COM procedure.

Example 8-24 DEMO_BUILD.COM Procedure

      .
      .
      .
   $ ! If Bliss and UCX are installed on the system and DECwindows is installed
   $ ! with the common transport shareable image and Bliss programming support,
   $ ! then compile and link the example transport.
   $ !
   $ if f$search("sys$library:ucx$inetdef.r32") .eqs. "" then goto do_fortran
   $ if f$search("sys$share:decw$transport_common.exe") .eqs. "" then goto do_fortran
   $ define/nolog src$ decw$examples
(1) $ bliss decw$examples:xport_example
   $ macro decw$examples:xport_example_xfer
(2) $ link/share=decw$transport_example.exe -
           xport_example,-
           xport_example_xfer,-
           sys$input/opt

(3) gsmatch=lequal,12,12
   psect_attr=$code$,pic,shr,exe,nowrt
   psect_attr=$plit$,pic,shr,exe,nowrt
   psect_attr=$own$,pic,noshr,noexe,wrt
   psect_attr=$global$,pic,noshr,noexe,wrt

(4) cluster=transfer_cluster,,,
   collect=transfer_cluster,$transfer$
   cluster=code_cluster,,,
   collect=code_cluster,$code$,$plit$

(5) protect=yes
   cluster=own_cluster,,,
   collect=own_cluster,$own$,$global$
   protect=no
   sys$share:decw$transport_common/shareable
      .
      .
      .
  1. Compile the transport-specific code.
    The DECW$EXAMPLES:XPORT_EXAMPLE_XFER.MAR module generates transfer vectors for the sample transport.
  2. Link the transport-specific code as a VMS shareable image that can be accessed by the transport-common component.
    Make sure your transport-specific shareable image is in the form DECW_TRANSPORT_transport_name.EXE. (Transport names that do not contain a $ character are reserved for third-party and customer transport images.) When called by either Xlib or the server, DECW$XPORT_ATTACH_TRANSPORT attempts to locate and activate an image with a name in this form.
  3. Prevent image activation of incompatible transport versions.
    Set program section attributes appropriately for shareable images.
  4. Create a cluster for the transfer vector and place the named program section, in this case $transfer$, in it. The $transfer$ program section points to the DECW$TRANSPORT_INIT routine, as described in Section 8.2.23. The transfer vector must be at the beginning of the image (in the first cluster) or the transport common will not activate it.
  5. OWN and global variables are protected from user-mode writing.

8.3.1 Installing the Transport-Specific Shareable Image

You must install your transport-specific image as a protected image in the SYS$SHARE directory in order for the transport-common layer to access it. To do this, perform the following steps:

Note

Because the common transport uses only executive-mode logical names, the logical name SYS$SHARE cannot be redefined.
  1. Log in to the system manager account.
  2. Copy the transport image to the SYS$SHARE directory.


    $COPY DECW_TRANSPORT_transport_name.EXE SYS$SHARE:/PROT=W:RE
    
  3. Add the following line to SYS$MANAGER:SYSTARTUP_V5.COM:


    $ INSTALL CREATE SYS$SHARE:DECW_TRANSPORT_transport_name/OPEN /SHARED /HEADER_RES /PROTECTED
    
  4. If you have not already done so, copy SYS$MANAGER:DECW$PRIVATE_SERVER_SETUP.TEMPLATE to *.COM . Then, modify the DECW$SERVER_TRANSPORTS symbol to include your transport. For example, DECW$SERVER_TRANSPORTS could translate to "DECNET,LOCAL,TCPIP,FOO".


    $ DECW$SERVER_TRANSPORTS == "DECNET,LOCAL,TCPIP,FOO"
    

    Note

    If you write your own transport layer based on TCP/IP, do not include the Digital-supplied TCPIP transport name in the DECW$SERVER_TRANSPORTS symbol. The X11 protocol convention for TCP/IP is that server number 0 listens on port 6000, server number 1 listens on port 6001, and so forth.
    The Digital-supplied TCPIP transport attaches to port 6000 and will conflict with your own TCP/IP transport.

    The server uses the symbol DECW$SERVER_TRANSPORTS to determine which transports to attach and initialize and calls the DECW$XPORT_ATTACH_TRANSPORT routine for each transport identified by the symbol. The transport_name argument specifies the transport, such as FOO.
  5. Manually execute the install command you added to SYS$MANAGER:SYSTARTUP_V5.COM.
  6. Enter the following command to restart DECwindows:


    $@DECW$STARTUP RESTART
    

    Answer "yes" to the confirmation question.
  7. Customize security as described in the Using DECwindows Motif for OpenVMS for TCP/IP, but use the transport name transport_name instead of TCPIP.
  8. Create a DECterm window on the workstation and enter the following command:


    $SET DISPLAY /CREATE /NODE=your_node /TRANSPORT=transport_name
    

    Substitute the node name of your workstation for your_node. Enclose your_node in quotes if your transport distinguishes lowercase node names.
  9. Run any DECwindows application from the DECterm window. The application will now use your transport to establish the connection.

8.3.2 Installing the Example Transport Shareable Image

If you have installed the UCX software, you can install and use the example transport by doing the following:

Note

The Digital-supplied TCPIP transport attaches to port 6000 and will conflict with the example transport, which also attaches to port 6000. If you want to use the example transport, do not include the Digital-supplied TCPIP transport name in the DECW$SERVER_TRANSPORTS symbol.
  1. Log into the system manager account.
  2. Copy the example transport to the SYS$SHARE directory as follows:


    $COPY DECW$EXAMPLES:DECW$TRANSPORT_EXAMPLE.EXE SYS$SHARE:/PROT=W:RE
    
  3. Add the following line to SYS$MANAGER:SYSTARTUP_V5.COM:


    $ INSTALL CREATE SYS$SHARE:DECW$TRANSPORT_EXAMPLE /OPEN /SHARED /HEADER_RES /PROTECTED
    
  4. If you have not already done so, copy SYS$MANAGER:DECW$PRIVATE_SERVER_SETUP.TEMPLATE to *.COM . Then, modify the DECW$SERVER_TRANSPORTS symbol to include the example transport.


    $ DECW$SERVER_TRANSPORTS == "DECNET,LOCAL,EXAMPLE"
    
  5. Manually execute the install command.
  6. Enter the following command to restart DECwindows:


    $@DECW$STARTUP RESTART
    

    Answer "yes" to the confirmation question.
  7. Customize security as described in the Using DECwindows Motif for OpenVMS for TCP/IP, but use the transport name EXAMPLE instead of TCPIP.
  8. Create a DECterm window on the workstation and enter the following command:


    $SET DISPLAY /CREATE /NODE=your_node /TRANSPORT=EXAMPLE
    

    Substitute the node name of your workstation for your_node. Enclose your_node in quotes if the Internet node name contains lowercase characters.
  9. Run any DECwindows application from the DECterm window. The application will now use the example transport to establish the connection.


Index Contents