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 );
55 memset( addr, 0, sizeof( struct sockaddr ) );
57 status = accept( tpptr->fd, addr, &addrlen ); // accept and assign new fd (status)
63 newtp = SInew( TP_BLK ); // get a new tp block for the session
65 CLOSE( status ); // must disconnect the other side
70 newtp->next = gptr->tplist; // add new block to the head of the list
71 if( newtp->next != NULL ) {
72 newtp->next->prev = newtp; // back chain to us
75 newtp->paddr = (struct sockaddr *) addr; // partner address
76 newtp->fd = status; // save the fd from accept
78 if( gptr->tcp_flags & SI_TF_NODELAY ) { // set on/off for no delay configuration
83 SETSOCKOPT( tpptr->fd, SOL_TCP, TCP_NODELAY, (void *)&optval, sizeof( optval) );
85 if( gptr->tcp_flags & SI_TF_FASTACK ) { // set on/off for fast ack config
90 SETSOCKOPT( tpptr->fd, SOL_TCP, TCP_QUICKACK, (void *)&optval, sizeof( optval) ) ;
92 SIaddress( addr, (void **) &buf, AC_TODOT ); // get addr of remote side; buf must be freed
93 if( (cbptr = gptr->cbtab[SI_CB_SECURITY].cbrtn) != NULL ) { // invoke the security callback function if there
94 status = (*cbptr)( gptr->cbtab[SI_CB_SECURITY].cbdata, buf );
95 if( status == SI_RET_ERROR ) { // session to be rejected
96 SIterm( gptr, newtp ); // terminate new tp block (do NOT call trash)
97 // free( addr ); // not required, will be eventually freed by SItrash
101 SIcbstat( gptr, status, SI_CB_SECURITY ); // allow for unreg or shutdown signal
105 newtp->flags |= TPF_SESSION; // indicate a session here
107 if( (cbptr = gptr->cbtab[SI_CB_CONN].cbrtn) != NULL ) { // drive connection callback
108 status=(*cbptr)( gptr->cbtab[SI_CB_CONN].cbdata, newtp->fd, buf );
109 SIcbstat( gptr, status, SI_CB_CONN ); // handle status
112 SImap_fd( gptr, newtp->fd, newtp ); // add fd to the map