1 // vim: noet sw=4 ts=4:
3 ==================================================================================
4 Copyright (c) 2020 Nokia
5 Copyright (c) 2020 AT&T Intellectual Property.
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 ==================================================================================
22 *****************************************************************************
24 * Mnemonic: SInewsession
25 * Abstract: This routine can be called when a request for connection is
26 * received. It will establish a new fd, create a new
27 * transport provider block (added to the head of the list).
28 * The security callback and connection callback
29 * routines are driven from this routine.
30 * Parms: gptr - Pointer to the general information block
31 * tpptr- Pointer to the tp block that describes the fd that
32 * received the connection request (the listen tp block).
33 * Returns: SI_OK if all went well, SI_ERROR if not.
35 * Author: E. Scott Daniels
37 ******************************************************************************
39 #include "sisetup.h" // get necessary defs etc
40 #include "sitransport.h"
41 #include <netinet/tcp.h>
43 extern int SInewsession( struct ginfo_blk *gptr, struct tp_blk *tpptr ) {
44 struct sockaddr *addr; // pointer to address of caller
45 struct spxopt_s *sopts; // pointer to spx options
46 struct tp_blk *newtp; // pointer at new tp block
47 int status = SI_OK; // processing status
48 int (*cbptr)(); // pointer to callback function
49 unsigned int addrlen; // length of address from accept
50 char *buf = NULL; // pointer to address
53 addr = (struct sockaddr *) malloc( sizeof( struct sockaddr ) );
54 addrlen = sizeof( struct sockaddr );
56 status = accept( tpptr->fd, addr, &addrlen ); // accept and assign new fd (status)
62 newtp = SInew( TP_BLK ); // get a new tp block for the session
64 CLOSE( status ); // must disconnect the other side
69 newtp->next = gptr->tplist; // add new block to the head of the list
70 if( newtp->next != NULL ) {
71 newtp->next->prev = newtp; // back chain to us
74 newtp->paddr = (struct sockaddr *) addr; // partner address
75 newtp->fd = status; // save the fd from accept
76 //fprintf( stderr, ">>>>> newsession: accepted session on fd %d\n", status );
78 if( gptr->tcp_flags & SI_TF_NODELAY ) {
83 //fprintf( stderr, ">>>>> newsession: setting no delay = %d\n", optval );
84 SETSOCKOPT( tpptr->fd, SOL_TCP, TCP_NODELAY, (void *)&optval, sizeof( optval) ) ;
87 if( gptr->tcp_flags & SI_TF_FASTACK ) {
92 //fprintf( stderr, ">>>>> conn_prep: setting quick ack = %d\n", optval );
93 SETSOCKOPT( tpptr->fd, SOL_TCP, TCP_QUICKACK, (void *)&optval, sizeof( optval) ) ;
95 SIaddress( addr, (void **) &buf, AC_TODOT ); // get addr of remote side
96 if( (cbptr = gptr->cbtab[SI_CB_SECURITY].cbrtn) != NULL ) { // invoke the security callback function if there
97 status = (*cbptr)( gptr->cbtab[SI_CB_SECURITY].cbdata, buf );
98 if( status == SI_RET_ERROR ) { // session to be rejected
99 SIterm( gptr, newtp ); // terminate new tp block
100 SItrash( TP_BLK, newtp );
105 SIcbstat( gptr, status, SI_CB_SECURITY ); // allow for unreg or shutdown signal
109 newtp->flags |= TPF_SESSION; // indicate a session here
111 //fprintf( stderr, ">>>> pending connection callback for: %s\n", buf );
112 if( (cbptr = gptr->cbtab[SI_CB_CONN].cbrtn) != NULL ) { // drive connection callback
113 status=(*cbptr)( gptr->cbtab[SI_CB_CONN].cbdata, newtp->fd, buf );
114 SIcbstat( gptr, status, SI_CB_CONN ); // handle status
117 SImap_fd( gptr, newtp->fd, newtp ); // add fd to the map