Beispiel #1
0
/*
=============
Sys_StringToNetAdr
=============
*/
bool Sys_StringToNetAdr( const char *s, netadr_t *a, bool doDNSResolve ) {
	struct sockaddr sadr;

	if ( !Net_StringToSockaddr( s, &sadr, doDNSResolve ) ) {
		return false;
	}

	Net_SockadrToNetadr( &sadr, a );
	return true;
}
Beispiel #2
0
/*
==================
Net_GetUDPPacket
==================
*/
bool Net_GetUDPPacket( int netSocket, netadr_t &net_from, char *data, int &size, int maxSize ) {
	int				ret;
	struct sockaddr	from;
	int				fromlen;
	int				err;

	if( !netSocket ) {
		return false;
	}

	fromlen = sizeof(from);
	ret = recvfrom( netSocket, data, maxSize, 0, (struct sockaddr *)&from, &fromlen );
	if ( ret == SOCKET_ERROR ) {
		err = WSAGetLastError();

		if( err == WSAEWOULDBLOCK || err == WSAECONNRESET ) {
			return false;
		}
		char	buf[1024];
		sprintf( buf, "Net_GetUDPPacket: %s\n", NET_ErrorString() );
		OutputDebugString( buf );
		return false;
	}

	if ( netSocket == ip_socket ) {
		memset( ((struct sockaddr_in *)&from)->sin_zero, 0, 8 );
	}

	if ( usingSocks && netSocket == ip_socket && memcmp( &from, &socksRelayAddr, fromlen ) == 0 ) {
		if ( ret < 10 || data[0] != 0 || data[1] != 0 || data[2] != 0 || data[3] != 1 ) {
			return false;
		}
		net_from.type = NA_IP;
		net_from.ip[0] = data[4];
		net_from.ip[1] = data[5];
		net_from.ip[2] = data[6];
		net_from.ip[3] = data[7];
		net_from.port = *(short *)&data[8];
		memmove( data, &data[10], ret - 10 );
	} else {
		Net_SockadrToNetadr( &from, &net_from );
	}

	if( ret == maxSize ) {
		char	buf[1024];
		sprintf( buf, "Net_GetUDPPacket: oversize packet from %s\n", Sys_NetAdrToString( net_from ) );
		OutputDebugString( buf );
		return false;
	}

	size = ret;

	return true;
}
/*
========================
Net_GetUDPPacket
========================
*/
bool Net_GetUDPPacket( int netSocket, netadr_t& net_from, char* data, int& size, int maxSize )
{
	int 			ret;
	sockaddr_in		from;
	socklen_t		fromlen;
	int				err;
	
	if( !netSocket )
	{
		return false;
	}
	
	fromlen = sizeof( from );
	ret = recvfrom( netSocket, data, maxSize, 0, ( sockaddr* )&from, &fromlen );
	if( ret == SOCKET_ERROR )
	{
		err = Net_GetLastError();
		
		if( err == D3_NET_EWOULDBLOCK || err == D3_NET_ECONNRESET )
		{
			return false;
		}
		
		idLib::Printf( "Net_GetUDPPacket: %s\n", NET_ErrorString() );
		return false;
	}
#if 0
	// TODO: WTF was this about?
	// DG: ip_socket is never initialized, so this is dead code
	// - and if netSocket is 0 (so this would be true) recvfrom above will already fail
	if( static_cast<unsigned int>( netSocket ) == ip_socket )
	{
		memset( from.sin_zero, 0, sizeof( from.sin_zero ) );
	}
	
	if( usingSocks && static_cast<unsigned int>( netSocket ) == ip_socket && memcmp( &from, &socksRelayAddr, fromlen ) == 0 )
	{
		if( ret < 10 || data[0] != 0 || data[1] != 0 || data[2] != 0 || data[3] != 1 )
		{
			return false;
		}
		net_from.type = NA_IP;
		net_from.ip[0] = data[4];
		net_from.ip[1] = data[5];
		net_from.ip[2] = data[6];
		net_from.ip[3] = data[7];
		net_from.port = *( short* )&data[8];
		memmove( data, &data[10], ret - 10 );
	}
	else
	{
#endif // 0
	
		Net_SockadrToNetadr( &from, &net_from );
#if 0 // this is ugly, but else astyle is confused
	}
#endif
	
	if( ret > maxSize )
	{
		idLib::Printf( "Net_GetUDPPacket: oversize packet from %s\n", Sys_NetAdrToString( net_from ) );
		return false;
	}
	
	size = ret;
	
	return true;
}
/*
========================
NET_IPSocket
========================
*/
int NET_IPSocket( const char* bind_ip, int port, netadr_t* bound_to )
{
	SOCKET				newsocket;
	sockaddr_in			address;
	
	if( port != PORT_ANY )
	{
		if( bind_ip )
		{
			idLib::Printf( "Opening IP socket: %s:%i\n", bind_ip, port );
		}
		else
		{
			idLib::Printf( "Opening IP socket: localhost:%i\n", port );
		}
	}
	
	if( ( newsocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET )
	{
		idLib::Printf( "WARNING: UDP_OpenSocket: socket: %s\n", NET_ErrorString() );
		return 0;
	}
	
	// make it non-blocking
#ifdef _WIN32 // which has no fcntl()
	unsigned long	_true = 1;
	if( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR )
	{
		idLib::Printf( "WARNING: UDP_OpenSocket: ioctl FIONBIO: %s\n", NET_ErrorString() );
		closesocket( newsocket );
		return 0;
	}
#else
	int flags = fcntl( newsocket, F_GETFL, 0 );
	if( flags < 0 )
	{
		idLib::Printf( "WARNING: UDP_OpenSocket: fcntl F_GETFL: %s\n", NET_ErrorString() );
		closesocket( newsocket );
		return 0;
	}
	flags |= O_NONBLOCK;
	if( fcntl( newsocket, F_SETFL, flags ) < 0 )
	{
		idLib::Printf( "WARNING: UDP_OpenSocket: fcntl F_SETFL with O_NONBLOCK: %s\n", NET_ErrorString() );
		closesocket( newsocket );
		return 0;
	}
#endif
	
	// make it broadcast capable
	int i = 1;
	if( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, ( char* )&i, sizeof( i ) ) == SOCKET_ERROR )
	{
		idLib::Printf( "WARNING: UDP_OpenSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() );
		closesocket( newsocket );
		return 0;
	}
	
	if( !bind_ip || !bind_ip[0] || !idStr::Icmp( bind_ip, "localhost" ) )
	{
		address.sin_addr.s_addr = INADDR_ANY;
	}
	else
	{
		Net_StringToSockaddr( bind_ip, &address, true );
	}
	
	if( port == PORT_ANY )
	{
		address.sin_port = 0;
	}
	else
	{
		address.sin_port = htons( ( short )port );
	}
	
	address.sin_family = AF_INET;
	
	if( bind( newsocket, ( const sockaddr* )&address, sizeof( address ) ) == SOCKET_ERROR )
	{
		idLib::Printf( "WARNING: UDP_OpenSocket: bind: %s\n", NET_ErrorString() );
		closesocket( newsocket );
		return 0;
	}
	
	// if the port was PORT_ANY, we need to query again to know the real port we got bound to
	// ( this used to be in idUDP::InitForPort )
	if( bound_to )
	{
		socklen_t len = sizeof( address );
		if( getsockname( newsocket, ( struct sockaddr* )&address, &len ) == SOCKET_ERROR )
		{
			common->Printf( "ERROR: IPSocket: getsockname: %s\n", NET_ErrorString() );
			closesocket( newsocket );
			return 0;
		}
		Net_SockadrToNetadr( &address, bound_to );
	}
	
	return newsocket;
}
Beispiel #5
0
/*
====================
NET_IPSocket
====================
*/
int NET_IPSocket( const char *net_interface, int port, netadr_t *bound_to ) {
	SOCKET				newsocket;
	struct sockaddr_in	address;
	unsigned long		_true = 1;
	int					i = 1;
	int					err;

	if( net_interface ) {
		common->DPrintf( "Opening IP socket: %s:%i\n", net_interface, port );
	} else {
		common->DPrintf( "Opening IP socket: localhost:%i\n", port );
	}

	if( ( newsocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET ) {
		err = WSAGetLastError();
		if( err != WSAEAFNOSUPPORT ) {
			common->Printf( "WARNING: UDP_OpenSocket: socket: %s\n", NET_ErrorString() );
		}
		return 0;
	}

	// make it non-blocking
	if( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR ) {
		common->Printf( "WARNING: UDP_OpenSocket: ioctl FIONBIO: %s\n", NET_ErrorString() );
		return 0;
	}

	// make it broadcast capable
	if( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i) ) == SOCKET_ERROR ) {
		common->Printf( "WARNING: UDP_OpenSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() );
		return 0;
	}

	if( !net_interface || !net_interface[0] || !idStr::Icmp( net_interface, "localhost" ) ) {
		address.sin_addr.s_addr = INADDR_ANY;
	}
	else {
		Net_StringToSockaddr( net_interface, (struct sockaddr *)&address, true );
	}

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

	address.sin_family = AF_INET;

	if( bind( newsocket, (const struct sockaddr *)&address, sizeof(address) ) == SOCKET_ERROR ) {
		common->Printf( "WARNING: UDP_OpenSocket: bind: %s\n", NET_ErrorString() );
		closesocket( newsocket );
		return 0;
	}

	// if the port was PORT_ANY, we need to query again to know the real port we got bound to
	// ( this used to be in idPort::InitForPort )
	if ( bound_to ) {
		int len = sizeof( address );
		getsockname( newsocket, (sockaddr *)&address, &len );
		Net_SockadrToNetadr( (sockaddr *)&address, bound_to );
	}

	return newsocket;
}