Exemple #1
0
void
NET_SendPacket (int length, const void *data, netadr_t to)
{
	int         ret;
	AF_address_t addr;

	NetadrToSockadr (&to, &addr);

	ret = sendto (net_socket, data, length, 0, &addr.sa, SA_LEN (&addr.sa));
	if (ret == -1) {
#ifdef _WIN32
		int         err = WSAGetLastError ();

		if (err == WSAEADDRNOTAVAIL)
			Sys_Printf ("NET_SendPacket Warning: %i\n", err);
#else /* _WIN32 */
		int         err = errno;

		if (err == ECONNREFUSED)
			return;
#endif /* _WIN32 */
		if (err == EWOULDBLOCK)
			return;

		Sys_Printf ("NET_SendPacket: %s\n", strerror (err));
	}
}
Exemple #2
0
//=============================================================================
void NET_SendPacket (int length, void *data, netadr_t to)
{
	int ret;
	int outlen;
	struct sockaddr_in	addr;
	char string[120];

	NetadrToSockadr (&to, &addr);
	HuffEncode((unsigned char *)data,huffbuff,length,&outlen);

#ifdef _DEBUG
	sprintf(string,"in: %d  out: %d  ratio: %f\n",HuffIn, HuffOut, 1-(float)HuffOut/(float)HuffIn);
	OutputDebugString(string);

	CalcFreq((unsigned char *)data, length);
#endif

	ret = sendto (net_socket, (char *) huffbuff, outlen, 0, (struct sockaddr *)&addr, sizeof(addr) );
	if (ret == -1)
	{
		int errno = WSAGetLastError();

		Con_Printf ("NET_SendPacket ERROR: %i", errno);
	}
}
Exemple #3
0
void NET_SendPacket(int length, byte *data, netadr_t to)
{
    int ret;
    struct sockaddr_in addr;

    NetadrToSockadr(&to, &addr);

    ret = sendto(net_socket, (const char*)data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );

    if (ret == -1)
    {
#ifdef _WIN32
		  int err = WSAGetLastError();

		  if (err == WSAEWOULDBLOCK)
			  return;
#else
          if (errno == EWOULDBLOCK)
              return;
          if (errno == ECONNREFUSED)
              return;
          printf("NET_SendPacket: %s\n", strerror(errno));
#endif
    }
}
const char *NET_AdrToString(netadr_t a)
{
	static char s[NET_ADDRSTRMAXLEN];

	if (a.type == NA_LOOPBACK)
	{
		Com_sprintf(s, sizeof(s), "loopback");
	}
	else if (a.type == NA_BOT)
	{
		Com_sprintf(s, sizeof(s), "bot");
	}
	else if (a.type == NA_IP)
	{
		// Port has to be returned along with ip address because of compatibility
		Com_sprintf(s, sizeof(s), "%i.%i.%i.%i:%hu",
		            a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port));
	}
#ifdef FEATURE_IPV6
	else if (a.type == NA_IP6)
	{
		// FIXME: add port for compatibility
		// (joining a server through the server browser)
		struct sockaddr_storage sadr;

		memset(&sadr, 0, sizeof(sadr));
		NetadrToSockadr(&a, (struct sockaddr *) &sadr);
		Sys_SockaddrToString(s, sizeof(s), (struct sockaddr *) &sadr);
	}
