8665892ddd6d9ac97b183e62e80fede384a90884
[ric-plt/lib/rmr.git] / src / rmr / si / src / si95 / sinewses.c
1 // vim: noet sw=4 ts=4:
2 /*
3 ==================================================================================
4     Copyright (c) 2020 Nokia
5     Copyright (c) 2020 AT&T Intellectual Property.
6
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
10
11        http://www.apache.org/licenses/LICENSE-2.0
12
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 ==================================================================================
19 */
20
21 /*
22 *****************************************************************************
23 *
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.
34 *  Date:     26 March 1995
35 *  Author:   E. Scott Daniels
36 *
37 ******************************************************************************
38 */
39 #include "sisetup.h"          //  get necessary defs etc
40 #include "sitransport.h"
41 #include <netinet/tcp.h>
42
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
51         int optval;
52
53         addr = (struct sockaddr *) malloc( sizeof( struct sockaddr ) );
54         addrlen = sizeof( struct sockaddr );
55         memset( addr, 0, sizeof( struct sockaddr ) );
56
57         status = accept( tpptr->fd, addr, &addrlen );   //  accept and assign new fd (status)
58         if( status < 0 ) {
59                 free( addr );
60                 return SI_ERROR;
61         }
62
63         newtp = SInew( TP_BLK );                              //  get a new tp block for the session
64         if( newtp == NULL ) {
65                 CLOSE( status );                                                // must disconnect the other side
66                 free( addr );
67                 return SI_ERROR;
68         }
69
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
73         }
74         gptr->tplist = newtp;
75         newtp->paddr = (struct sockaddr *) addr;        //  partner address
76         newtp->fd = status;                         //  save the fd from accept
77
78         if( gptr->tcp_flags & SI_TF_NODELAY ) {         // set on/off for no delay configuration
79                 optval = 1;
80         } else {
81                 optval = 0;
82         }
83         SETSOCKOPT( tpptr->fd, SOL_TCP, TCP_NODELAY, (void *)&optval, sizeof( optval) );
84
85         if( gptr->tcp_flags & SI_TF_FASTACK ) {         // set on/off for fast ack config
86                 optval = 1;
87         } else {
88                 optval = 0;
89         }
90         SETSOCKOPT( tpptr->fd, SOL_TCP, TCP_QUICKACK, (void *)&optval, sizeof( optval) ) ;
91
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
98                         free( buf );
99                         return SI_ERROR;
100                 } else {
101                         SIcbstat( gptr, status, SI_CB_SECURITY );               //  allow for unreg or shutdown signal
102                 }
103         }
104
105         newtp->flags |= TPF_SESSION;     //  indicate a session here
106
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
110         }
111
112         SImap_fd( gptr, newtp->fd, newtp );             // add fd to the map
113
114         free( buf );
115         return SI_OK;
116 }
117