Skip to content

Commit e1d5f40

Browse files
committed
Merge branch 'next' into agpl_next
2 parents 3defd1b + 3c17686 commit e1d5f40

File tree

10 files changed

+240
-108
lines changed

10 files changed

+240
-108
lines changed

lib/include/srsran/common/network_utils.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,14 @@ class unique_socket
8383
std::string get_ip() const { return net_utils::get_ip(addr); }
8484
net_utils::socket_type get_family() const { return net_utils::get_addr_family(sockfd); }
8585

86+
bool open_socket(net_utils::addr_family ip, net_utils::socket_type socket_type, net_utils::protocol_type protocol);
8687
bool bind_addr(const char* bind_addr_str, int port);
8788
bool connect_to(const char* dest_addr_str, int dest_port, sockaddr_in* dest_sockaddr = nullptr);
8889
bool start_listen();
89-
bool open_socket(net_utils::addr_family ip, net_utils::socket_type socket_type, net_utils::protocol_type protocol);
90+
bool reuse_addr();
91+
bool sctp_subscribe_to_events();
92+
bool sctp_set_rto_opts(int rto_max);
93+
bool sctp_set_init_msg_opts(int max_init_attempts, int max_init_timeo);
9094
int get_socket() const { return sockfd; };
9195

9296
protected:

lib/include/srsran/interfaces/enb_s1ap_interfaces.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ struct s1ap_args_t {
4242
uint32_t ts1_reloc_prep_timeout;
4343
uint32_t ts1_reloc_overall_timeout;
4444
int32_t max_s1_setup_retries;
45+
bool sctp_reuse_addr;
46+
int32_t sctp_rto_max;
47+
int32_t sctp_init_max_attempts;
48+
int32_t sctp_max_init_timeo;
4549
};
4650

4751
// S1AP interface for RRC

lib/src/common/network_utils.cc

Lines changed: 129 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -118,75 +118,7 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty
118118
perror("Could not create socket\n");
119119
return -1;
120120
}
121-
122-
if (protocol == protocol_type::SCTP) {
123-
// Sets the data_io_event to be able to use sendrecv_info
124-
// Subscribes to the SCTP_SHUTDOWN event, to handle graceful shutdown
125-
// Also subscribes to SCTP_PEER_ADDR_CHANGE, to handle ungraceful shutdown of the link.
126-
struct sctp_event_subscribe evnts = {};
127-
evnts.sctp_data_io_event = 1;
128-
evnts.sctp_shutdown_event = 1;
129-
evnts.sctp_address_event = 1;
130-
if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) {
131-
srslog::fetch_basic_logger(LOGSERVICE).error("Failed to subscribe to SCTP_SHUTDOWN event: %s", strerror(errno));
132-
perror("Could not register socket to SCTP events\n");
133-
close(fd);
134-
return -1;
135-
}
136-
137-
/*
138-
* Modify SCTP default parameters for quicker detection of broken links.
139-
* This includes changes to the SCTP_INITMSG parameters (to control the timeout of the connect() syscall)
140-
* And changes to the maximum re-transmission timeout (rto_max), for quicker detection of broken links.
141-
*/
142-
// Set RTO_MAX to quickly detect broken links.
143-
sctp_rtoinfo rto_opts;
144-
socklen_t rto_sz = sizeof(sctp_rtoinfo);
145-
rto_opts.srto_assoc_id = 0;
146-
if (getsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, &rto_sz) < 0) {
147-
printf("Error getting RTO_INFO sockopts\n");
148-
close(fd);
149-
return -1;
150-
}
151-
152-
rto_opts.srto_max = 6000; // 6 seconds
153-
154-
srslog::fetch_basic_logger(LOGSERVICE)
155-
.debug(
156-
"Setting RTO_INFO options on SCTP socket. Association %d, Initial RTO %d, Minimum RTO %d, Maximum RTO %d",
157-
rto_opts.srto_assoc_id,
158-
rto_opts.srto_initial,
159-
rto_opts.srto_min,
160-
rto_opts.srto_max);
161-
162-
if (setsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, rto_sz) < 0) {
163-
perror("Error setting RTO_INFO sockopts\n");
164-
close(fd);
165-
return -1;
166-
}
167-
168-
// Set SCTP INITMSG options to reduce blocking timeout of connect()
169-
sctp_initmsg init_opts;
170-
socklen_t init_sz = sizeof(sctp_initmsg);
171-
if (getsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, &init_sz) < 0) {
172-
printf("Error getting sockopts\n");
173-
close(fd);
174-
return -1;
175-
}
176-
177-
init_opts.sinit_max_attempts = 3;
178-
init_opts.sinit_max_init_timeo = 5000; // 5 seconds
179-
180-
srslog::fetch_basic_logger(LOGSERVICE)
181-
.debug("Setting SCTP_INITMSG options on SCTP socket. Max attempts %d, Max init attempts timeout %d",
182-
init_opts.sinit_max_attempts,
183-
init_opts.sinit_max_init_timeo);
184-
if (setsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, init_sz) < 0) {
185-
perror("Error setting SCTP_INITMSG sockopts\n");
186-
close(fd);
187-
return -1;
188-
}
189-
}
121+
srslog::fetch_basic_logger(LOGSERVICE).debug("Opened %s socket=%d", net_utils::protocol_to_string(protocol), fd);
190122

