56d9b105f0e81fd654ef129c99ab6775c7e4251a
[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
56         status = accept( tpptr->fd, addr, &addrlen );   //  accept and assign new fd (status)
57         if( status < 0 ) {
58                 free( addr );
59                 return SI_ERROR;
60         }
61
62         newtp = SInew( TP_BLK );                              //  get a new tp block for the session
63         if( newtp == NULL ) {
64                 CLOSE( status );                                                // must disconnect the other side
65                 free( addr );
66                 return SI_ERROR;
67         }
68
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
72         }
73         gptr->tplist = newtp;
74         newtp->paddr = (struct sockaddr *) addr;        //  partner address
75         newtp->fd = status;                         //  save the fd from accept
76
77         if( gptr->tcp_flags & SI_TF_NODELAY ) {         // set on/off for no delay configuration
78                 optval = 1;
79         } else {
80                 optval = 0;
81         }
82         SETSOCKOPT( tpptr->fd, SOL_TCP, TCP_NODELAY, (void *)&optval, sizeof( optval) );
83
84         if( gptr->tcp_flags & SI_TF_FASTACK ) {         // set on/off for fast ack config
85                 optval = 1;
86         } else {
87                 optval = 0;
88         }
89         SETSOCKOPT( tpptr->fd, SOL_TCP, TCP_QUICKACK, (void *)&optval, sizeof( optval) ) ;
90
91         SIaddress( addr, (void **) &buf, AC_TODOT );                                                    // get addr of remote side; buf must be freed
92         if( (cbptr = gptr->cbtab[SI_CB_SECURITY].cbrtn) != NULL ) {                             //   invoke the security callback function if there
93                 status = (*cbptr)( gptr->cbtab[SI_CB_SECURITY].cbdata, buf );
94                 if( status == SI_RET_ERROR ) {                                                                          //  session to be rejected
95                         SIterm( gptr, newtp );                                                                                  //  terminate new tp block (do NOT call trash)
96                         free( addr );
97                         free( buf );
98                         return SI_ERROR;
99                 } else {
100                         SIcbstat( gptr, status, SI_CB_SECURITY );               //  allow for unreg or shutdown signal
101                 }
102         }
103
104         newtp->flags |= TPF_SESSION;     //  indicate a session here
105
106         if( (cbptr = gptr->cbtab[SI_CB_CONN].cbrtn) != NULL ) {         // drive connection callback
107                 status=(*cbptr)( gptr->cbtab[SI_CB_CONN].cbdata, newtp->fd, buf );
108                 SIcbstat(  gptr, status, SI_CB_CONN );               //  handle status
109         }
110
111         SImap_fd( gptr, newtp->fd, newtp );             // add fd to the map
112
113         free( buf );
114         return SI_OK;
115 }
116