Exemplo n.º 1
0
/*
====================
NET_IP6Socket
====================
*/
SOCKET NET_IP6Socket( const char *net_interface, int port, struct sockaddr_in6 *bindto, int *err )
{
	SOCKET              newsocket;
	struct sockaddr_in6 address;

	u_long              _true = 1;
	qboolean            brackets = net_interface && Q_CountChar( net_interface, ':' );

	*err = 0;

	// Print the name in brackets if there is a colon:
	Com_Printf(_( "Opening IP6 socket: %s%s%s:%s\n"), brackets ? "[" : "", net_interface ? net_interface : "[::]", brackets ? "]" : "", port ? va( "%i", port ) : "*" );

	if ( ( newsocket = socket( PF_INET6, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET )
	{
		*err = socketError;
		Com_Printf( "WARNING: NET_IP6Socket: socket: %s\n", NET_ErrorString() );
		return newsocket;
	}

	// make it non-blocking
	if ( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR )
	{
		Com_Printf( "WARNING: NET_IP6Socket: ioctl FIONBIO: %s\n", NET_ErrorString() );
		*err = socketError;
		closesocket( newsocket );
		return INVALID_SOCKET;
	}

#ifdef IPV6_V6ONLY
	{
		int i = 1;

		// IPv4 addresses should not be allowed to connect via this socket.
		if ( setsockopt( newsocket, IPPROTO_IPV6, IPV6_V6ONLY, ( char * ) &i, sizeof( i ) ) == SOCKET_ERROR )
		{
			// win32 systems don't seem to support this anyways.
			Com_DPrintf( "WARNING: NET_IP6Socket: setsockopt IPV6_V6ONLY: %s\n", NET_ErrorString() );
		}
	}
#endif

	if ( !net_interface || !net_interface[ 0 ] )
	{
		address.sin6_family = AF_INET6;
		address.sin6_addr = in6addr_any;
	}
	else
	{
		if ( !Sys_StringToSockaddr( net_interface, ( struct sockaddr * ) &address, sizeof( address ), AF_INET6 ) )
		{
			closesocket( newsocket );
			return INVALID_SOCKET;
		}
	}

	address.sin6_port = htons( ( short ) port );

	if ( bind( newsocket, ( void * ) &address, sizeof( address ) ) == SOCKET_ERROR )
	{
		Com_Printf( "WARNING: NET_IP6Socket: bind: %s\n", NET_ErrorString() );
		*err = socketError;
		closesocket( newsocket );
		return INVALID_SOCKET;
	}

	if ( bindto )
	{
		// random port? find what was chosen
		if ( address.sin6_port == 0 )
		{
			struct sockaddr_in6 addr; // enough space
			socklen_t           addrlen = sizeof( addr );

			if ( !getsockname( newsocket, (struct sockaddr *) &addr, &addrlen ) && addrlen )
			{
				address.sin6_port = addr.sin6_port;
			}
		}
		*bindto = address;
	}

	return newsocket;
}
Exemplo n.º 2
0
/*
====================
NET_IP6Socket
====================
*/
int NET_IP6Socket( char *net_interface, int port, struct sockaddr_in6 *bindto, int *err )
{
    SOCKET              newsocket;
    struct sockaddr_in6 address;

    u_long              _true = 1;

    *err = 0;

    if ( net_interface )
    {
        // Print the name in brackets if there is a colon:
        if ( Q_CountChar( net_interface, ':' ) )
        {
            Com_Printf(_( "Opening IP6 socket: [%s]:%i\n"), net_interface, port );
        }
        else
        {
            Com_Printf(_( "Opening IP6 socket: %s:%i\n"), net_interface, port );
        }
    }
    else
    {
        Com_Printf(_( "Opening IP6 socket: [::]:%i\n"), port );
    }

    if ( ( newsocket = socket( PF_INET6, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET )
    {
        *err = socketError;
        Com_Printf(_( "WARNING: NET_IP6Socket: socket: %s\n"), NET_ErrorString() );
        return newsocket;
    }

    // make it non-blocking
    if ( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR )
    {
        Com_Printf(_( "WARNING: NET_IP6Socket: ioctl FIONBIO: %s\n"), NET_ErrorString() );
        *err = socketError;
        closesocket( newsocket );
        return INVALID_SOCKET;
    }

#ifdef IPV6_V6ONLY
    {
        int i = 1;

        // ipv4 addresses should not be allowed to connect via this socket.
        if ( setsockopt( newsocket, IPPROTO_IPV6, IPV6_V6ONLY, ( char * ) &i, sizeof( i ) ) == SOCKET_ERROR )
        {
            // win32 systems don't seem to support this anyways.
            Com_DPrintf( "WARNING: NET_IP6Socket: setsockopt IPV6_V6ONLY: %s\n", NET_ErrorString() );
        }
    }
#endif

    if ( !net_interface || !net_interface[ 0 ] )
    {
        address.sin6_family = AF_INET6;
        address.sin6_addr = in6addr_any;
    }
    else
    {
        if ( !Sys_StringToSockaddr( net_interface, ( struct sockaddr * ) &address, sizeof( address ), AF_INET6 ) )
        {
            closesocket( newsocket );
            return INVALID_SOCKET;
        }
    }

    if ( port == PORT_ANY )
    {
        address.sin6_port = 0;
    }
    else
    {
        address.sin6_port = htons( ( short ) port );
    }

    if ( bind( newsocket, ( void * ) &address, sizeof( address ) ) == SOCKET_ERROR )
    {
        Com_Printf(_( "WARNING: NET_IP6Socket: bind: %s\n"), NET_ErrorString() );
        *err = socketError;
        closesocket( newsocket );
        return INVALID_SOCKET;
    }

    if ( bindto )
    {
        *bindto = address;
    }

    return newsocket;
}
Exemplo n.º 3
0
/*
=============
NET_StringToAdr

Traps "localhost" for loopback, passes everything else to system
return 0 on address not found, 1 on address found with port, 2 on address found without port.
=============
*/
int NET_StringToAdr( const char *s, netadr_t *a, netadrtype_t family )
{
	char base[ MAX_STRING_CHARS ], *search;
	char *port = nullptr;

	if ( !strcmp( s, "localhost" ) )
	{
		Com_Memset( a, 0, sizeof( *a ) );
		a->type = NA_LOOPBACK;
// as NA_LOOPBACK doesn't require ports report port was given.
		return 1;
	}

	Q_strncpyz( base, s, sizeof( base ) );

	if ( *base == '[' || Q_CountChar( base, ':' ) > 1 )
	{
		// This is an IPv6 address, handle it specially.
		search = strchr( base, ']' );

		if ( search )
		{
			*search = '\0';
			search++;

			if ( *search == ':' )
			{
				port = search + 1;
			}
		}

		if ( *base == '[' )
		{
			search = base + 1;
		}
		else
		{
			search = base;
		}
	}
	else
	{
		// look for a port number
		port = strchr( base, ':' );

		if ( port )
		{
			*port = '\0';
			port++;
		}

		search = base;
	}

	if ( !Sys_StringToAdr( search, a, family ) )
	{
		a->type = NA_BAD;
		return 0;
	}

	if ( port )
	{
		a->port = BigShort( ( short ) atoi( port ) );
		return 1;
	}
	else
	{
		a->port = BigShort( PORT_SERVER );
		return 2;
	}
}