Add safe connect, fix possible seg fault in RTC
[ric-plt/lib/rmr.git] / test / test_transport_em.c
1 /*
2 ==================================================================================
3         Copyright (c) 2020 Nokia
4         Copyright (c) 2020 AT&T Intellectual Property.
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10            http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 /*
21         Mnemonic:       test_transport.c
22         Abstract:       This supplies a bunch of dummy system functions which emulate
23                                 things like connect() bind() etc.
24
25                                 This module must be directly included to be used.
26         Date:           17 April 2020
27         Author:         E. Scott Daniels
28 */
29
30 #ifndef _test_transport_c
31 #define _sitransport_h                  // prevent the transport defs when including SI95
32
33
34 char    tpem_last_addr[1024];           // last address to simulate connection to ourself
35 int             tpem_last_len = 0;
36
37 int tpem_addr_dup = 0;                  // getsockname duplicates last addr if true
38 int tpem_conn_state = 0;                // states returned by emulated functions allowing failures to be driven
39 int tpem_sock_state = 0;
40 int tpem_listen_state = 0;
41 int tpem_bind_state = 0;
42
43 // ------------ emulation control -------------------------------------------
44
45 /*
46         All test prog to set various things
47 */
48 static void tpem_set_conn_state( int s ) {
49         tpem_conn_state = s;
50 }
51
52 static void tpem_set_addr_dup_state( int s ) {
53         tpem_addr_dup = s;
54 }
55
56 static void tpem_set_sock_state( int s ) {
57         tpem_sock_state = s;
58 }
59
60 static void tpem_set_bind_state( int s ) {
61         tpem_bind_state = s;
62 }
63
64 // ---- emulated functions ---------------------------------------------------
65
66 static int tpem_bind( int socket, struct sockaddr* addr, socklen_t alen ) {
67         return tpem_bind_state;
68 }
69
70 static int tpem_connect( int socket, struct sockaddr* addr, socklen_t alen ) {
71         memcpy( tpem_last_addr, addr, alen );
72         tpem_last_len = alen;
73         fprintf( stderr, "<SYSEM> connection simulated rc=%d\n", tpem_conn_state );
74         return tpem_conn_state;
75 }
76
77 /*
78         This gets the last address connected to if dup is true; else returns 0s
79         which should be enough to test that connection didn't loop back to us.
80 */
81 static int tpem_getsockname( int socket, struct sockaddr* address, socklen_t* alen ) {
82         int clen;               // copy len
83
84         if( tpem_last_len > 0 ) {
85                 clen = tpem_last_len > *alen ? *alen : tpem_last_len;
86                 if( tpem_addr_dup ) {
87                         memcpy( address, tpem_last_addr, clen );
88                 } else {
89                         memset( address, 0, clen );
90                 }
91                 *alen = clen;
92         } else {
93                 memset( address, 0, *alen );
94         }
95
96         return 0;
97 }
98
99 static int tpem_listen( int socket, int backlog ) {
100         return tpem_listen_state;
101 }
102
103 static int tpem_socket( int domain, int type, int protocol ) {
104         static int fd = 1;
105
106         if( tpem_sock_state == 0 ) {
107                 if( ++fd > 10 ) {
108                         fd = 1;
109                 }
110
111                 return fd;
112         }
113
114         return -1;
115 }
116
117 /*
118         redefine all system calls to reference functions here. There are two defs
119         SI functions should use the capitalised verision so that sliding ff under
120         it is possible. There might be instances wehre the actual system call is
121         needed, so we also define the lowercase value.
122 */
123 #define BIND tpem_bind
124 #define bind tpem_bind
125 #define CONNECT tpem_connect
126 #define connect tpem_connect
127 #define getsockname tpem_getsockname
128 #define SOCKET tpem_socket
129 #define socket tpem_socket
130 #define LISTEN tpem_listen
131 #define listen tpem_listen
132
133 /*
134         these are defined in SI so that we can use the system stack or FFstack
135         they must exist and reference system calls if not defined above.
136 */
137 #define ACCEPT          accept
138 #define CLOSE           close
139 #define SHUTDOWN        shutdown
140 #define GETSOCKOPT      getscokopt
141 #define SETSOCKOPT      setsockopt
142 #define READ            read
143 #define WRITE           write
144 #define SEND            send
145 #define SENDTO          sendto
146 #define RECV            recv
147 #define RECVFROM        recvfrom
148 #define RECVMSG         recvmsg
149
150
151
152 #endif
153