@ -57,13 +57,20 @@ typedef struct {
# define UDP_TX_BUF_SIZE 32768
# define UDP_MAX_PKT_SIZE 65536
static void log_net_error ( void * ctx , int level , const char * prefix )
{
char errbuf [ 100 ] ;
av_strerror ( ff_neterrno ( ) , errbuf , sizeof ( errbuf ) ) ;
av_log ( ctx , level , " %s: %s \n " , prefix , errbuf ) ;
}
static int udp_set_multicast_ttl ( int sockfd , int mcastTTL ,
struct sockaddr * addr )
{
# ifdef IP_MULTICAST_TTL
if ( addr - > sa_family = = AF_INET ) {
if ( setsockopt ( sockfd , IPPROTO_IP , IP_MULTICAST_TTL , & mcastTTL , sizeof ( mcastTTL ) ) < 0 ) {
av_log ( NULL , AV_LOG_ERROR , " setsockopt(IP_MULTICAST_TTL): %s \n " , strerror ( errno ) ) ;
log_net_error ( NULL , AV_LOG_ERROR , " setsockopt(IP_MULTICAST_TTL) " ) ;
return - 1 ;
}
}
@ -71,7 +78,7 @@ static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
# if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS)
if ( addr - > sa_family = = AF_INET6 ) {
if ( setsockopt ( sockfd , IPPROTO_IPV6 , IPV6_MULTICAST_HOPS , & mcastTTL , sizeof ( mcastTTL ) ) < 0 ) {
av_ log( NULL , AV_LOG_ERROR , " setsockopt(IPV6_MULTICAST_HOPS): %s \n " , strerror ( errno ) ) ;
log_net_error ( NULL , AV_LOG_ERROR , " setsockopt(IPV6_MULTICAST_HOPS) " ) ;
return - 1 ;
}
}
@ -88,7 +95,7 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr)
mreq . imr_multiaddr . s_addr = ( ( struct sockaddr_in * ) addr ) - > sin_addr . s_addr ;
mreq . imr_interface . s_addr = INADDR_ANY ;
if ( setsockopt ( sockfd , IPPROTO_IP , IP_ADD_MEMBERSHIP , ( const void * ) & mreq , sizeof ( mreq ) ) < 0 ) {
av_ log( NULL , AV_LOG_ERROR , " setsockopt(IP_ADD_MEMBERSHIP): %s \n " , strerror ( errno ) ) ;
log_net_error ( NULL , AV_LOG_ERROR , " setsockopt(IP_ADD_MEMBERSHIP) " ) ;
return - 1 ;
}
}
@ -100,7 +107,7 @@ static int udp_join_multicast_group(int sockfd, struct sockaddr *addr)
memcpy ( & mreq6 . ipv6mr_multiaddr , & ( ( ( struct sockaddr_in6 * ) addr ) - > sin6_addr ) , sizeof ( struct in6_addr ) ) ;
mreq6 . ipv6mr_interface = 0 ;
if ( setsockopt ( sockfd , IPPROTO_IPV6 , IPV6_ADD_MEMBERSHIP , & mreq6 , sizeof ( mreq6 ) ) < 0 ) {
av_ log( NULL , AV_LOG_ERROR , " setsockopt(IPV6_ADD_MEMBERSHIP): %s \n " , strerror ( errno ) ) ;
log_net_error ( NULL , AV_LOG_ERROR , " setsockopt(IPV6_ADD_MEMBERSHIP) " ) ;
return - 1 ;
}
}
@ -117,7 +124,7 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr)
mreq . imr_multiaddr . s_addr = ( ( struct sockaddr_in * ) addr ) - > sin_addr . s_addr ;
mreq . imr_interface . s_addr = INADDR_ANY ;
if ( setsockopt ( sockfd , IPPROTO_IP , IP_DROP_MEMBERSHIP , ( const void * ) & mreq , sizeof ( mreq ) ) < 0 ) {
av_ log( NULL , AV_LOG_ERROR , " setsockopt(IP_DROP_MEMBERSHIP): %s \n " , strerror ( errno ) ) ;
log_net_error ( NULL , AV_LOG_ERROR , " setsockopt(IP_DROP_MEMBERSHIP) " ) ;
return - 1 ;
}
}
@ -129,7 +136,7 @@ static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr)
memcpy ( & mreq6 . ipv6mr_multiaddr , & ( ( ( struct sockaddr_in6 * ) addr ) - > sin6_addr ) , sizeof ( struct in6_addr ) ) ;
mreq6 . ipv6mr_interface = 0 ;
if ( setsockopt ( sockfd , IPPROTO_IPV6 , IPV6_DROP_MEMBERSHIP , & mreq6 , sizeof ( mreq6 ) ) < 0 ) {
av_ log( NULL , AV_LOG_ERROR , " setsockopt(IPV6_DROP_MEMBERSHIP): %s \n " , strerror ( errno ) ) ;
log_net_error ( NULL , AV_LOG_ERROR , " setsockopt(IPV6_DROP_MEMBERSHIP) " ) ;
return - 1 ;
}
}
@ -194,7 +201,7 @@ static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr,
for ( res = res0 ; res ; res = res - > ai_next ) {
udp_fd = socket ( res - > ai_family , SOCK_DGRAM , 0 ) ;
if ( udp_fd > 0 ) break ;
av_ log( NULL , AV_LOG_ERROR , " socket: %s \n " , strerror ( errno ) ) ;
log_net_error ( NULL , AV_LOG_ERROR , " socket " ) ;
}
if ( udp_fd < 0 )
@ -268,7 +275,7 @@ int ff_udp_set_remote_url(URLContext *h, const char *uri)
if ( connect ( s - > udp_fd , ( struct sockaddr * ) & s - > dest_addr ,
s - > dest_addr_len ) ) {
s - > is_connected = 0 ;
av_ log( h , AV_LOG_ERROR , " connect: %s \n " , strerror ( errno ) ) ;
log_net_error ( h , AV_LOG_ERROR , " connect " ) ;
return AVERROR ( EIO ) ;
}
}
@ -391,7 +398,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
* bind failed */
/* the bind is needed to give a port to the socket now */
if ( bind_ret < 0 & & bind ( udp_fd , ( struct sockaddr * ) & my_addr , len ) < 0 ) {
av_ log( h , AV_LOG_ERROR , " bind failed: %s \n " , strerror ( errno ) ) ;
log_net_error ( h , AV_LOG_ERROR , " bind failed " ) ;
goto fail ;
}
@ -416,7 +423,7 @@ static int udp_open(URLContext *h, const char *uri, int flags)
/* limit the tx buf size to limit latency */
tmp = s - > buffer_size ;
if ( setsockopt ( udp_fd , SOL_SOCKET , SO_SNDBUF , & tmp , sizeof ( tmp ) ) < 0 ) {
av_ log( h , AV_LOG_ERROR , " setsockopt(SO_SNDBUF): %s \n " , strerror ( errno ) ) ;
log_net_error ( h , AV_LOG_ERROR , " setsockopt(SO_SNDBUF) " ) ;
goto fail ;
}
} else {
@ -424,14 +431,14 @@ static int udp_open(URLContext *h, const char *uri, int flags)
* avoid losing data on OSes that set this too low by default . */
tmp = s - > buffer_size ;
if ( setsockopt ( udp_fd , SOL_SOCKET , SO_RCVBUF , & tmp , sizeof ( tmp ) ) < 0 ) {
av_ log( h , AV_LOG_WARNING , " setsockopt(SO_RECVBUF): %s \n " , strerror ( errno ) ) ;
log_net_error ( h , AV_LOG_WARNING , " setsockopt(SO_RECVBUF) " ) ;
}
/* make the socket non-blocking */
ff_socket_nonblock ( udp_fd , 1 ) ;
}
if ( s - > is_connected ) {
if ( connect ( udp_fd , ( struct sockaddr * ) & s - > dest_addr , s - > dest_addr_len ) ) {
av_ log( h , AV_LOG_ERROR , " connect: %s \n " , strerror ( errno ) ) ;
log_net_error ( h , AV_LOG_ERROR , " connect " ) ;
goto fail ;
}
}