Пример #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;
}
Пример #2
0
/*
 * @brief Creates and binds a new network socket for the specified protocol.
 */
int32_t Net_Socket(net_addr_type_t type, const char *iface, in_port_t port) {
	int32_t sock, i = 1;

	switch (type) {
		case NA_BROADCAST:
		case NA_DATAGRAM:
			if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
				Com_Error(ERR_DROP, "socket: %s\n", Net_GetErrorString());
			}

			if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const void *) &i, sizeof(i)) == -1) {
				Com_Error(ERR_DROP, "setsockopt: %s\n", Net_GetErrorString());
			}
			break;

		case NA_STREAM:
			if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
				Com_Error(ERR_DROP, "socket: %s", Net_GetErrorString());
			}

			if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const void *) &i, sizeof(i)) == -1) {
				Com_Error(ERR_DROP, "setsockopt: %s", Net_GetErrorString());
			}
			break;

		default:
			Com_Error(ERR_DROP, "Invalid socket type: %d", type);
	}

	// make all sockets non-blocking
	if (ioctl(sock, FIONBIO, (void *) &i) == -1) {
		Com_Error(ERR_DROP, "ioctl: %s\n", Net_GetErrorString());
	}

	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));

	if (iface) {
		Net_StringToSockaddr(iface, &addr);
	} else {
		addr.sin_family = AF_INET;
		addr.sin_addr.s_addr = INADDR_ANY;
	}

	addr.sin_port = htons(port);

	if (bind(sock, (void *) &addr, sizeof(addr)) == -1) {
		Com_Error(ERR_DROP, "bind: %s\n", Net_GetErrorString());
	}

	return sock;
}
Пример #3
0
/*
 * @brief localhost
 * idnewt
 * idnewt:28000
 * 192.246.40.70
 * 192.246.40.70:28000
 */
_Bool Net_StringToNetaddr(const char *s, net_addr_t *a) {
	struct sockaddr_in saddr;

	if (!g_strcmp0(s, "localhost")) {
		memset(a, 0, sizeof(*a));
		a->type = NA_LOCAL;
		return true;
	}

	if (!Net_StringToSockaddr(s, (struct sockaddr *) &saddr))
		return false;

	Net_SockaddrToNetaddr(&saddr, a);

	return true;
}
Пример #4
0
/*
 * @brief Parses the hostname and port into the specified net_addr_t.
 */
_Bool Net_StringToNetaddr(const char *s, net_addr_t *a) {
	struct sockaddr_in saddr;

	if (!Net_StringToSockaddr(s, &saddr))
		return false;

	a->addr = saddr.sin_addr.s_addr;

	if (a->addr == net_lo) {
		a->port = 0;
		a->type = NA_LOOP;
	} else {
		a->port = saddr.sin_port;
		a->type = NA_DATAGRAM;
	}

	return true;
}
Пример #5
0
/**
 * @brief Parses the hostname and port into the specified net_addr_t.
 */
_Bool Net_StringToNetaddr(const char *s, net_addr_t *a) {
	net_sockaddr saddr;

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

	a->addr = saddr.sin_addr.s_addr;

	if (g_strcmp0(s, "localhost") == 0) {
		a->port = 0;
		a->type = NA_LOOP;
	} else {
		a->port = saddr.sin_port;
		a->type = NA_DATAGRAM;
	}

	return true;
}
Пример #6
0
/*
 * @brief
 */
static int32_t Net_Socket(const char *net_interface, uint16_t port) {
	int32_t sock;
	struct sockaddr_in addr;
	int32_t i = 1;

	if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
		Com_Error(ERR_FATAL, "Call socket: %s\n", Net_ErrorString());
		return 0;
	}

	// make it non-blocking
	if (ioctl(sock, FIONBIO, (char *) &i) == -1) {
		Com_Error(ERR_FATAL, "Call ioctl: %s\n", Net_ErrorString());
		return 0;
	}

	// make it broadcast capable
	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof(i)) == -1) {
		Com_Error(ERR_FATAL, "Call setsockopt: %s\n", Net_ErrorString());
		return 0;
	}

	if (!net_interface || !net_interface[0] || !strcasecmp(net_interface, "localhost"))
		addr.sin_addr.s_addr = INADDR_ANY;
	else
		Net_StringToSockaddr(net_interface, (struct sockaddr *) &addr);

	addr.sin_port = htons(port);
	addr.sin_family = AF_INET;

	if (bind(sock, (void *) &addr, sizeof(addr)) == -1) {
		Com_Print("ERROR: UDP_OpenSocket: bind: %s\n", Net_ErrorString());
		close(sock);
		return 0;
	}

	return sock;
}
Пример #7
0
/**
 * @brief Establishes a TCP connection to the specified host.
 *
 * @param host The host to connect to. See Net_StringToNetaddr.
 */
int32_t Net_Connect(const char *host, struct timeval *timeout) {

	int32_t sock = Net_Socket(NA_STREAM, NULL, 0);

	struct sockaddr_in to;
	Net_StringToSockaddr(host, &to);

	if (connect(sock, (const struct sockaddr *) &to, sizeof(to)) == -1) {

		if (Net_GetError() == EINPROGRESS) {
			fd_set w_set;

			FD_ZERO(&w_set);
			FD_SET((uint32_t) sock, &w_set);

			if (select(sock + 1, NULL, &w_set, NULL, timeout) < 1) {
				Com_Error(ERROR_DROP, "%s\n", Net_GetErrorString());
			}

			int32_t error = -1;
			socklen_t len = sizeof(error);

			if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *) &error, &len) < 0) {
				Com_Error(ERROR_DROP, "%s\n", Net_GetErrorString());
			}

			if (error) {
				Com_Error(ERROR_DROP, "%s\n", strerror(error));
			}
		} else {
			Com_Error(ERROR_DROP, "%s\n", Net_GetErrorString());
		}
	}

	return sock;
}
/*
========================
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;
}
Пример #9
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;
}