fixing RMR messages with negative size
[ric-plt/lib/rmr.git] / src / rmr / si / src / si95 / siestablish.c
index 49e484d..f2bb752 100644 (file)
 * Mnemonic:            SIestablish
 * Abstract:i   Prep functions that set up a socket for listening or making a
 *                              connection.
-* Date:        26 March 1995
-* Author:      E. Scott Daniels
+* Date:                        26 March 1995
+* Author:              E. Scott Daniels
 *
-* Modified:    19 Apr 1995 - To keep returned address of the port.
+* Modified:    19 Apr 1995 - To keep returned address of the port.
 *                              08 Mar 2007 - conversion for ipv6.
 *                              12 Oct 2020 - split into connect prep and listen prep
 *                                                              functions.
        Family is one of the AF_* constants (AF_ANY, AF_INET or AF_INET6)
 
        The address should be one of these forms:
-                       [::1]:port                      // v6 localhost device (loop back)
-                       localhost:port          // v4 or 6 loopback depending on /etc/hosts
-                       0.0.0.0:port            // any interface
-                       addr:port                       // an address assigned to one of the devices
+                       [::1]:port                         v6 localhost device (loop back)
+                       localhost:port             v4 or 6 loopback depending on /etc/hosts
+                       0.0.0.0:port               any interface
+                       addr:port                          an address assigned to one of the devices
 
        Returns a transport struct which is the main context for the listener.
 */