191123
return fd;
192124
}
@@ -200,7 +132,12 @@ bool bind_addr(int fd, const sockaddr_in& addr_in)
200132

201133
if (bind(fd, (struct sockaddr*)&addr_in, sizeof(addr_in)) != 0) {
202134
srslog::fetch_basic_logger(LOGSERVICE)
203-
.error("Failed to bind on address %s: %s errno %d", get_ip(addr_in).c_str(), strerror(errno), errno);
135+
.error("Failed to bind on address %s:%d. Socket=%d, strerror=%s, errno=%d",
136+
get_ip(addr_in).c_str(),
137+
get_port(addr_in),
138+
fd,
139+
strerror(errno),
140+
errno);
204141
perror("bind()");
205142
return false;
206143
}
@@ -267,6 +204,107 @@ bool start_listen(int fd)
267204
return true;
268205
}
269206

207+
bool reuse_addr(int fd)
208+
{
209+
if (fd < 0) {
210+
srslog::fetch_basic_logger(LOGSERVICE).error("Trying reuse_addr a closed socket. Socket=%d", fd);
211+
return false;
212+
}
213+
214+
int enable = 1;
215+
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) {
216+
srslog::fetch_basic_logger(LOGSERVICE).error("Failed to set SO_REUSEADDR. Socket=%d", fd);
217+
return false;
218+
}
219+
srslog::fetch_basic_logger(LOGSERVICE).debug("Successfully set SO_REUSEADDR. Socket=%d", fd);
220+
return true;
221+
}
222+
223+
bool sctp_subscribe_to_events(int fd)
224+
{
225+
if (fd < 0) {
226+
srslog::fetch_basic_logger(LOGSERVICE).error("Trying subscribe to SCTP events on a closed socket. Socket=%d", fd);
227+
return false;
228+
}
229+
230+
// Sets the data_io_event to be able to use sendrecv_info
231+
// Subscribes to the SCTP_SHUTDOWN event, to handle graceful shutdown
232+
// Also subscribes to SCTP_PEER_ADDR_CHANGE, to handle ungraceful shutdown of the link.
233+
struct sctp_event_subscribe evnts = {};
234+
evnts.sctp_data_io_event = 1;
235+
evnts.sctp_shutdown_event = 1;
236+
evnts.sctp_address_event = 1;
237+
if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) {
238+
srslog::fetch_basic_logger(LOGSERVICE).error("Failed to subscribe to SCTP_SHUTDOWN event: %s", strerror(errno));
239+
perror("Could not register socket to SCTP events\n");
240+
close(fd);
241+
return false;
242+
}
243+
return true;
244+
}
245+
246+
/*
247+
* Modify SCTP default parameters for quicker detection of broken links.
248+
* Changes to the maximum re-transmission timeout (rto_max).
249+
*/
250+
bool sctp_set_rto_opts(int fd, int rto_max)
251+
{
252+
// Set RTO_MAX to quickly detect broken links.
253+
sctp_rtoinfo rto_opts;
254+
socklen_t rto_sz = sizeof(sctp_rtoinfo);
255+
rto_opts.srto_assoc_id = 0;
256+
if (getsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, &rto_sz) < 0) {
257+
printf("Error getting RTO_INFO sockopts\n");
258+
close(fd);
259+
return false;
260+
}
261+
262+
rto_opts.srto_max = rto_max;
263+
264+
srslog::fetch_basic_logger(LOGSERVICE)
265+
.debug("Setting RTO_INFO options on SCTP socket. Association %d, Initial RTO %d, Minimum RTO %d, Maximum RTO %d",
266+
rto_opts.srto_assoc_id,
267+
rto_opts.srto_initial,
268+
rto_opts.srto_min,
269+
rto_opts.srto_max);
270+
271+
if (setsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, rto_sz) < 0) {
272+
perror("Error setting RTO_INFO sockopts\n");
273+
close(fd);
274+
return false;
275+
}
276+
return true;
277+
}
278+
279+
/*
280+
* Modify SCTP default parameters for quicker detection of broken links.
281+
* Changes to the SCTP_INITMSG parameters (to control the timeout of the connect() syscall)
282+
*/
283+
bool sctp_set_init_msg_opts(int fd, int init_max_attempts, int max_init_timeo)
284+
{
285+
// Set SCTP INITMSG options to reduce blocking timeout of connect()
286+
sctp_initmsg init_opts;
287+
socklen_t init_sz = sizeof(sctp_initmsg);
288+
if (getsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, &init_sz) < 0) {
289+
printf("Error getting sockopts\n");
290+
close(fd);
291+
return false;
292+
}
293+
294+
init_opts.sinit_max_attempts = init_max_attempts;
295+
init_opts.sinit_max_init_timeo = max_init_timeo;
296+
297+
srslog::fetch_basic_logger(LOGSERVICE)
298+
.debug("Setting SCTP_INITMSG options on SCTP socket. Max attempts %d, Max init attempts timeout %d",
299+
init_opts.sinit_max_attempts,
300+
init_opts.sinit_max_init_timeo);
301+
if (setsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, init_sz) < 0) {
302+
perror("Error setting SCTP_INITMSG sockopts\n");
303+
close(fd);
304+
return false;
305+
}
306+
return true;
307+
}
270308
} // namespace net_utils
271309

272310
/********************************************
@@ -306,9 +344,15 @@ bool unique_socket::open_socket(net_utils::addr_family ip_type,
306344
void unique_socket::close()
307345
{
308346
if (sockfd >= 0) {
309-
::close(sockfd);
347+
if (::close(sockfd) == -1) {
348+
srslog::fetch_basic_logger(LOGSERVICE).error("Socket=%d could not be closed.", sockfd);
349+
} else {
350+
srslog::fetch_basic_logger(LOGSERVICE).debug("Socket=%d was closed.", sockfd);
351+
}
310352
sockfd = -1;
311353
addr = {};
354+
} else {
355+
srslog::fetch_basic_logger(LOGSERVICE).debug("Socket=%d could not be closed.", sockfd);
312356
}
313357
}
314358

@@ -327,25 +371,25 @@ bool unique_socket::start_listen()
327371
return net_utils::start_listen(sockfd);
328372
}
329373

330-
/***********************************************************************
331-
* SCTP socket
332-
**********************************************************************/
374+
bool unique_socket::reuse_addr()
375+
{
376+
return net_utils::reuse_addr(sockfd);
377+
}
333378

334-
namespace net_utils {
379+
bool unique_socket::sctp_subscribe_to_events()
380+
{
381+
return net_utils::sctp_subscribe_to_events(sockfd);
382+
}
335383

336-
bool sctp_init_socket(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int bind_port)
384+
bool unique_socket::sctp_set_rto_opts(int rto_max)
337385
{
338-
if (not socket->open_socket(net_utils::addr_family::ipv4, socktype, net_utils::protocol_type::SCTP)) {
339-
return false;
340-
}
341-
if (not socket->bind_addr(bind_addr_str, bind_port)) {
342-
socket->close();
343-
return false;
344-
}
345-
return true;
386+
return net_utils::sctp_set_rto_opts(sockfd, rto_max);
346387
}
347388

348-
} // namespace net_utils
389+
bool unique_socket::sctp_set_init_msg_opts(int max_init_attempts, int max_init_timeo)
390+
{
391+
return net_utils::sctp_set_init_msg_opts(sockfd, max_init_attempts, max_init_timeo);
392+
}
349393

