📄 ipv6.c
字号:
/* Open a SOCK_DGRAM (UDP) socket, in the AF_INET6 domain, automatic (0) * protocol */ if( (i_handle = socket( AF_INET6, SOCK_DGRAM, 0 )) == -1 ) { msg_Warn( p_this, "cannot create socket (%s)", strerror(errno) ); return( -1 ); } /* We may want to reuse an already used socket */ i_opt = 1; if( setsockopt( i_handle, SOL_SOCKET, SO_REUSEADDR, (void *) &i_opt, sizeof( i_opt ) ) == -1 ) { msg_Warn( p_this, "cannot configure socket (SO_REUSEADDR: %s)", strerror(errno) ); close( i_handle ); return( -1 ); } /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s) to avoid * packet loss caused by scheduling problems */ i_opt = 0x80000; if( setsockopt( i_handle, SOL_SOCKET, SO_RCVBUF, (void *) &i_opt, sizeof( i_opt ) ) == -1 ) { msg_Warn( p_this, "cannot configure socket (SO_RCVBUF: %s)", strerror(errno) ); } /* Check if we really got what we have asked for, because Linux, etc. * will silently limit the max buffer size to net.core.rmem_max which * is typically only 65535 bytes */ i_opt = 0; i_opt_size = sizeof( i_opt ); if( getsockopt( i_handle, SOL_SOCKET, SO_RCVBUF, (void*) &i_opt, &i_opt_size ) == -1 ) { msg_Warn( p_this, "cannot query socket (SO_RCVBUF: %s)", strerror(errno) ); } else if( i_opt < 0x80000 ) { msg_Warn( p_this, "socket buffer size is 0x%x instead of 0x%x", i_opt, 0x80000 ); } /* Build the local socket */ if ( BuildAddr( p_this, &sock, psz_bind_addr, i_bind_port ) == -1 ) { close( i_handle ); return( -1 ); }#if defined(WIN32) /* Under Win32 and for multicasting, we bind to IN6ADDR_ANY */ if( IN6_IS_ADDR_MULTICAST(&sock.sin6_addr) ) { struct sockaddr_in6 sockany = sock; sockany.sin6_addr = in6addr_any; sockany.sin6_scope_id = 0; /* Bind it */ if( bind( i_handle, (struct sockaddr *)&sockany, sizeof( sock ) ) < 0 ) { msg_Warn( p_this, "cannot bind socket (%s)", strerror(errno) ); close( i_handle ); return( -1 ); } } else#endif /* Bind it */ if( bind( i_handle, (struct sockaddr *)&sock, sizeof( sock ) ) < 0 ) { msg_Warn( p_this, "cannot bind socket (%s)", strerror(errno) ); close( i_handle ); return( -1 ); } /* Allow broadcast reception if we bound on in6addr_any */ if( !*psz_bind_addr ) { i_opt = 1; if( setsockopt( i_handle, SOL_SOCKET, SO_BROADCAST, (void*) &i_opt, sizeof( i_opt ) ) == -1 ) { msg_Warn( p_this, "ipv6 warning: cannot configure socket " "(SO_BROADCAST: %s)", strerror(errno) ); } } /* Join the multicast group if the socket is a multicast address */#if defined( WIN32 ) || defined( HAVE_IF_NAMETOINDEX ) if( IN6_IS_ADDR_MULTICAST(&sock.sin6_addr) ) { struct ipv6_mreq imr; int res; imr.ipv6mr_interface = sock.sin6_scope_id; imr.ipv6mr_multiaddr = sock.sin6_addr; res = setsockopt(i_handle, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void*) &imr,#if defined(WIN32) sizeof(imr) + 4); /* Doesn't work without this */#else sizeof(imr));#endif if( res == -1 ) { msg_Err( p_this, "cannot join multicast group" ); } }#else msg_Warn( p_this, "Multicast IPv6 is not supported on your OS" );#endif if( *psz_server_addr ) { int ttl = p_socket->i_ttl; if( ttl < 1 ) { ttl = config_GetInt( p_this, "ttl" ); } if( ttl < 1 ) ttl = 1; /* Build socket for remote connection */ if ( BuildAddr( p_this, &sock, psz_server_addr, i_server_port ) == -1 ) { msg_Warn( p_this, "cannot build remote address" ); close( i_handle ); return( -1 ); } /* Connect the socket */ if( connect( i_handle, (struct sockaddr *) &sock, sizeof( sock ) ) == (-1) ) { msg_Warn( p_this, "cannot connect socket (%s)", strerror(errno) ); close( i_handle ); return( -1 ); } /* Set the time-to-live */ if( ttl > 1 ) {#if defined( WIN32 ) || defined( HAVE_IF_NAMETOINDEX ) if( IN6_IS_ADDR_MULTICAST(&sock.sin6_addr) ) { if( setsockopt( i_handle, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof( ttl ) ) < 0 ) {#ifdef HAVE_ERRNO_H msg_Err( p_this, "failed to set multicast ttl (%s)", strerror(errno) );#else msg_Err( p_this, "failed to set multicast ttl" );#endif } } else#endif { if( setsockopt( i_handle, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (void *)&ttl, sizeof( ttl ) ) < 0 ) {#ifdef HAVE_ERRNO_H msg_Err( p_this, "failed to set unicast ttl (%s)", strerror(errno) );#else msg_Err( p_this, "failed to set unicast ttl" );#endif } } } } p_socket->i_handle = i_handle; p_socket->i_mtu = config_GetInt( p_this, "mtu" ); return( 0 );}/***************************************************************************** * OpenTCP: open a TCP socket ***************************************************************************** * psz_server_addr, i_server_port : address and port used for the connect() * system call. If i_server_port == 0, 80 is used. * Other parameters are ignored. * This function returns -1 in case of error. *****************************************************************************/static int OpenTCP( vlc_object_t * p_this, network_socket_t * p_socket ){ char * psz_server_addr = p_socket->psz_server_addr; int i_server_port = p_socket->i_server_port; int i_handle; struct sockaddr_in6 sock; if( i_server_port == 0 ) { i_server_port = 80; } /* Open a SOCK_STREAM (TCP) socket, in the AF_INET6 domain, automatic (0) * protocol */ if( (i_handle = socket( AF_INET6, SOCK_STREAM, 0 )) == -1 ) { msg_Warn( p_this, "cannot create socket (%s)", strerror(errno) ); return( -1 ); } /* Build remote address */ if ( BuildAddr( p_this, &sock, psz_server_addr, i_server_port ) == -1 ) { close( i_handle ); return( -1 ); } /* Connect the socket */ if( connect( i_handle, (struct sockaddr *) &sock, sizeof( sock ) ) == (-1) ) { msg_Warn( p_this, "cannot connect socket (%s)", strerror(errno) ); close( i_handle ); return( -1 ); } p_socket->i_handle = i_handle; p_socket->i_mtu = 0; /* There is no MTU notion in TCP */ return( 0 );}/***************************************************************************** * Open: wrapper around OpenUDP and OpenTCP *****************************************************************************/static int Open( vlc_object_t * p_this ){ network_socket_t * p_socket = p_this->p_private; if( p_socket->i_type == NETWORK_UDP ) { return OpenUDP( p_this, p_socket ); } else { return OpenTCP( p_this, p_socket ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -