Source code of HPW routine I255604

Server program that runs on Host

 

*********************************************************************
*
*                                I255604
*
*                        TCP/IP Password Server
*
*             Written by William van den Heuvel, 1998
*
*             Update: 1998-11-10
*
*********************************************************************
*
* This program is a TCP/IP server that listens on port x.
*
* It provides Password services submitted by the client program.
* The client is a program that may run on any platform that
* supports TCP/IP.
* The client program submits the request by sending a TCP/IP message
* to port x. The server listens on this port and returns a reply.
*
***********************************************************************
*
* this program uses the EZASMI assembler macro API:
* EZASMI TYPE=SETSOCKOPT  - set socket options
* EZASMI TYPE=BIND        - bind server socket to a port
* EZASMI TYPE=GETSOCKNAME - get bound port number
* EZASMI TYPE=LISTEN      - make backlog queue for incoming conections
*
***********************************************************************
*
* on entry,
* register 1 points to the API parameters.
*
*......................................................................
*
* on completion,
* register 15 will contain a return code (RC):
*
* RC=0 - normal completion (always)
*
***********************************************************************




**********************************************************************
*
I255604  CSECT
I255604  AMODE ANY
I255604  RMODE ANY
*
R0       EQU   0
R1       EQU   1
R2       EQU   2
R3       EQU   3
R4       EQU   4
R5       EQU   5
R6       EQU   6
R7       EQU   7
R8       EQU   8
R9       EQU   9
R10      EQU   10   PARM - address of pointer to PARM-string)
R11      EQU   11   BASE - base register of this program
R12      EQU   12   CAA  - reserved for LE
R13      EQU   13   DSA  - Dynamic Storage Area
R14      EQU   14   return address
R15      EQU   15   entry point address
*
DSA      EQU   R13
CAA      EQU   R12
BASE     EQU   R11
API      EQU   R10        API parameters
GWA      EQU   R9         GLOBAL storage
TIE      EQU   R8         TASK storage
*
         USING API_DSECT,API
         USING DSA_DSECT,DSA
         USING GWA_DSECT,GWA
         USING TIE_DSECT,TIE
*
*********************************************************************



*********************************************************************
*
         LEMENTRY BASE=BASE,LENGTH=DSA_DSECT_LENGTH,PARAM=API TRACE=0
*
* note:
*        API -> API_DSECT
*        DSA -> DSA_DSECT
*
***********************************************************************


         LEMTRACE 0,'I255604: entry'


***********************************************************************
*
*        get GLOBAL storage (GWA)
         L     GWA,API_GWA         get pointer to GWA
*
*        get TASK storage (TIE)
         L     TIE,API_TIE         get pointer to TIE
*
***********************************************************************








***********************************************************************
*
*        SETSOCKOPT - set options for server socket
*
*        We are going to use the SO_LINGER option.
*        This option enables us to specify how long TCP will linger
*        on the server socket after CLOSE.
*        "LINGER" means that the socket will remain in use for a
*        certain period of time after the CLOSE.
*
*        If we don't set a LINGER time then TCP will assume a long
*        LINGER time during which the server socket will remain
*        "in use" for about two minutes after the CLOSE.
*        If this server program is restarted within these two minutes
*        then it would get an error code 48 ("socket in use") when it
*        attempts to BIND the same socket again.
*
*        Since this program does not send data over the server socket
*        there is no need for TCP to linger after CLOSE. Therefore,
*        we will set the linger time to 1 second, which is the shortest
*        time that can be specified.
*        (We can not specify 0 seconds because 0 means "use default")
*
*
A100     EQU   *
         LEMTRACE 0,'I255604: SETSOCKOPT'
*
*        set OPTLEN - length of LINGER value
         MVC   DSA_OPTLEN,=F'8'                length of LINGER value
*
*        set OPTVAL - LINGER value
         MVC   DSA_OPTVAL_ONOFF,=F'1'          enable LINGER time
         MVC   DSA_OPTVAL_LINGER,=F'1'         linger for 1 seconds
*
         EZASMI TYPE=SETSOCKOPT,                                       X
               TASK=(TIE),                 TASK storage (TIE)          X
               S=API_SERVER_SOCKET,        server socket               X
               OPTNAME='SO_LINGER',        set LINGER value            X
               OPTLEN=DSA_OPTLEN,          length of LINGER value      X
               OPTVAL=DSA_OPTVAL,          LINGER value                X
               RETCODE=DSA_RETCODE,   -1 (error) or 0 (successful)     X
               ERRNO=DSA_ERRNO,       error number (if RETCODE = -1)   X
               ERROR=A110             if API error occurs
         B     A120