350394
/***************************************************************
351395
* Rx Multisocket Handler

lib/src/phy/rf/rf_imp.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,9 @@ static int load_plugin(srsran_rf_plugin_t* rf_plugin)
428428
rf_plugin->dl_handle = dlopen(rf_plugin->plugin_name, RTLD_NOW);
429429
if (rf_plugin->dl_handle == NULL) {
430430
// Not an error, if loading failed due to missing dependencies.
431-
// Mark this plugin as not available and return SUCCESS.
432-
INFO("Failed to load RF plugin %s: %s", rf_plugin->plugin_name, dlerror());
431+
// Flag this plugin as not available and return SUCCESS.
432+
// Note: as this function is called before log-level is configured, use plain printf for any messages < ERROR
433+
printf("Skipping RF plugin %s: %s\n", rf_plugin->plugin_name, dlerror());
433434
rf_plugin->rf_api = NULL;
434435
return SRSRAN_SUCCESS;
435436
}

lib/test/common/network_utils_test.cc

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,19 @@ int test_socket_handler()
6161
const char* server_addr = "127.0.100.1";
6262
using namespace srsran::net_utils;
6363

64-
TESTASSERT(sctp_init_socket(&server_socket, socket_type::seqpacket, server_addr, server_port));
64+
TESTASSERT(server_socket.open_socket(
65+
srsran::net_utils::addr_family::ipv4, socket_type::seqpacket, srsran::net_utils::protocol_type::SCTP));
66+
TESTASSERT(server_socket.bind_addr(server_addr, server_port));
6567
TESTASSERT(server_socket.start_listen());
6668
logger.info("Listening from fd=%d", server_socket.fd());
6769

68-
TESTASSERT(sctp_init_socket(&client_socket, socket_type::seqpacket, "127.0.0.1", 0));
69-
TESTASSERT(sctp_init_socket(&client_socket2, socket_type::seqpacket, "127.0.0.2", 0));
70+
TESTASSERT(client_socket.open_socket(
71+
srsran::net_utils::addr_family::ipv4, socket_type::seqpacket, srsran::net_utils::protocol_type::SCTP));
72+
TESTASSERT(client_socket.bind_addr("127.0.0.1", 0));
7073
TESTASSERT(client_socket.connect_to(server_addr, server_port));
74+
TESTASSERT(client_socket2.open_socket(
75+
srsran::net_utils::addr_family::ipv4, socket_type::seqpacket, srsran::net_utils::protocol_type::SCTP));
76+
TESTASSERT(client_socket2.bind_addr("127.0.0.2", 0));
7177
TESTASSERT(client_socket2.connect_to(server_addr, server_port));
7278

7379
// register server Rx handler
@@ -127,12 +133,18 @@ int test_socket_handler()
127133
int test_sctp_bind_error()
128134
{
129135
srsran::unique_socket sock;
130-
TESTASSERT(not srsran::net_utils::sctp_init_socket(
131-
&sock, srsran::net_utils::socket_type::seqpacket, "1.1.1.1", 8000)); // Bogus IP address
132-
// should not be able to bind
133-
TESTASSERT(srsran::net_utils::sctp_init_socket(
134-
&sock, srsran::net_utils::socket_type::seqpacket, "127.0.0.1", 8000)); // Good IP address
135-
// should be able to bind
136+
TESTASSERT(sock.open_socket(srsran::net_utils::addr_family::ipv4,
137+
srsran::net_utils::socket_type::seqpacket,
138+
srsran::net_utils::protocol_type::SCTP));
139+
TESTASSERT(not sock.bind_addr("1.1.1.1", 8000)); // Bogus IP address
140+
// should not be able to bind
141+
142+
srsran::unique_socket sock2;
143+
TESTASSERT(sock2.open_socket(srsran::net_utils::addr_family::ipv4,
144+
srsran::net_utils::socket_type::seqpacket,
145+
srsran::net_utils::protocol_type::SCTP));
146+
TESTASSERT(sock.bind_addr("127.0.0.1", 8000)); // Good IP address
147+
// should be able to bind
136148
return SRSRAN_SUCCESS;
137149
}
138150

srsenb/hdr/stack/rrc/rrc_ue.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class rrc::ue
3939
enum activity_timeout_type_t {
4040
MSG3_RX_TIMEOUT = 0, ///< Msg3 has its own timeout to quickly remove fake UEs from random PRACHs
4141
UE_INACTIVITY_TIMEOUT, ///< UE inactivity timeout (usually bigger than reestablishment timeout)
42-
MSG5_RX_TIMEOUT, ///< UE timeout for receiving RRCConnectionSetupComplete / RRCReestablishmentComplete
42+
MSG5_RX_TIMEOUT_T300, ///< UE timeout for receiving RRCConnectionSetupComplete
43+
MSG5_RX_TIMEOUT_T301, ///< UE timeout for receiving RRCReestablishmentComplete
4344
nulltype
4445
};
4546

srsenb/src/main.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,12 @@ void parse_args(all_args_t* args, int argc, char* argv[])
267267
("expert.ts1_reloc_prep_timeout", bpo::value<uint32_t>(&args->stack.s1ap.ts1_reloc_prep_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocPrep Expiry Timeout value in milliseconds.")
268268
("expert.ts1_reloc_overall_timeout", bpo::value<uint32_t>(&args->stack.s1ap.ts1_reloc_overall_timeout)->default_value(10000), "S1AP TS 36.413 TS1RelocOverall Expiry Timeout value in milliseconds.")
269269
("expert.rlf_min_ul_snr_estim", bpo::value<int>(&args->stack.mac.rlf_min_ul_snr_estim)->default_value(-2), "SNR threshold in dB below which the eNB is notified with rlf ko.")
270+
271+
("expert.sctp_reuse_addr", bpo::value<bool>(&args->stack.s1ap.sctp_reuse_addr)->default_value(false), "Use SO_REUSE_ADDR on S1-C interface.")
270272
("expert.max_s1_setup_retries", bpo::value<int32_t>(&args->stack.s1ap.max_s1_setup_retries)->default_value(-1), "Max S1 setup retries")
273+
("expert.sctp_rto_max", bpo::value<int32_t>(&args->stack.s1ap.sctp_rto_max)->default_value(6000), "SCTP maximum RTO.")
274+
("expert.sctp_init_max_attempts", bpo::value<int32_t>(&args->stack.s1ap.sctp_init_max_attempts)->default_value(3), "Maximum SCTP init attempts.")
275+
("expert.sctp_max_init_timeo)", bpo::value<int32_t>(&args->stack.s1ap.sctp_max_init_timeo)->default_value(5000), "Maximum SCTP init timeout.")
271276
("expert.rx_gain_offset", bpo::value<float>(&args->phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to calibrate RSRP readings")
272277
("expert.mac_prach_bi", bpo::value<uint32_t>(&args->stack.mac.prach_bi)->default_value(0), "Backoff Indicator to reduce contention in the PRACH channel")
273278

0 commit comments

Comments
 (0)