#endif

	return s;
}
Exemple #5
0
void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to) {
	int ret;
	struct sockaddr_in	addr;
	int net_socket;

	if (to.type == NA_LOOPBACK) {
		NET_SendLoopPacket (sock, length, data, to);
		return;
	}

	net_socket = ip_sockets[sock];
	if (net_socket == -1)
		return;

	NetadrToSockadr (&to, &addr);

	ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
	if (ret == -1) {
		if (errno == EWOULDBLOCK)
			return;
		if (errno == ECONNREFUSED)
			return;
		Sys_Printf ("NET_SendPacket: %s\n", strerror(errno));
	}
}
Exemple #6
0
// Returns true if we can't bind the address locally--in other words, 
// the IP is NOT one of our interfaces.
qboolean NET_IsClientLegal(netadr_t *adr)
{
	struct sockaddr_in sadr;
	int newsocket;

#if 0
	if (adr->ip[0] == 127)
		return false; // no local connections period

	NetadrToSockadr (adr, &sadr);

	if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
		Sys_Error ("NET_IsClientLegal: socket:", strerror(errno));

	sadr.sin_port = 0;

	if( bind (newsocket, (void *)&sadr, sizeof(sadr)) == -1) 
	{
		// It is not a local address
		close(newsocket);
		return true;
	}
	close(newsocket);
	return false;
#else
	return true;
#endif
}
Exemple #7
0
/*
==================
Sys_SendPacket
==================
*/
void Sys_SendPacket( int length, const void* data, netadr_t to )
{
	int             ret = SOCKET_ERROR;
	struct sockaddr_storage addr;
	
	if ( to.type != NA_BROADCAST && to.type != NA_IP && to.type != NA_IP6 && to.type != NA_MULTICAST6 )
	{
		Com_Error( ERR_FATAL, "Sys_SendPacket: bad address type" );
		return;
	}
	
	if ( ( ip_socket == INVALID_SOCKET && to.type == NA_IP ) ||
			( ip_socket == INVALID_SOCKET && to.type == NA_BROADCAST ) ||
			( ip6_socket == INVALID_SOCKET && to.type == NA_IP6 ) ||
			( ip6_socket == INVALID_SOCKET && to.type == NA_MULTICAST6 ) )
		return;
		
	if ( to.type == NA_MULTICAST6 && ( net_enabled->integer & NET_DISABLEMCAST ) )
		return;
		
	memset( &addr, 0, sizeof( addr ) );
	NetadrToSockadr( &to, ( struct sockaddr* ) &addr );
	
	if ( usingSocks && to.type == NA_IP )
	{
		socksBuf[0] = 0;    // reserved
		socksBuf[1] = 0;
		socksBuf[2] = 0;    // fragment (not fragmented)
		socksBuf[3] = 1;    // address type: IPV4
		*( int* )&socksBuf[4] = ( ( struct sockaddr_in* )&addr )->sin_addr.s_addr;
		*( short* )&socksBuf[8] = ( ( struct sockaddr_in* )&addr )->sin_port;
		memcpy( &socksBuf[10], data, length );
		ret = sendto( ip_socket, socksBuf, length + 10, 0, &socksRelayAddr, sizeof( socksRelayAddr ) );
	}
	else
	{
		if ( addr.ss_family == AF_INET )
			ret = sendto( ip_socket, ( const char* )data, length, 0, ( struct sockaddr* ) &addr, sizeof( struct sockaddr_in ) );
		else if ( addr.ss_family == AF_INET6 )
			ret = sendto( ip6_socket, ( const char* )data, length, 0, ( struct sockaddr* ) &addr, sizeof( struct sockaddr_in6 ) );
	}
	if ( ret == SOCKET_ERROR )
	{
		int err = socketError;
		
		// wouldblock is silent
		if ( err == EAGAIN )
		{
			return;
		}
		
		// some PPP links do not allow broadcasts and return an error
		if ( ( err == EADDRNOTAVAIL ) && ( ( to.type == NA_BROADCAST ) ) )
		{
			return;
		}
		
		Com_Printf( "Sys_SendPacket: %s\n", NET_ErrorString() );
	}
}
Exemple #8
0
DWORD WINAPI SB_PingTree_SendQueryThread(void *thread_arg)
{
	proxy_request_queue *queue = (proxy_request_queue *) thread_arg;
	int i, ret;
	double interval_ms = (1.0 / sb_proxinfopersec.value) * 1000.0;
	timerresolution_session_t timersession = {0, 0};

	Sys_TimerResolution_InitSession(&timersession);
	Sys_TimerResolution_RequestMinimum(&timersession);

	for (i = 0; i < queue->items; i++) {
		if (!queue->data[i].done) {
			struct sockaddr_storage addr_to;
			netadr_t netadr = SB_NodeNetadr_Get(queue->data[i].nodeid);

			NetadrToSockadr(&netadr, &addr_to);
			ret = sendto(queue->data[i].sock,
				PROXY_PINGLIST_QUERY, PROXY_PINGLIST_QUERY_LEN, 0,
				(struct sockaddr *) &addr_to, sizeof (struct sockaddr));
			if (ret < 0) {
				Com_DPrintf("SB_PingTree_SendQueryThread sendto returned %d\n", ret);
			}
			Sys_MSleep(interval_ms);
		}

		if (queue->allrecved) break;
	}

	Sys_TimerResolution_Clear(&timersession);

	queue->sending_done = true;

	return 0;
}
Exemple #9
0
void NET_SendPacket (buf_t &buf, netadr_t &to)
{
    int                   ret;
    struct sockaddr_in    addr;

    NetadrToSockadr (&to, &addr);

	ret = sendto (net_socket, (const char *)buf.ptr(), buf.size(), 0, (struct sockaddr *)&addr, sizeof(addr));

	buf.clear();

    if (ret == -1)
    {
#ifdef _WIN32
          int err = WSAGetLastError();

          // wouldblock is silent
          if (err == WSAEWOULDBLOCK)
              return;
#else
          if (errno == EWOULDBLOCK)
              return;
          if (errno == ECONNREFUSED)
              return;
          Printf (PRINT_HIGH, "NET_SendPacket: %s\n", strerror(errno));
#endif
    }
}
Exemple #10
0
std::string AddressToString( const netadr_t& address, bool with_port )
{

    if ( address.type == netadrtype_t::NA_LOOPBACK )
    {
        return "loopback";
    }
    else if ( address.type == netadrtype_t::NA_BOT )
    {
        return "bot";
    }
    else if ( address.type == netadrtype_t::NA_IP ||
              address.type == netadrtype_t::NA_IP6 ||
              address.type == netadrtype_t::NA_IP_DUAL )
    {
        char s[ NET_ADDR_STR_MAX_LEN ];
        sockaddr_storage sadr = {0};
        NetadrToSockadr( &address, reinterpret_cast<sockaddr*>(&sadr) );
        Sys_SockaddrToString( s, sizeof(s), reinterpret_cast<sockaddr*>(&sadr) );

        std::string result = s;
        if ( with_port )
        {
            if ( NET_IS_IPv6( address.type ) )
            {
                result = '[' + result + ']';
            }
                result += ':' + std::to_string(ntohs(GetPort(address)));
        }
        return result;
    }

    return "";
}
Exemple #11
0
/*
==================
Sys_SendPacket
==================
*/
void Sys_SendPacket( int length, const void *data, netadr_t to ) {
	int				ret;
	struct sockaddr	addr;
	SOCKET			net_socket;

	if( to.type == NA_BROADCAST ) {
		net_socket = ip_socket;
	}
	else if( to.type == NA_IP ) {
		net_socket = ip_socket;
	}
	else if( to.type == NA_IPX ) {
		net_socket = ipx_socket;
	}
	else if( to.type == NA_BROADCAST_IPX ) {
		net_socket = ipx_socket;
	}
	else {
		Com_Error( ERR_FATAL, "Sys_SendPacket: bad address type" );
		return;
	}

	if( !net_socket ) {
		return;
	}

	NetadrToSockadr( &to, &addr );

	if( usingSocks && to.type == NA_IP ) {
		socksBuf[0] = 0;	// reserved
		socksBuf[1] = 0;
		socksBuf[2] = 0;	// fragment (not fragmented)
		socksBuf[3] = 1;	// address type: IPV4
		*(int *)&socksBuf[4] = ((struct sockaddr_in *)&addr)->sin_addr.s_addr;
		*(short *)&socksBuf[8] = ((struct sockaddr_in *)&addr)->sin_port;
		memcpy( &socksBuf[10], data, length );
		ret = sendto( net_socket, socksBuf, length+10, 0, &socksRelayAddr, sizeof(socksRelayAddr) );
	}
	else {
		ret = sendto( net_socket, (const char *)data, length, 0, &addr, sizeof(addr) );
	}
	if( ret == SOCKET_ERROR ) {
		int err = WSAGetLastError();

		// wouldblock is silent
		if( err == WSAEWOULDBLOCK ) {
			return;
		}

		// some PPP links do not allow broadcasts and return an error
		if( ( err == WSAEADDRNOTAVAIL ) && ( ( to.type == NA_BROADCAST ) || ( to.type == NA_BROADCAST_IPX ) ) ) {
			return;
		}

		Com_Printf( "NET_SendPacket: %s\n", NET_ErrorString() );
	}
}
/*
==================
idTCP::Init
==================
*/
bool idTCP::Init( const char *host, short port )
{
    struct sockaddr_in sadr;
    if ( !Sys_StringToNetAdr( host, &address, true ) )
    {
        common->Printf( "Couldn't resolve server name \"%s\"\n", host );
        return false;
    }
    address.type = NA_IP;
    if (!address.port)
    {
        address.port = port;
    }
    common->Printf( "\"%s\" resolved to %i.%i.%i.%i:%i\n", host,
                    address.ip[0], address.ip[1], address.ip[2], address.ip[3],  address.port );
    NetadrToSockadr(&address, &sadr);

    if (fd)
    {
        common->Warning("idTCP::Init: already initialized?\n");
    }

    if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
    {
        fd = 0;
        common->Printf("ERROR: idTCP::Init: socket: %s\n", strerror(errno));
        return false;
    }

    if ( connect( fd, (const sockaddr *)&sadr, sizeof( sadr ) ) == -1 )
    {
        common->Printf( "ERROR: idTCP::Init: connect: %s\n", strerror( errno ) );
        close( fd );
        fd = 0;
        return false;
    }

    int status;
    if ((status = fcntl(fd, F_GETFL, 0)) != -1)
    {
        status |= O_NONBLOCK; /* POSIX */
        status = fcntl(fd, F_SETFL, status);
    }
    if (status == -1)
    {
        common->Printf("ERROR: idTCP::Init: fcntl / O_NONBLOCK: %s\n", strerror(errno));
        close(fd);
        fd = 0;
        return false;
    }

    common->DPrintf("Opened TCP connection\n");
    return true;
}
Exemple #13
0
void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to)
{
	int		ret;
	struct sockaddr_in	addr;
	int		net_socket;

	if ( to.type == NA_LOOPBACK )
	{
		NET_SendLoopPacket (sock, length, data, to);
		return;
	}

	if (to.type == NA_BROADCAST)
	{
		net_socket = ip_sockets[sock];
		if (!net_socket)
			return;
	}
	else if (to.type == NA_IP)
	{
		net_socket = ip_sockets[sock];
		if (!net_socket)
			return;
	}
	else if (to.type == NA_IPX)
	{
		net_socket = ipx_sockets[sock];
		if (!net_socket)
			return;
	}
	else if (to.type == NA_BROADCAST_IPX)
	{
		net_socket = ipx_sockets[sock];
		if (!net_socket)
			return;
	}
	else
		Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");

	NetadrToSockadr (&to, &addr);

// >>> FIX: For Nintendo Wii using devkitPPC / libogc
// Switching to the equivalent function in the platform:
	//ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
	//if (ret == -1)
	ret = net_sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, 8);
	if (ret < 0)
