blob: ce9d6498ceeee497f0babd3b9ec8612c1de6251f [file] [log] [blame]
Harry Tran1f1098a2020-03-10 10:40:10 -04001/*****************************************************************************
2# *
3# Copyright 2019 AT&T Intellectual Property *
4# Copyright 2019 Nokia *
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#include <stdio.h>
20#include <string.h>
21#include <unistd.h> //for close()
22#include <stdlib.h>
23#include <sys/socket.h>
24#include <netinet/in.h>
25#include <netinet/sctp.h>
26#include <arpa/inet.h> //for inet_ntop()
27#include <assert.h>
28
29#include "e2sim_sctp.hpp"
30// #include "e2sim_defs.h"
31
32
33#include <sys/types.h>
34#include <sys/socket.h>
35#include <netinet/sctp.h>
36#include <signal.h>
37#include <unistd.h>
38#include <string.h>
39#include <stdio.h>
40#include <stdlib.h>
41
42int sctp_start_server(const char *server_ip_str, const int server_port)
43{
44 if(server_port < 1 || server_port > 65535) {
45 LOG_E("Invalid port number (%d). Valid values are between 1 and 65535.\n", server_port);
46 exit(1);
47 }
48
49 int server_fd, af;
50 struct sockaddr* server_addr;
51 size_t addr_len;
52
53 struct sockaddr_in server4_addr;
54 memset(&server4_addr, 0, sizeof(struct sockaddr_in));
55
56 struct sockaddr_in6 server6_addr;
57 memset(&server6_addr, 0, sizeof(struct sockaddr_in6));
58
59 if(inet_pton(AF_INET, server_ip_str, &server4_addr.sin_addr) == 1)
60 {
61 server4_addr.sin_family = AF_INET;
62 server4_addr.sin_port = htons(server_port);
63
64 server_addr = (struct sockaddr*)&server4_addr;
65 af = AF_INET;
66 addr_len = sizeof(server4_addr);
67 }
68 else if(inet_pton(AF_INET6, server_ip_str, &server6_addr.sin6_addr) == 1)
69 {
70 server6_addr.sin6_family = AF_INET6;
71 server6_addr.sin6_port = htons(server_port);
72
73 server_addr = (struct sockaddr*)&server6_addr;
74 af = AF_INET6;
75 addr_len = sizeof(server6_addr);
76 }
77 else {
78 perror("inet_pton()");
79 exit(1);
80 }
81
82 if((server_fd = socket(af, SOCK_STREAM, IPPROTO_SCTP)) == -1) {
83 perror("socket");
84 exit(1);
85 }
86
87 //set send_buffer
88 // int sendbuff = 10000;
89 // socklen_t optlen = sizeof(sendbuff);
90 // if(getsockopt(server_fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen) == -1) {
91 // perror("getsockopt send");
92 // exit(1);
93 // }
94 // else
95 // LOG_D("[SCTP] send buffer size = %d\n", sendbuff);
96
97
98 if(bind(server_fd, server_addr, addr_len) == -1) {
99 perror("bind");
100 exit(1);
101 }
102
103 if(listen(server_fd, SERVER_LISTEN_QUEUE_SIZE) != 0) {
104 perror("listen");
105 exit(1);
106 }
107
108 assert(server_fd != 0);
109
110 LOG_I("[SCTP] Server started on %s:%d", server_ip_str, server_port);
111
112 return server_fd;
113}
114
115int sctp_start_client(const char *server_ip_str, const int server_port)
116{
117 int client_fd, af;
118
119 struct sockaddr* server_addr;
120 size_t addr_len;
121
122 struct sockaddr_in server4_addr;
123 memset(&server4_addr, 0, sizeof(struct sockaddr_in));
124
125 struct sockaddr_in6 server6_addr;
126 memset(&server6_addr, 0, sizeof(struct sockaddr_in6));
127
128 if(inet_pton(AF_INET, server_ip_str, &server4_addr.sin_addr) == 1)
129 {
130 server4_addr.sin_family = AF_INET;
131 server4_addr.sin_port = htons(server_port);
132 server_addr = (struct sockaddr*)&server4_addr;
133 addr_len = sizeof(server4_addr);
134 }
135 else if(inet_pton(AF_INET6, server_ip_str, &server6_addr.sin6_addr) == 1)
136 {
137 server6_addr.sin6_family = AF_INET6;
138 server6_addr.sin6_port = htons(server_port);
139 server_addr = (struct sockaddr*)&server6_addr;
140 addr_len = sizeof(server6_addr);
141 }
142 else {
143 perror("inet_pton()");
144 exit(1);
145 }
146
147 if((client_fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) == -1)
148 {
149 perror("socket");
150 exit(1);
151 }
152
153 // int sendbuff = 10000;
154 // socklen_t optlen = sizeof(sendbuff);
155 // if(getsockopt(client_fd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen) == -1) {
156 // perror("getsockopt send");
157 // exit(1);
158 // }
159 // else
160 // LOG_D("[SCTP] send buffer size = %d\n", sendbuff);
161
162 //--------------------------------
163 //Bind before connect
164 auto optval = 1;
165 if( setsockopt(client_fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof optval) != 0 ){
166 perror("setsockopt port");
167 exit(1);
168 }
169
170 if( setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval) != 0 ){
171 perror("setsockopt addr");
172 exit(1);
173 }
174
175 struct sockaddr_in6 client6_addr {};
176 client6_addr.sin6_family = AF_INET6;
177 client6_addr.sin6_port = htons(RIC_SCTP_SRC_PORT);
178 client6_addr.sin6_addr = in6addr_any;
179
180 LOG_I("[SCTP] Binding client socket to source port %d", RIC_SCTP_SRC_PORT);
181 if(bind(client_fd, (struct sockaddr*)&client6_addr, sizeof(client6_addr)) == -1) {
182 perror("bind");
183 exit(1);
184 }
185 // end binding ---------------------
186
187 LOG_I("[SCTP] Connecting to server at %s:%d ...", server_ip_str, server_port);
188 if(connect(client_fd, server_addr, addr_len) == -1) {
189 perror("connect");
190 exit(1);
191 }
192 assert(client_fd != 0);
193
194 LOG_I("[SCTP] Connection established");
195
196 return client_fd;
197}
198
199int sctp_accept_connection(const char *server_ip_str, const int server_fd)
200{
201 LOG_I("[SCTP] Waiting for new connection...");
202
203 struct sockaddr client_addr;
204 socklen_t client_addr_size;
205 int client_fd;
206
207 //Blocking call
208 client_fd = accept(server_fd, &client_addr, &client_addr_size);
Ron Shachama9733db2020-09-14 12:05:31 -0400209 fprintf(stderr, "client fd is %d\n", client_fd);
Harry Tran1f1098a2020-03-10 10:40:10 -0400210 if(client_fd == -1){
211 perror("accept()");
212 close(client_fd);
213 exit(1);
214 }
215
216 //Retrieve client IP_ADDR
217 char client_ip6_addr[INET6_ADDRSTRLEN], client_ip4_addr[INET_ADDRSTRLEN];
218 if(strchr(server_ip_str, ':') != NULL) //IPv6
219 {
220 struct sockaddr_in6* client_ipv6 = (struct sockaddr_in6*)&client_addr;
221 inet_ntop(AF_INET6, &(client_ipv6->sin6_addr), client_ip6_addr, INET6_ADDRSTRLEN);
222 LOG_I("[SCTP] New client connected from %s", client_ip6_addr);
223 }
224 else {
225 struct sockaddr_in* client_ipv4 = (struct sockaddr_in*)&client_addr;
226 inet_ntop(AF_INET, &(client_ipv4->sin_addr), client_ip4_addr, INET_ADDRSTRLEN);
227 LOG_I("[SCTP] New client connected from %s", client_ip4_addr);
228 }
229
230 return client_fd;
231}
232
233int sctp_send_data(int &socket_fd, sctp_buffer_t &data)
234{
Ron Shachama9733db2020-09-14 12:05:31 -0400235 fprintf(stderr,"in sctp send data func\n");
236 fprintf(stderr,"data.len is %d", data.len);
Harry Tran1f1098a2020-03-10 10:40:10 -0400237 int sent_len = send(socket_fd, (void*)(&(data.buffer[0])), data.len, 0);
Ron Shachama9733db2020-09-14 12:05:31 -0400238 fprintf(stderr,"after getting sent_len\n");
Harry Tran1f1098a2020-03-10 10:40:10 -0400239
240 if(sent_len == -1) {
241 perror("[SCTP] sctp_send_data");
242 exit(1);
243 }
244
245 return sent_len;
246}
247
248int sctp_send_data_X2AP(int &socket_fd, sctp_buffer_t &data)
249{
Ron Shachama9733db2020-09-14 12:05:31 -0400250 /*
Harry Tran1f1098a2020-03-10 10:40:10 -0400251 int sent_len = sctp_sendmsg(socket_fd, (void*)(&(data.buffer[0])), data.len,
252 NULL, 0, (uint32_t) X2AP_PPID, 0, 0, 0, 0);
253
254 if(sent_len == -1) {
255 perror("[SCTP] sctp_send_data");
256 exit(1);
257 }
Ron Shachama9733db2020-09-14 12:05:31 -0400258 */
259 return 1;
Harry Tran1f1098a2020-03-10 10:40:10 -0400260}
261
262/*
263Receive data from SCTP socket
264Outcome of recv()
265-1: exit the program
2660: close the connection
267+: new data
268*/
269int sctp_receive_data(int &socket_fd, sctp_buffer_t &data)
270{
271 //clear out the data before receiving
Ron Shachama9733db2020-09-14 12:05:31 -0400272 fprintf(stderr, "receive data1\n");
Harry Tran1f1098a2020-03-10 10:40:10 -0400273 memset(data.buffer, 0, sizeof(data.buffer));
Ron Shachama9733db2020-09-14 12:05:31 -0400274 fprintf(stderr, "receive data2\n");
Harry Tran1f1098a2020-03-10 10:40:10 -0400275 data.len = 0;
276
277 //receive data from the socket
278 int recv_len = recv(socket_fd, &(data.buffer), sizeof(data.buffer), 0);
Ron Shachama9733db2020-09-14 12:05:31 -0400279 fprintf(stderr, "receive data3\n");
280
Harry Tran1f1098a2020-03-10 10:40:10 -0400281 if(recv_len == -1)
282 {
283 perror("[SCTP] recv");
284 exit(1);
285 }
286 else if (recv_len == 0)
287 {
288 LOG_I("[SCTP] Connection closed by remote peer");
289 if(close(socket_fd) == -1)
290 {
291 perror("[SCTP] close");
292 }
293 return -1;
294 }
295
296 data.len = recv_len;
297
298 return recv_len;
299}