@@ -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,
306344void 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
0 commit comments