// <<< FIX
	{
		Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
				NET_AdrToString (to));
	}
}
Exemple #14
0
int
UDP_Write(int socket, const void *buf, int len, const netadr_t *addr)
{
    struct sockaddr_in saddr;
    int ret;

    NetadrToSockadr(addr, &saddr);
    ret = sendto(socket, buf, len, 0, (struct sockaddr *)&saddr, sizeof(saddr));
    if (ret == -1 && errno == EWOULDBLOCK)
	return 0;
    return ret;
}
Exemple #15
0
/*
==================
Sys_SendVoicePacket
==================
*/
void Sys_SendVoicePacket( int length, const void *data, netadr_t to ) {
    int				ret;
    struct sockaddr	addr;

    // check for valid packet intentions (direct send or broadcast)
    //
    if( to.type != NA_IP && to.type != NA_BROADCAST )
    {
        Com_Error( ERR_FATAL, "Sys_SendVoicePacket: bad address type" );
        return;
    }

    // check we have our voice socket set up
    //
    if( v_socket == INVALID_SOCKET) {
        return;
    }

    NetadrToSockadr( &to, &addr );
#ifdef SOF2_METRICS
    gXBL_NumberVoicePacketsSent++;
    gXBL_SizeVoicePacketsSent += length;
#endif
    /*if( usingSocks && to.type == NA_IP ) {
    	vsocksBuf[0] = 0;	// reserved
    	vsocksBuf[1] = 0;
    	vsocksBuf[2] = 0;	// fragment (not fragmented)
    	vsocksBuf[3] = 1;	// address type: IPV4
    	*(int *)&vsocksBuf[4] = ((struct sockaddr_in *)&addr)->sin_addr.s_addr;
    	*(short *)&vsocksBuf[8] = ((struct sockaddr_in *)&addr)->sin_port;
    	memcpy( &vsocksBuf[10], data, length );
    	ret = sendto( v_socket, vsocksBuf, length+10, 0, &socksRelayAddr, sizeof(socksRelayAddr) );
    }
    else {*/
    ret = sendto( v_socket, (const char *)data, length, 0, &addr, sizeof(addr) );
    //}

    if( ret == SOCKET_ERROR ) {
        int err = WSAGetLastError();

        // wouldblock is silent
        if( err == WSAEWOULDBLOCK ) {
            return;
        }

        // some PPP links do not allow broadcasts and return an error
        if( ( err == WSAEADDRNOTAVAIL ) && ( ( to.type == NA_BROADCAST ) || ( to.type == NA_BROADCAST_IPX ) ) ) {
            return;
        }

        Com_DPrintf( "NET_SendVoicePacket: %s\n", NET_ErrorString() );
    }
}
Exemple #16
0
void NET_SendPacket (netsrc_t sock, int length, void *data, netadr_t to)
{
	int		ret;
	struct sockaddr_in	addr;
	int		net_socket;

	if ( to.type == NA_LOOPBACK )
	{
		NET_SendLoopPacket (sock, length, data, to);
		return;
	}

	if (to.type == NA_BROADCAST)
	{
		net_socket = ip_sockets[sock];
		if (!net_socket)
			return;
	}
	else if (to.type == NA_IP)
	{
		net_socket = ip_sockets[sock];
		if (!net_socket)
			return;
	}
	else if (to.type == NA_IPX)
	{
		net_socket = ipx_sockets[sock];
		if (!net_socket)
			return;
	}
	else if (to.type == NA_BROADCAST_IPX)
	{
		net_socket = ipx_sockets[sock];
		if (!net_socket)
			return;
	}
	else 
	{
		Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
		return;
	}	

	NetadrToSockadr (&to, &addr);

	ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
	if (ret == -1)
	{
		Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
				NET_AdrToString (to));
	}
}
Exemple #17
0
void NET_SendPacket (int length, void *data, netadr_t to)
{
	int ret;
	struct sockaddr_in	addr;

	NetadrToSockadr (&to, &addr);

	ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
	if (ret == -1) {
		if (errno == EWOULDBLOCK)
			return;
		if (errno == ECONNREFUSED)
			return;
		Sys_Printf ("NET_SendPacket: %s\n", strerror(errno));
	}
}
Exemple #18
0
const char	*NET_AdrToString (netadr_t a)
{
	static	char	s[NET_ADDRSTRMAXLEN];

	if (a.type == NA_LOOPBACK)
		Com_sprintf (s, sizeof(s), "loopback");
	else if (a.type == NA_IP || a.type == NA_IP6)
	{
		struct sockaddr_storage sadr;
	
		memset(&sadr, 0, sizeof(sadr));
		NetadrToSockadr(&a, (struct sockaddr *) &sadr);
		Sys_SockaddrToString(s, sizeof(s), (struct sockaddr *) &sadr);
	}

	return s;
}
Exemple #19
0
int NET_SendPacket (netsrc_t sock, int length, const void *data, netadr_t *to)
{
	int		net_socket;

	if (to->type == NA_IP)
	{
		net_socket = ip_sockets[sock];
		if (!net_socket)
			return 0;
	}
#ifndef DEDICATED_ONLY
	else if ( to->type == NA_LOOPBACK )
	{
		NET_SendLoopPacket (sock, length, data);
		return 1;
	}
#endif
	else if (to->type == NA_BROADCAST)
	{
		net_socket = ip_sockets[sock];
		if (!net_socket)
			return 0;
	}
	else
	{
		Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
		return 0;
	}

	struct sockaddr_in	addr;
	NetadrToSockadr (to, &addr);

	assert(length > 0);
	assert(length < 0x10000);

	uint16_t size = length;
	fuzzWrite(reinterpret_cast<const char *>(&size), sizeof(size));
	fuzzWrite(reinterpret_cast<const char *>(to),    sizeof(*to));
	fuzzWrite(reinterpret_cast<const char *>(data),  size);

	return 0;
}
void GetServerInfo(server_data *serv)
{
    socket_t newsocket;
    struct sockaddr_storage server;
    int ret;
    char answer[5000];
    fd_set fd;
    struct timeval tv;

    // so we have a socket
    newsocket = UDP_OpenSocket(PORT_ANY);
    NetadrToSockadr (&(serv->address), &server);

    // send status request
    ret = sendto (newsocket, senddata, sizeof(senddata), 0,
                  (struct sockaddr *)&server, sizeof(server) );

    if (ret == -1)
        return;

    //fd.fd_count = 1;
    //fd.fd_array[0] = newsocket;
    FD_ZERO(&fd);
    FD_SET(newsocket, &fd);
    tv.tv_sec = 0;
    tv.tv_usec = 1000 * 1.5 * sb_infotimeout.value; // multiply timeout by 1.5
    ret = select(newsocket+1, &fd, NULL, NULL, &tv);

    // get answer
    if (ret > 0)
        ret = recvfrom (newsocket, answer, 5000, 0, NULL, NULL);

    if (ret > 0  &&  ret < 5000)
    {
        answer[ret] = 0;
        server_during_update = 1;
        Reset_Server(serv);
        Parse_Serverinfo(serv, answer);
        server_during_update = 0;
    }
    closesocket(newsocket);
}
Exemple #21
0
/*
==================
idPort::SendPacket
==================
*/
void idPort::SendPacket( const netadr_t to, const void *data, int size ) {
	int ret;
	struct sockaddr_in addr;

	if ( to.type == NA_BAD ) {
		common->Warning( "idPort::SendPacket: bad address type NA_BAD - ignored" );
		return;
	}

	if ( !netSocket ) {
		return;
	}

	NetadrToSockadr( &to, &addr );

	ret = sendto( netSocket, data, size, 0, (struct sockaddr *) &addr, sizeof(addr) );
	if ( ret == -1 ) {
		common->Printf( "idPort::SendPacket ERROR: to %s: %s\n", Sys_NetAdrToString( to ), strerror( errno ) );
	}
}
Exemple #22
0
int NET_SendPacket (netsrc_t sock, int length, const void *data, netadr_t *to)
{
	int		net_socket;
	if (to->type == NA_IP)
	{
		net_socket = ip_sockets[sock];
		if (!net_socket)
			return 0;
	}
	else if ( to->type == NA_LOOPBACK )
	{
		NET_SendLoopPacket (sock, length, data);
		return 1;
	}
	else if (to->type == NA_BROADCAST)
	{
		net_socket = ip_sockets[sock];
		if (!net_socket)
			return 0;
	}
	else
	{
		Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
		return 0;
	}

	struct sockaddr_in	addr;
	NetadrToSockadr (to, &addr);

	int ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
	if (ret == -1)
	{
		Com_Printf ("NET_SendPacket to %s: ERROR: %s\n", LOG_NET, NET_AdrToString(to), NET_ErrorString());
		return 0;
	}

	net_packets_out++;
	net_total_out += ret;
	return 1;
}
Exemple #23
0
const char *NET_AdrToString(netadr_t a)
{
	static char s[NET_ADDRSTRMAXLEN];

	switch (a.type)
	{
	case NA_LOOPBACK:
		Com_sprintf(s, sizeof(s), "loopback");
		break;
	case NA_BOT:
		Com_sprintf(s, sizeof(s), "bot");
		break;
	case NA_IP:
		// Port has to be returned along with ip address because of compatibility
		Com_sprintf(s, sizeof(s), "%i.%i.%i.%i:%hu",
		            a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port));
		break;
#ifdef FEATURE_IPV6
	case NA_IP6:
	{
		// FIXME: add port for compatibility
		// (joining a server through the server browser)
		// Needs to be [ip]:port since : is a valid entry in ipv6
		struct sockaddr_storage sadr;

		memset(&sadr, 0, sizeof(sadr));
		NetadrToSockadr(&a, (struct sockaddr *) &sadr);
		Sys_SockaddrToString(s, sizeof(s), (struct sockaddr *) &sadr);
		break;
	}
	break;
#endif
	default:
		Com_Printf("NET_AdrToString: Unknown address type: %i\n", a.type);
		break;
	}

	return s;
}
Exemple #24
0
int TCP_OpenStream (netadr_t remoteaddr)
{
	unsigned long _true = true;
	int newsocket;
	int temp;
	struct sockaddr_storage qs;

	NetadrToSockadr(&remoteaddr, &qs);
	temp = sizeof(struct sockaddr_in);

	if ((newsocket = socket (((struct sockaddr_in*)&qs)->sin_family, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
		Con_Printf ("TCP_OpenStream: socket: (%i): %s\n", qerrno, strerror(qerrno));
		return INVALID_SOCKET;
	}

	if (connect (newsocket, (struct sockaddr *)&qs, temp) == INVALID_SOCKET) {
		Con_Printf ("TCP_OpenStream: connect: (%i): %s\n", qerrno, strerror(qerrno));
		closesocket(newsocket);
		return INVALID_SOCKET;
	}

#ifndef _WIN32
	if ((fcntl (newsocket, F_SETFL, O_NONBLOCK)) == -1) { // O'Rly?! @@@
		Con_Printf ("TCP_OpenStream: fcntl: (%i): %s\n", qerrno, strerror(qerrno));
		closesocket(newsocket);
		return INVALID_SOCKET;
	}
#endif

	if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) { // make asynchronous
		Con_Printf ("TCP_OpenStream: ioctl: (%i): %s\n", qerrno, strerror(qerrno));
		closesocket(newsocket);
		return INVALID_SOCKET;
	}

	return newsocket;
}
Exemple #25
0
void NET_SendPacket (buf_t &buf, netadr_t &to)
{
    int                   ret;
    struct sockaddr_in    addr;

	// [SL] 2011-07-06 - Don't try to send a packet if we're not really connected
	// (eg, a netdemo is being played back)
	if (simulated_connection)
	{
		buf.clear();
		return;
	}

    NetadrToSockadr (&to, &addr);

	ret = sendto (inet_socket, (const char *)buf.ptr(), buf.size(), 0, (struct sockaddr *)&addr, sizeof(addr));

	buf.clear();

    if (ret == -1)
    {
#ifdef _WIN32
          int err = WSAGetLastError();

          // wouldblock is silent
          if (err == WSAEWOULDBLOCK)
              return;
#else
          if (errno == EWOULDBLOCK)
              return;
          if (errno == ECONNREFUSED)
              return;
          Printf (PRINT_HIGH, "NET_SendPacket: %s\n", strerror(errno));
#endif
    }
}
Exemple #26
0
qbool NET_SendUDPPacket (netsrc_t netsrc, int length, void *data, netadr_t to)
{
	struct sockaddr_storage addr;
	int ret;
	int socket = NET_GetSocket(netsrc, false);

	if (socket == INVALID_SOCKET)
		return false;

	NetadrToSockadr (&to, &addr);

	ret = sendto (socket, data, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
	if (ret == -1)
	{
		int err = qerrno;

		if (err == EWOULDBLOCK || err == ECONNREFUSED || err == EADDRNOTAVAIL)
			; // nothing
		else
			Con_Printf ("NET_SendPacket: sendto: (%i): %s %i\n", err, strerror(err), socket);
	}

	return true;
}
Exemple #27
0
void NET_SendPacket(size_t length, void *data, netadr_t to)
{
	int ret;
	struct sockaddr_in	addr;

	NetadrToSockadr (&to, &addr);

	ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
	if (ret == -1)
	{
		int err = WSAGetLastError();

// wouldblock is silent
        if (err == WSAEWOULDBLOCK)
	        return;

#ifndef SERVERONLY
		if (err == WSAEADDRNOTAVAIL)
			Con_DPrintf("NET_SendPacket Warning: %i\n", err);
		else
#endif
			Con_Printf ("NET_SendPacket ERROR: %i\n", errno);
	}
}
DWORD WINAPI GetServerInfosProc(void * lpParameter)
{
    infohost *hosts;   // 0 if not sent yet, -1 if data read
    double interval, lastsenttime;

    socket_t newsocket;
    struct sockaddr_storage dest;
    int ret, i;
    fd_set fd;
    struct timeval timeout;

    if (abort_ping)
        return 0;

    // so we have a socket
    newsocket = UDP_OpenSocket(PORT_ANY);

    hosts = (infohost *) Q_malloc (serversn * sizeof(infohost));
    for (i=0; i < serversn; i++)
    {
        hosts[i].phase = 0;
        hosts[i].lastsenttime = -1000;
        Reset_Server(servers[i]);

        // do not update dead servers
		if (servers[i]->ping < 0) {
            hosts[i].phase = -1;//(int)sb_inforetries.value;
		}
		// do not update too distant servers
		else if (sb_hidehighping.integer && servers[i]->ping > sb_pinglimit.integer) {
			hosts[i].phase = -1;
		}
    }

    interval = (1000.0 / sb_infospersec.value) / 1000;
    lastsenttime = Sys_DoubleTime() - interval;
    timeout.tv_sec = 0;
    timeout.tv_usec = (long)(interval * 1000.0 * 1000.0 / 2);

    ping_pos = 0;

    while (1  &&  !abort_ping)
    {
        int index = -1;
        double time = Sys_DoubleTime();

        // if it is time to send next request
        if (time > lastsenttime + interval)
        {
            int finished = 0;
            int to_ask = 0;
            int phase = (int)(sb_inforetries.value);

            // find next server to ask
            for (i=0; i < serversn; i++)
            {
                if (hosts[i].phase < phase  &&  hosts[i].phase >= 0  &&
                    time > hosts[i].lastsenttime + (sb_infotimeout.value / 1000))
                {
                    index = i;
                    phase = hosts[i].phase;
                }

                if (hosts[i].phase >= (int)sb_inforetries.value)
                    finished++;
                else
                    if (hosts[i].phase >= 0)
                        to_ask++;
            }
            //ping_pos = finished / (double)serversn;
            ping_pos = (finished+to_ask <= 0) ? 0 :
            finished / (double)(finished+to_ask);
        }

        // check if we should finish
        if (index < 0)
            if (time > lastsenttime + 1.2 * (sb_infotimeout.value / 1000))
                break;

        // send status request
        if (index >= 0)
        {
            hosts[index].phase ++;
            hosts[index].lastsenttime = time;
            lastsenttime = time;

            NetadrToSockadr (&(servers[index]->address), &dest);

            ret = sendto (newsocket, senddata, sizeof(senddata), 0,
                          (struct sockaddr *)&dest, sizeof(*(struct sockaddr *)&dest));
            if(ret < 0)
            {
                Com_DPrintf("sendto() gave errno = %d : %s\n", errno, strerror(errno));
            }
            if (ret == -1)
                ;//return;

            // requests_sent++;
            // ping_pos = requests_total <= 0 ? 0 : requests_sent / (double)requests_total;
        }

        // check if answer arrived and decode it
        //fd.fd_count = 1;
        //fd.fd_array[0] = newsocket;
        FD_ZERO(&fd);
        FD_SET(newsocket, &fd);

        ret = select(newsocket+1, &fd, NULL, NULL, &timeout);
        if (ret < 1)
        {
            Com_DPrintf("select() gave errno = %d : %s\n", errno, strerror(errno));
        }

        if (FD_ISSET(newsocket, &fd))
        {
            struct sockaddr_storage hostaddr;
            netadr_t from;
            int i;
            char answer[5000];
            answer[0] = 0;

            i = sizeof(hostaddr);
            ret = recvfrom (newsocket, answer, 5000, 0, (struct sockaddr *)&hostaddr, (socklen_t *)&i);
            answer[max(0, min(ret, 4999))] = 0;

            if (ret > 0)
            {
                SockadrToNetadr (&hostaddr, &from);

                for (i=0; i < serversn; i++)
                    if (from.ip[0] == servers[i]->address.ip[0] &&
                        from.ip[1] == servers[i]->address.ip[1] &&
                        from.ip[2] == servers[i]->address.ip[2] &&
                        from.ip[3] == servers[i]->address.ip[3] &&
                        from.port == servers[i]->address.port)
                    {
                        hosts[i].phase = (int)sb_inforetries.value;
                        Parse_Serverinfo(servers[i], answer);
                        break;
                    }
            }
        }
    }

    // reset pings to 999 if server didn't answer
    for (i=0; i < serversn; i++)
        if (servers[i]->keysn <= 0)
            SetPing(servers[i], -1);

    closesocket(newsocket);
    Q_free(hosts);

    return 0;
}
DWORD WINAPI Update_Multiple_Sources_Proc(void * lpParameter)
{
    // get servers from master server
    SYSTEMTIME lt;
    char request[] = {'c', '\n', '\0'};

    socket_t newsocket;
	struct sockaddr_storage server;
    int ret = 0, i, sourcenum;
    unsigned char answer[10000];
    fd_set fd;
    struct timeval tv;
    int total_masters = 0;
    int updated = 0;
    int d1, d2;

    GetLocalTime(&lt);
    d1 = lt.wSecond + 60*(lt.wMinute + 60*(lt.wHour + 24*(lt.wDay)));
    // update file sources - this should be a flash
    for (sourcenum = 0; sourcenum < psourcesn; sourcenum++)
        if (psources[sourcenum]->checked)
        {
            if (psources[sourcenum]->type == type_file)
                Update_Source(psources[sourcenum]);
			if (psources[sourcenum]->type == type_url)
				Update_Source(psources[sourcenum]); // todo cache this too
            else if (psources[sourcenum]->type == type_master)
            {
                source_data *s = psources[sourcenum];
                if (s->last_update.wYear != 0  &&  !source_full_update)
                {
                    d2 = s->last_update.wSecond + 60*(s->last_update.wMinute + 60*(s->last_update.wHour + 24*(s->last_update.wDay)));

                    if (d1 > d2  &&  d1 < d2 + sb_sourcevalidity.value*60)
                    continue;
                }
                total_masters++;
            }
        }
	
    // update master sources
    newsocket = UDP_OpenSocket(PORT_ANY);

    for (sourcenum = 0; sourcenum < psourcesn  &&  !abort_ping; sourcenum++)
    {
        server_data *servers[MAX_SERVERS];
        int serversn = 0;
        int trynum = 0;
        source_data *s = psources[sourcenum];
		double timeout;

        if (psources[sourcenum]->type != type_master  ||  !psources[sourcenum]->checked)
            continue;

        if (s->last_update.wYear != 0  &&  !source_full_update)
        {
            d2 = s->last_update.wSecond + 60*(s->last_update.wMinute + 60*(s->last_update.wHour + 24*(s->last_update.wDay)));

            if (d1 > d2  &&  d1 < d2 + sb_sourcevalidity.value*60)
                continue;
        }

		// send trynum queries to master server
        for (trynum=0; trynum < sb_masterretries.value; trynum++)
        {
			NetadrToSockadr (&(s->address.address), &server);
            ret = sendto (newsocket, request, sizeof(request), 0,
                          (struct sockaddr *)&server, sizeof(server) );
		}

		if (ret <= 0)
			continue;

		timeout = Sys_DoubleTime() + (sb_mastertimeout.value / 1000.0);
		while (Sys_DoubleTime() < timeout) {
			struct sockaddr_storage hostaddr;
            netadr_t from;

            //fd.fd_count = 1;
            //fd.fd_array[0] = newsocket;
			FD_ZERO(&fd);
			FD_SET(newsocket, &fd);
            tv.tv_sec = 0;
            tv.tv_usec = 1000 * sb_mastertimeout.value;
            ret = select(newsocket+1, &fd, NULL, NULL, &tv);

            // get answer
            i = sizeof(hostaddr);
            if (ret > 0)
                ret = recvfrom (newsocket, (char *) answer, 10000, 0,
				(struct sockaddr *)&hostaddr, (socklen_t *)&i);

            if (ret > 0  &&  ret < 10000)
            {
                SockadrToNetadr (&hostaddr, &from);

                if (from.ip[0] == s->address.address.ip[0] &&
                    from.ip[1] == s->address.address.ip[1] &&
                    from.ip[2] == s->address.address.ip[2] &&
                    from.ip[3] == s->address.address.ip[3] &&
                    from.port == s->address.address.port)
                {
                    answer[ret] = 0;

                    if (memcmp(answer, "\xff\xff\xff\xff\x64\x0a", 6))
                    {
                        continue;
                    }

                    // create servers avoiding duplicates
					for (i=6; i+5 < ret; i+=6)
					{
						char buf[32];
						server_data* server;
						qbool exists = false;
						int j;

						snprintf(buf, sizeof (buf), "%u.%u.%u.%u:%u",
							(int)answer[i+0], (int)answer[i+1],
							(int)answer[i+2], (int)answer[i+3],
							256 * (int)answer[i+4] + (int)answer[i+5]);

						server = Create_Server(buf);
						for (j=0; j<serversn; j++) {
							if (NET_CompareAdr(servers[j]->address, server->address)) {
								exists = true;
								break;
							}
						}
						
						if (!exists)
							servers[serversn++] = server;
						else
							Delete_Server(server);
					}
                }
            }
		}

        // copy all servers to source list
        if (serversn > 0)
        {
			updated++;

			SB_ServerList_Lock();

            Reset_Source(s);
            s->servers = (server_data **) Q_malloc(serversn * sizeof(server_data *));
            for (i=0; i < serversn; i++)
                s->servers[i] = servers[i];
            s->serversn = serversn;
			s->servers_allocated = serversn;
            if (s->checked)
                rebuild_servers_list = 1;
            GetLocalTime(&(s->last_update));

			SB_ServerList_Unlock();

            if (sb_mastercache.value)
                DumpSource(s);
        }

        ping_pos = updated / (double)total_masters;
    }

    closesocket(newsocket);

	// Not having this here leads to crash almost always when some
	// other action with servers list happens right after this function.
	// Even 1 ms delay was enough during the tests, previously 500 ms was used.
    //Sys_MSleep(100);

    updating_sources = 0;
	sb_queuedtriggers |= SB_TRIGGER_SOURCESUPDATED;
    return 0;
}
void Update_Source(source_data *s)
{
    int i;
    qbool should_dump = false;
    server_data *servers[MAX_SERVERS];
    int serversn = 0;

	if (s->type == type_dummy)
        return;

    if (s->type == type_file)
    {
        // read servers from file
        char name[1024];
        snprintf(name, sizeof (name), "sb/%s", s->address.filename);
        should_dump = Update_Source_From_File(s, name, servers, &serversn);
        GetLocalTime(&(s->last_update));
    }

	if (s->type == type_url)
	{	
		SB_Update_Source_From_URL(s, servers, &serversn);
	}

    if (s->type == type_master)
    {
        // get servers from master server
        char request[] = {'c', '\n', '\0'};

        socket_t newsocket;
		struct sockaddr_storage server;
        int ret = 0, i;
        unsigned char answer[10000];
        fd_set fd;
        struct timeval tv;
		int trynum;
		int timeout;

        newsocket = UDP_OpenSocket(PORT_ANY);
        // so we have a socket

        // send status request

		for (trynum=0; trynum < sb_masterretries.value; trynum++) {
			NetadrToSockadr (&(s->address.address), &server);
			ret = sendto (newsocket, request, sizeof(request), 0,
						  (struct sockaddr *)&server, sizeof(server) );
		}

        if (ret < 0)
            return;

		timeout = Sys_DoubleTime() + (sb_mastertimeout.value / 1000.0);
		while (Sys_DoubleTime() < timeout) {
			//fd.fd_count = 1;
			//fd.fd_array[0] = newsocket;
			FD_ZERO(&fd);
			FD_SET(newsocket, &fd);
			tv.tv_sec = 0;
			tv.tv_usec = 1000 * 1.5 * sb_mastertimeout.value; // multiply timeout by 1.5
			ret = select(newsocket+1, &fd, NULL, NULL, &tv);

			// get answer
			if (ret > 0)
				ret = recvfrom (newsocket, (char *) answer, 10000, 0, NULL, NULL);

			if (ret > 0  &&  ret < 10000)
			{
				answer[ret] = 0;

				if (memcmp(answer, "\xff\xff\xff\xff\x64\x0a", 6))
				{
					closesocket(newsocket);
					return;
				}

				// create servers avoiding duplicates
				for (i=6; i+5 < ret; i+=6)
				{
					char buf[32];
					server_data* server;
					qbool exists = false;
					int j;

					snprintf(buf, sizeof (buf), "%u.%u.%u.%u:%u",
						(int)answer[i+0], (int)answer[i+1],
						(int)answer[i+2], (int)answer[i+3],
						256 * (int)answer[i+4] + (int)answer[i+5]);

					server = Create_Server(buf);
					for (j=0; j<serversn; j++) {
						if (NET_CompareAdr(servers[j]->address, server->address)) {
							exists = true;
							break;
						}
					}
					
					if (!exists)
						servers[serversn++] = server;
					else
						Delete_Server(server);
				}
			}
		}
 
        closesocket(newsocket);
        
    }

	SB_ServerList_Lock();
    // copy all servers to source list
    if (serversn > 0)
    {
        Reset_Source(s);
        s->servers = (server_data **) Q_malloc((serversn + (s->type==type_file ? MAX_UNBOUND : 0)) * sizeof(server_data *));
		for (i=0; i < serversn; i++)
			s->servers[i] = servers[i];
        s->serversn = serversn;
		s->servers_allocated = serversn + (s->type == type_file ? MAX_UNBOUND : 0);

        if (s->checked)
            rebuild_servers_list = 1;

        if (sb_mastercache.value)
		{
			DumpSource(s);
			should_dump = false;
		}
        GetLocalTime(&(s->last_update));
    }
    else
        if (s->type == type_file)
        {
            Reset_Source(s);
            s->servers = (server_data **) Q_malloc((serversn + (s->type==type_file ? MAX_UNBOUND : 0)) * sizeof(server_data *));
        }
	SB_ServerList_Unlock();
    if (should_dump)
        DumpSource(s);
    //Com_Printf ("Updating %15.15s: %d servers\n", s->name, serversn);
}