* 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;
}
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
}
}
*/
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;
}
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;
}
}
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
}
}