@@ -54,11 +54,44 @@ struct rtpp_notify {
5454 int fd ;
5555 char * remaining ;
5656 int remaining_len ;
57+ int linked ;
5758 union sockaddr_union addr ;
5859 struct list_head list ;
5960};
6061OSIPS_LIST_HEAD (rtpp_notify_fds );
6162
63+ static void free_rtpp_notify (int fd , struct rtpp_notify * notify )
64+ {
65+ reactor_del_reader (fd , -1 , IO_FD_CLOSING );
66+ if (notify ) {
67+ if (notify -> linked )
68+ list_del (& notify -> list );
69+ if (notify -> remaining )
70+ pkg_free (notify -> remaining );
71+ pkg_free (notify );
72+ }
73+ shutdown (fd , SHUT_RDWR );
74+ close (fd );
75+ }
76+
77+ static int set_nonblocking (int fd )
78+ {
79+ int flags ;
80+
81+ flags = fcntl (fd , F_GETFL );
82+ if (flags == -1 ) {
83+ LM_ERR ("fcntl(%d, F_GETFL) failed: %s\n" , fd , strerror (errno ));
84+ return -1 ;
85+ }
86+
87+ if (fcntl (fd , F_SETFL , flags | O_NONBLOCK ) == -1 ) {
88+ LM_ERR ("fcntl(%d, F_SETFL) failed: %s\n" , fd , strerror (errno ));
89+ return -1 ;
90+ }
91+
92+ return 0 ;
93+ }
94+
6295static int notification_handler (str * command )
6396{
6497 char cmd , * p ;
@@ -200,7 +233,7 @@ static int rtpproxy_io_callback(int fd, void *fs, int was_timeout)
200233{
201234 struct rtpp_notify * notify = (struct rtpp_notify * )fs ;
202235 char buffer [BUF_LEN ];
203- int len , left , offset ;
236+ int len , left , offset , total ;
204237 str command ;
205238 char * p , * start , * sp , * end ;
206239
@@ -214,59 +247,79 @@ static int rtpproxy_io_callback(int fd, void *fs, int was_timeout)
214247 offset = 0 ;
215248 }
216249
217- do
218- len = read (fd , buffer + offset , BUF_LEN - offset );
219- while (len == -1 && errno == EINTR );
220-
221- if (len < 0 ) {
222- LM_ERR ("reading from socket failed: %s\n" ,strerror (errno ));
223- return -1 ;
224- }
225- if (len == 0 ) {
226- LM_DBG ("closing rtpproxy notify socket\n" );
227- reactor_del_reader (fd , -1 , IO_FD_CLOSING );
228- if (notify ) {
229- list_del (& notify -> list );
230- pkg_free (notify );
250+ for (;;) {
251+ if (offset == BUF_LEN ) {
252+ LM_ERR ("RTPProxy notification command too large [%.*s]\n" ,
253+ offset , buffer );
254+ free_rtpp_notify (fd , notify );
255+ return -1 ;
231256 }
232- shutdown (fd , SHUT_RDWR );
233- close (fd );
234- return 0 ;
235- }
236257
237- LM_DBG ("Notification(s) received: [%.*s]\n" , len , buffer );
238- p = buffer ;
239- left = len + offset ;
240- end = buffer + left ;
258+ do
259+ len = read (fd , buffer + offset , BUF_LEN - offset );
260+ while (len == -1 && errno == EINTR );
241261
242- do {
243- start = p ;
262+ if (len < 0 ) {
263+ if (errno == EAGAIN || errno == EWOULDBLOCK )
264+ break ;
244265
245- sp = q_memchr (p , '\n' , left );
246- if (sp == NULL )
247- break ;
248- command .s = p ;
249- command .len = sp - p ;
250- /* skip the command */
251- p = sp + 1 ;
252- left -= (sp - start ) + 1 ;
253-
254- if (notification_handler (& command ) < 0 )
266+ LM_ERR ("reading from socket failed: %s\n" ,strerror (errno ));
267+ free_rtpp_notify (fd , notify );
255268 return -1 ;
269+ }
270+ if (len == 0 ) {
271+ if (offset )
272+ LM_WARN ("dropping partial RTPProxy notification [%.*s]\n" ,
273+ offset , buffer );
274+ LM_DBG ("closing rtpproxy notify socket\n" );
275+ free_rtpp_notify (fd , notify );
276+ return 0 ;
277+ }
278+
279+ total = len + offset ;
280+ LM_DBG ("Notification(s) received: [%.*s]\n" , total , buffer );
281+ p = buffer ;
282+ left = total ;
283+ end = buffer + total ;
284+
285+ do {
286+ start = p ;
287+
288+ sp = q_memchr (p , '\n' , left );
289+ if (sp == NULL )
290+ break ;
291+ command .s = p ;
292+ command .len = sp - p ;
293+ /* skip the command */
294+ p = sp + 1 ;
295+ left -= (sp - start ) + 1 ;
296+
297+ if (notification_handler (& command ) < 0 ) {
298+ LM_ERR ("notification_handler failed\n" );
299+ free_rtpp_notify (fd , notify );
300+ return -1 ;
301+ }
256302
257- LM_DBG ("Left to process: %d\n[%.*s]\n" , left , left , p );
303+ LM_DBG ("Left to process: %d\n[%.*s]\n" , left , left , p );
258304
259- } while (p < end );
305+ } while (p < end );
306+
307+ offset = end - p ;
308+ if (offset ) {
309+ LM_DBG ("%d remaining data in buffer!\n" , offset );
310+ memmove (buffer , p , offset );
311+ }
312+ }
260313
261- if (end - p ) {
262- LM_DBG ("%d remaining data in buffer!\n" , (int )(end - start ));
263- if (notify && (notify -> remaining = pkg_malloc (end - start )) != NULL ) {
264- notify -> remaining_len = (int )(end - start );
265- memcpy (notify -> remaining , p , notify -> remaining_len );
314+ if (offset ) {
315+ if (notify && (notify -> remaining = pkg_malloc (offset )) != NULL ) {
316+ notify -> remaining_len = offset ;
317+ memcpy (notify -> remaining , buffer , offset );
266318 } else {
267- LM_WARN ("dropping remaining data [%.*s]\n" , ( int )( end - start ), start );
319+ LM_WARN ("dropping remaining data [%.*s]\n" , offset , buffer );
268320 }
269321 }
322+
270323 return 0 ;
271324}
272325
@@ -285,35 +338,43 @@ static int rtpproxy_io_new_callback(int fd, void *fs, int was_timeout)
285338 return -1 ;
286339 }
287340
288- if (rtpp_notify_socket_un ) {
289- LM_DBG ("trusting unix socket connection\n" );
290- if (reactor_proc_add_fd (fd , rtpproxy_io_callback , NULL )< 0 ) {
291- LM_CRIT ("failed to add RTPProxy new connection to reactor\n" );
292- return -1 ;
293- }
294- return 0 ;
295- }
296- node = rtpproxy_get_node ((union sockaddr_union * )& rtpp_info );
297- if (!node ) {
298- LM_WARN ("connection from unknown RTPProxy node" );
299- return -1 ;
300- }
341+ if (set_nonblocking (fd ) < 0 )
342+ goto err ;
301343
302344 notify = pkg_malloc (sizeof * notify );
303345 if (!notify ) {
304346 LM_ERR ("could not allocate notify node\n" );
305- return -1 ;
347+ goto err ;
306348 }
307349 memset (notify , 0 , sizeof * notify );
308350 notify -> fd = fd ;
309- memcpy (& notify -> addr , & node -> addr , sizeof (union sockaddr_union ));
351+
352+ if (rtpp_notify_socket_un ) {
353+ LM_DBG ("trusting unix socket connection\n" );
354+ } else {
355+ node = rtpproxy_get_node ((union sockaddr_union * )& rtpp_info );
356+ if (!node ) {
357+ LM_WARN ("connection from unknown RTPProxy node" );
358+ pkg_free (notify );
359+ goto err ;
360+ }
361+ memcpy (& notify -> addr , & node -> addr , sizeof (union sockaddr_union ));
362+ list_add (& notify -> list , & rtpp_notify_fds );
363+ notify -> linked = 1 ;
364+ }
365+
310366 if (reactor_proc_add_fd (fd , rtpproxy_io_callback , notify ) < 0 ) {
311367 LM_CRIT ("failed to add RTPProxy listen socket to reactor\n" );
368+ if (notify -> linked )
369+ list_del (& notify -> list );
312370 pkg_free (notify );
313- return -1 ;
371+ goto err ;
314372 }
315- list_add (& notify -> list , & rtpp_notify_fds );
316373 return 0 ;
374+ err :
375+ shutdown (fd , SHUT_RDWR );
376+ close (fd );
377+ return -1 ;
317378}
318379
319380int init_rtpp_notify (void )
@@ -411,6 +472,8 @@ void notification_listener_process(int rank)
411472 return ;
412473 }
413474
475+ if (set_nonblocking (socket_fd ) < 0 )
476+ return ;
414477 if (reactor_proc_add_fd ( socket_fd , rtpproxy_io_new_callback , NULL ) < 0 ) {
415478 LM_CRIT ("failed to add RTPProxy listen socket to reactor\n" );
416479 return ;
0 commit comments