*
*......................................................................
*
*        SETSOCKOPT failed (ERROR exit)
A110     EQU   *
         LEMTRACE 0,'I255604: SETSOCKOPT failed - ERROR exit'
         B     A190
*
*......................................................................
*
*        if DSA_RETCODE is -1 then DSA_ERRNO contains the error code
A120     EQU   *
*
         L    R15,DSA_RETCODE    R15 = RETCODE
         C    R15,=F'-1'         RETCODE = -1?
         BNE  A130               no; successful
*
*......................................................................
*
*      unsuccessful
*      DSA_ERRNO contains the error code
       LEMTRACE 0,'I255604: SETSOCKOPT failed - ERRNO=',(DSA_ERRNO,4,B)
       B     A190
*
*......................................................................
*
*        successful
A130     EQU   *
         LEMTRACE 0,'I255604: SETSOCKOPT successful'
*
*......................................................................
*
A190     EQU   *
*
***********************************************************************









***********************************************************************
*
*        BIND server socket to the port
*
B100     EQU   *
         LEMTRACE 0,'I255604: BIND'
*
*        initialize BIND parameters (socket address structur)
         MVC   DSA_NAME_FAMILY,=H'2'           FAMILY=2 (TCP)
         MVC   DSA_NAME_PORT,API_BIND_PORT     PORT
         MVC   DSA_NAME_IP,API_BIND_IP         IP-address
         MVC   DSA_NAME_RESERVED,=D'0'         reserved but not used
*
         EZASMI TYPE=BIND,                                             X
               TASK=(TIE),                 TASK storage (TIE)          X
               S=API_SERVER_SOCKET,        server socket               X
               NAME=DSA_NAME,              port and IP-address         X
               RETCODE=DSA_RETCODE,   -1 (error) or 0 (successful)     X
               ERRNO=DSA_ERRNO,       error number (if RETCODE = -1)   X
               ERROR=B110             if API error occurs
         B     B120
*
*......................................................................
*
*        BIND failed (ERROR exit)
B110     EQU   *
         LEMTRACE 0,'I255604: BIND failed - ERROR exit'
         B     X100
*
*......................................................................
*
*        if DSA_RETCODE is -1 then DSA_ERRNO contains the error code
B120     EQU   *
*
         L    R15,DSA_RETCODE    R15 = RETCODE
         C    R15,=F'-1'         RETCODE = -1?
         BNE  B130               no; successful
*
*......................................................................
*
*        unsuccessful
*        DSA_ERRNO contains the error code
         LEMTRACE 0,'I255604: BIND failed - ERRNO=',(DSA_ERRNO,4,B)
         B     X100
*
*......................................................................
*
*        successful
B130     EQU   *
         LEMTRACE 0,'I255604: BIND successful'
*
***********************************************************************






***********************************************************************
*
*        GETSOCKNAME to discover port
*
C100     EQU   *
         LEMTRACE 0,'I255604: GETSOCKNAME'
*
         EZASMI TYPE=GETSOCKNAME,                                      X
               TASK=(TIE),                 TASK storage (TIE)          X
               S=API_SERVER_SOCKET,        server socket               X
               NAME=DSA_NAME,              port and IP-address         X
               RETCODE=DSA_RETCODE,   -1 (error) or 0 (successful)     X
               ERRNO=DSA_ERRNO,       error number (if RETCODE = -1)   X
               ERROR=C110             if API error occurs
         B     C120
*
*......................................................................
*
*        BIND failed (ERROR exit)
C110     EQU   *
         LEMTRACE 0,'I255604: GETSOCKNAME failed - ERROR exit'
         B     X100
*
*......................................................................
*
*        if DSA_RETCODE is -1 then DSA_ERRNO contains the error code
C120     EQU   *
*
         L    R15,DSA_RETCODE    R15 = RETCODE
         C    R15,=F'-1'         RETCODE = -1?
         BNE  C130               no; successful
*
*......................................................................
*
*        unsuccessful
*        DSA_ERRNO contains the error code
      LEMTRACE 0,'I255604: GETSOCKNAME failed - ERRNO=',(DSA_ERRNO,4,B)
         B     X100
*
*......................................................................
*
*        successful
C130     EQU   *
         LEMTRACE 0,'I255604: GETSOCKNAME successful'
*
*        TRACE
****     LEMTRACE 0,'I255604: BIND=',(DSA_NAME,16,X)
         LEMTRACE 0,'I255604: PORT=',(DSA_NAME_PORT,2,B)
*
*        copy IP-address and port number to API
         MVC   API_BOUND_IP,DSA_NAME_IP
         MVC   API_BOUND_PORT,DSA_NAME_PORT
*
***********************************************************************





***********************************************************************
*
*        LISTEN - create connection queue
*
D100     EQU   *
         LEMTRACE 0,'I255604: LISTEN'
