Commit dddfd15d authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

RTP out: robustify send error handling

For error other than congestion (EAGAIN, EWOULDBLOCK, ENOBUFS, ENOMEM),
check the socket type. If the socket is a datagram, retry. Otherwise,
the socket is connection-oriented and we assume the connection broke,
close it.
parent 961fae15
...@@ -1425,31 +1425,20 @@ static void* ThreadSend( void *data ) ...@@ -1425,31 +1425,20 @@ static void* ThreadSend( void *data )
#endif #endif
SendRTCP( id->sinkv[i].rtcp, out ); SendRTCP( id->sinkv[i].rtcp, out );
if( send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 ) >= 0 ) if( send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 ) == -1
continue; && net_errno != EAGAIN && net_errno != EWOULDBLOCK
switch( net_errno ) && net_errno != ENOBUFS && net_errno != ENOMEM )
{ {
/* Soft errors (e.g. ICMP): */ int type;
case ECONNREFUSED: /* Port unreachable */ getsockopt( id->sinkv[i].rtp_fd, SOL_SOCKET, SO_TYPE,
case ENOPROTOOPT: &type, &(socklen_t){ sizeof(type) });
#ifdef EPROTO if( type == SOCK_DGRAM )
case EPROTO: /* Protocol unreachable */ /* ICMP soft error: ignore and retry */
#endif
case EHOSTUNREACH: /* Host unreachable */
case ENETUNREACH: /* Network unreachable */
case ENETDOWN: /* Entire network down */
send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 ); send( id->sinkv[i].rtp_fd, out->p_buffer, len, 0 );
/* Transient congestion: */ else
case ENOMEM: /* out of socket buffers */ /* Broken connection */
case ENOBUFS: deadv[deadc++] = id->sinkv[i].rtp_fd;
case EAGAIN:
#if (EAGAIN != EWOULDBLOCK)
case EWOULDBLOCK:
#endif
continue;
} }
deadv[deadc++] = id->sinkv[i].rtp_fd;
} }
id->i_seq_sent_next = ntohs(((uint16_t *) out->p_buffer)[1]) + 1; id->i_seq_sent_next = ntohs(((uint16_t *) out->p_buffer)[1]) + 1;
vlc_mutex_unlock( &id->lock_sink ); vlc_mutex_unlock( &id->lock_sink );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment