e7fd7b3e7f0f88d508b8736bb3430ca90350091e
[ric-plt/lib/rmr.git] / src / rmr / si / src / si95 / siconnect.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:    SIconnect
25 *  Abstract:    Start a TCP/IP session with another process.
26 *  Parms:    
27 *               addr - Pointer to a string containing the process' address
28 *                               The address is either ipv4 or ipv6 formmat with the
29 *                               port number separated with a semicolon (::1;4444,
30 *                               localhost;4444 climber;4444 129.168.0.4;4444).
31 *  Returns:     The session number if all goes well, SI_ERROR if not.
32 *
33 *  Date:                March 1995
34 *  Author:              E. Scott Daniels
35 *
36 *  Mod:         08 Mar 2007 - conversion of sorts to support ipv6
37 ******************************************************************************
38 */
39 #include "sisetup.h"
40 #include "sitransport.h"
41
42 /*
43         Accept a file descriptor and add it to the map.
44 */
45 extern void SImap_fd( struct ginfo_blk *gptr, int fd, struct tp_blk* tpptr ) {
46         if( fd < MAX_FDS ) {
47                 gptr->tp_map[fd] = tpptr;
48         } else {
49                 fprintf( stderr, "[WRN] fd on connected session is out of range: %d\n", fd );
50         }
51 }
52
53 extern int SIconnect( struct ginfo_blk *gptr, char *abuf ) {
54         int status;
55         struct tp_blk *tpptr;           //  pointer to new block 
56         struct sockaddr *taddr;         // convenience pointer to addr of target
57         int alen = 0;                                   //  len of address struct 
58         int fd = SI_ERROR;              //  file descriptor to return to caller 
59
60         if( PARINOID_CHECKS ) {
61                 if( gptr == NULL ) {
62                         return SI_ERROR;
63                 }
64
65                 gptr->sierr = SI_ERR_HANDLE;
66                 if( gptr->magicnum != MAGICNUM ) {              // no cookie -- no connection
67                         return SI_ERROR;
68                 }
69         }
70
71         gptr->sierr = SI_ERR_TPORT;
72         tpptr = SIconn_prep( gptr, TCP_DEVICE, abuf, 0 );                       // create tp struct, and socket. get peer address 0 == any family that suits the addr
73         if( tpptr != NULL ) {
74                 taddr = tpptr->paddr;
75                 gptr->sierr = SI_ERR_TP;
76                 errno = 0;
77                 if( connect( tpptr->fd, taddr, tpptr->palen ) != 0 ) {
78                         close( tpptr->fd );                             //  clean up fd and tp_block 
79                         SItrash( TP_BLK, tpptr );               //  free the trasnsport block 
80                         fd = SI_ERROR;                                  //  send bad session id num back 
81                 } else  {                                       //  connect ok 
82                         gptr->sierr = 0;
83                         tpptr->flags |= TPF_SESSION;                    //  indicate we have a session here 
84                         tpptr->next = gptr->tplist;                     //  add block to the list 
85                         if( tpptr->next != NULL ) {
86                                 tpptr->next->prev = tpptr;              //  if there - point back at new 
87                         }
88
89                         gptr->tplist = tpptr;                           //  point at new head 
90                         fd = tpptr->fd;                                 //  save for return value 
91                         SImap_fd( gptr, fd, tpptr );
92                 }
93         }
94
95         return fd;                    
96 }