-extern struct tp_blk *SIlisten_prep( struct ginfo_blk *gptr, int type, char* abuf, int family ) {
-       struct tp_blk *tptr;         //  pointer at new tp block
-       int status = SI_OK;             //  processing status
-       struct sockaddr *addr;          //  IP address we are requesting
-       int protocol;                //  protocol for socket call
-       char buf[256];               //  buffer to build request address in
+extern struct tp_blk *SIlisten_prep( int type, char* abuf, int family ) {
+       struct tp_blk *tptr;        //  pointer at new tp block
+       struct sockaddr *addr;          //  IP address we are requesting
        int optval = 0;
        int alen = 0;
+       int status = SI_OK;          //  processing status
+       int protocol;                //  protocol for socket call
 
-       tptr = (struct tp_blk *) SInew( TP_BLK );     //  new transport info block
+       tptr = (struct tp_blk *) SInew( TP_BLK );     // transport info
 
-       if( tptr != NULL )
-       {
+       if( tptr != NULL ) {
                addr = NULL;
 
-               switch( type )                  //  things specifc to tcp or udp
-               {
-                       case UDP_DEVICE:
-                               tptr->type = SOCK_DGRAM;
-                               protocol = IPPROTO_UDP;
-                               break;
-
-                       case TCP_DEVICE:
-                       default:
-                               tptr->type = SOCK_STREAM;
-                               protocol = IPPROTO_TCP;
+               if( type == UDP_DEVICE ) {
+                       tptr->type = SOCK_DGRAM;
+                       protocol = IPPROTO_UDP;
+               } else {
+                       tptr->type = SOCK_STREAM;
+                       protocol = IPPROTO_TCP;
                }
 
                alen = SIgenaddr( abuf, protocol, family, tptr->type, &addr );  //  family == 0 for type that suits the address passed in
                if( alen <= 0 ) {
+                       if( addr != NULL ) {
+                               free( addr );           // not needed, but scanners complain if we don't overtly do this
+                       }
+                       free( tptr );
                        return NULL;
                }
 
@@ -107,21 +104,21 @@ extern struct tp_blk *SIlisten_prep( struct ginfo_blk *gptr, int type, char* abu
 
                        status = BIND( tptr->fd, (struct sockaddr *) addr, alen );
                        if( status == SI_OK ) {
-                               tptr->addr = addr;              //  save address
+                               tptr->addr = addr;                      //  save address
                        } else {
-                               fprintf( stderr, ">>>>> siestablish: bind failed: fam=%d type=%d pro=%d %s\n", tptr->family, tptr->type, protocol, strerror( errno ) );
+                               fprintf( stderr, "<ERR> siestablish: bind failed: fam=%d type=%d pro=%d %s\n", tptr->family, tptr->type, protocol, strerror( errno ) );
                                close( tptr->fd );
                        }
                } else {
-                       status = ! SI_OK;                       //  force bad return later
-                       fprintf( stderr, ">>>>> siestablish: socket not esablished: fam=%d type=%d pro=%d %s\n", tptr->family, tptr->type, protocol, strerror( errno ) );
+                       status = ! SI_OK;                               //  force bad return later
+                       fprintf( stderr, "<ERR> siestablish: socket not esablished: fam=%d type=%d pro=%d %s\n", tptr->family, tptr->type, protocol, strerror( errno ) );
                }
 
-               if( status != SI_OK ) {                         //  socket or bind call failed - clean up stuff
-                       fprintf( stderr, ">>>>> siestablish: bad state -- returning nil pointer\n" );
+               if( status != SI_OK ) {                         //  socket or bind call failed - clean up stuff
+                       fprintf( stderr, "<ERR> siestablish: bad state -- returning nil pointer\n" );
                        free( addr );
                        SItrash( TP_BLK, tptr );        //  free the trasnsport block
-                       tptr = NULL;                    //  set to return nothing
+                       tptr = NULL;                            //  set to return nothing
                }
        }
 
@@ -163,7 +160,7 @@ static int need_smartc( char* abuf ) {
 */
 extern struct tp_blk *SIconn_prep( struct ginfo_blk *gptr, int type, char *abuf, int family ) {
        struct tp_blk *tptr;         //  pointer at new tp block
-       struct sockaddr *addr;          //  IP address we are requesting
+       struct sockaddr *addr;          //  IP address we are requesting
        int protocol;                //  protocol for socket call
        char buf[256];               //  buffer to build request address in
        int optval = 0;
@@ -189,10 +186,11 @@ extern struct tp_blk *SIconn_prep( struct ginfo_blk *gptr, int type, char *abuf,
                }
 
                alen = SIgenaddr( abuf, protocol, family, tptr->type, &addr );  //  family == 0 for type that suits the address passed in
-               if( alen <= 0 )
-               {
-                       //fprintf( stderr, ">>>>> siconn_prep: error generating an address struct for %s(abuf) %d(proto) %d(type): %s\n",
-                       //      abuf, protocol, tptr->type, strerror( errno ) );
+               if( alen <= 0 ) {
+                       if( addr != NULL ) {            // not needed, but scanners complain if we don't overtly do this
+                               free( addr );
+                       }
+                       free( tptr );
                        return NULL;
                }
 
@@ -216,13 +214,24 @@ extern struct tp_blk *SIconn_prep( struct ginfo_blk *gptr, int type, char *abuf,
                        }
                        SETSOCKOPT( tptr->fd, SOL_TCP, TCP_QUICKACK, (void *)&optval, sizeof( optval) ) ;
 
+                       if( gptr->tcp_flags & SI_TF_QUICK ) {
+                               optval = 1;
+                               SETSOCKOPT( tptr->fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, sizeof( optval) ) ;
+                               optval = 1;
+                               SETSOCKOPT( tptr->fd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&optval, sizeof( optval) ) ;
+                               optval = 1;
+                               SETSOCKOPT( tptr->fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&optval, sizeof( optval) ) ;
+                               optval = 5;
+                               SETSOCKOPT( tptr->fd, IPPROTO_TCP, TCP_KEEPCNT, (void *)&optval, sizeof( optval) ) ;
+                       }
+
                        tptr->paddr = addr;                             // tuck the remote peer address away
                        if( need_smartc( abuf ) ) {
                                tptr->flags |= TPF_SAFEC;
                        }
                } else {
                        free( addr );
-                       SItrash( TP_BLK, tptr );        // free the trasnsport block
+                       SItrash( TP_BLK, tptr );                // free the trasnsport block
                        tptr = NULL;                                    // we'll return nil
                }
        }