*
         EZASMI TYPE=LISTEN,                                           X
               TASK=(TIE),            TASK storage (TIE)               X
               S=API_SERVER_SOCKET,   server socket                    X
               BACKLOG=API_BACKLOG,   backlog incoming connections     X
               RETCODE=DSA_RETCODE,   -1 (error) or 0 (successful)     X
               ERRNO=DSA_ERRNO,       error number (if RETCODE = -1)   X
               ERROR=D110             if API error occurs
         B     D120
*
*......................................................................
*
*        LISTEN failed (ERROR exit)
D110     EQU   *
         LEMTRACE 0,'I255604: LISTEN failed - ERROR exit'
         B     X100
*
*......................................................................
*
*        if DSA_RETCODE is -1 then DSA_ERRNO contains the error code
D120     EQU   *
*
         L    R15,DSA_RETCODE    R15 = RETCODE
         C    R15,=F'-1'         RETCODE = -1?
         BNE  D130               no; successful
*
*......................................................................
*
*        unsuccessful
*        DSA_ERRNO contains the error code
         LEMTRACE 0,'I255604: LISTEN failed - ERRNO=',(DSA_ERRNO,4,B)
         B     X100
*
*......................................................................
*
*        successful
D130     EQU   *
         LEMTRACE 0,'I255604: LISTEN successful'
*
***********************************************************************







***********************************************************************
*
*        call I255605 passing API
*
         LR    R1,API
         L     R15,=V(I255605)
         BASR  R14,R15
*
***********************************************************************







**********************************************************************
*
*        return to caller
X100     EQU *
         LEMTRACE 0,'I255604: exit'
         LEMEXIT
*
*********************************************************************




**********************************************************************
*
*  GWA   Global Work Area
*
GWA_DSECT EZASMI TYPE=GLOBAL,STORAGE=DSECT
*
*********************************************************************





**********************************************************************
*
*  TIE   Task Work Area
*
TIE_DSECT EZASMI TYPE=TASK,STORAGE=DSECT
*
*********************************************************************




***********************************************************************
*
* DSA - Dynamic Storage Area (pointed to by register 13)
*
DSA_DSECT     LEMDSA
*
*......................................................................
*
DSA_RETCODE       DS   F     return code
*                            0 = successful
*                           -1 = check ERRNO for error code
*
DSA_ERRNO         DS   F     error code (only if RETCODE=-1)
*
*......................................................................
*
* the following fields are used by SETSOCKOPT:
*
DSA_OPTLEN        DS   F        length of OPTVAL (8)
*
DSA_OPTVAL        DS   0F       OPTVAL (LINGER value)
DSA_OPTVAL_ONOFF  DS   F        nonzero value means ON
DSA_OPTVAL_LINGER DS   F        linger time (1 second)
*
*......................................................................
*
* the following fields are used by BIND:
*
DSA_NAME          DS   0XL16
DSA_NAME_FAMILY   DS   H        FAMILY=2 (TCP)
DSA_NAME_PORT     DS   H        PORT number
DSA_NAME_IP       DS   F        IP_ADDRESS=0.0.0.0 (any)
DSA_NAME_RESERVED DS   XL8      reserved but not used
*
*......................................................................
*
              DS   0D   D-align what follows
DSA_DSECT_LENGTH EQU  *-DSA_DSECT
*
***********************************************************************
*
* API - parameters passed between modules
* this dsect is address via register API
*
API_DSECT       DSECT
*
* following fields are set by I25560:
API_BIND_IP     DS  XL4  IP-address to listen on (0.0.0.0 means "any")
API_BIND_PORT   DS  H    port number to listen on (0 means "any")
API_MAXSOC      DS  H    maximum number of sockets          for INITAPI
API_BACKLOG     DS  F    backlog queue incoming connections  for LISTEN
*
*......................................................................
*
* following fields are set by I255601:
API_GWA         DS  A    pointer to GLOBAL storage for EZASMI macro
API_TIE         DS  A    pointer to TASK   storage for EZASMI macro
API_MAXSNO      DS  H    highest socket number             from INITAPI
                DS  H    unused
*
*......................................................................
*
* following fields are set by I255602:
API_LOCAL_IP    DS  XL4  IP-address of server            from GETHOSTID
API_LOCAL_NAME  DS  CL26 local hostname (LL-string)    from GETHOSTNAME
*
*......................................................................
*
* following fields are set by I255603:
API_SERVER_SOCKET DS  H    server socket number             from SOCKET
*
*......................................................................
*
* following fields are set by I255604:
API_BOUND_IP     DS  XL4  IP-address of server       from GETSOCKETNAME
API_BOUND_PORT   DS  H    port bound to server       from GETSOCKETNAME
*
***********************************************************************
        END