예제 #1
0
void NET_InitClient(void)
{
	int port = PORT_CLIENT;
	int p;

	p = COM_CheckParm ("-clientport");
	if (p && p < COM_Argc()) {
		port = atoi(COM_Argv(p+1));
	}

	if (cls.socketip == INVALID_SOCKET)
		cls.socketip = UDP_OpenSocket (port);

	if (cls.socketip == INVALID_SOCKET)
		cls.socketip = UDP_OpenSocket (PORT_ANY); // any dynamic port

	if (cls.socketip == INVALID_SOCKET)
		Sys_Error ("Couldn't allocate client socket");

	// init the message buffer
	SZ_Init (&net_message, net_message_buffer, sizeof(net_message_buffer));

	// determine my name & address
	NET_GetLocalAddress (cls.socketip, &net_local_cl_ipadr);

	Com_Printf_State (PRINT_OK, "Client port Initialized\n");
}
예제 #2
0
파일: net_wins.c 프로젝트: barryp/qwpython
/*
====================
NET_Init
====================
*/
void NET_Init (int port)
{
	WORD	wVersionRequested; 
	int		r;

	wVersionRequested = MAKEWORD(1, 1); 

	r = WSAStartup (MAKEWORD(1, 1), &winsockdata);

	if (r)
		Sys_Error ("Winsock initialization failed.");

	//
	// open the single socket to be used for all communications
	//
	net_socket = UDP_OpenSocket (port);

	//
	// init the message buffer
	//
	net_message.maxsize = sizeof(net_message_buffer);
	net_message.data = net_message_buffer;

	//
	// determine my name & address
	//
	NET_GetLocalAddress ();

	Con_Printf("UDP Initialized\n");
}
예제 #3
0
void
NET_Init (int port)
{
#ifdef _WIN32
	int         r;
	WORD        wVersionRequested;

	wVersionRequested = MAKEWORD (1, 1);

	r = WSAStartup (wVersionRequested, &winsockdata);
	if (r)
		Sys_Error ("Winsock initialization failed.");
#endif /* _WIN32 */

	net_socket = UDP_OpenSocket (port);

	// init the message buffer
	_net_message_message.maxsize = sizeof (net_message_buffer);
	_net_message_message.data = net_message_buffer;

	// determine my name & address
	NET_GetLocalAddress ();

	net_loopback_adr.ip[0] = 127;
	net_loopback_adr.ip[3] = 1;

	Sys_Printf ("UDP (IPv4) Initialized\n");
}
예제 #4
0
void NET_ServerConfig (qboolean enable) {
	int i, port;

	if (enable) {
		if (ip_sockets[NS_SERVER] != -1)
			return;

		port = 0;
		i = COM_CheckParm ("-port");
		if (i && i < com_argc)
			port = atoi(com_argv[i+1]);
		if (!port)
			port = PORT_SERVER;

		ip_sockets[NS_SERVER] = UDP_OpenSocket (port);
		if (ip_sockets[NS_SERVER] == -1) {
#ifdef SERVERONLY
			Sys_Error ("Couldn't allocate server socket");
#else
			if (dedicated)
				Sys_Error ("Couldn't allocate server socket");
			else
				Com_Printf ("WARNING: Couldn't allocate server socket.\n");
#endif
		}
	} else {
		if (ip_sockets[NS_SERVER] != -1) {
			close (ip_sockets[NS_SERVER]);
			ip_sockets[NS_SERVER] = -1;
		}
	}
}
예제 #5
0
static void SB_PingTree_ScanProxies(void)
{
	int i;
	proxy_request_queue queue = { NULL, 0, false };
	size_t request = 0;
	FILE *f = NULL;

	for (i = 0; i < ping_nodes_count; i++) {
		if (ping_nodes[i].proxport) {
			queue.items++;
		}
	}

	if (!queue.items) return;

	queue.data = (proxy_query_request_t *) Q_malloc(sizeof(proxy_query_request_t) * queue.items);

	for (i = 0; i < ping_nodes_count; i++) {
		if (ping_nodes[i].proxport) {
			queue.data[request].done = false;
			queue.data[request].nodeid = i;
			queue.data[request].sock = UDP_OpenSocket(NA_IPv4, PORT_ANY);
			request++;
		}
	}

	if (sb_listcache.value) {
		f = fopen(va("%s/%s", com_homedir, "proxies_data"), "wb");
		if (f)
			SB_Proxylist_Serialize_Start(f);
	}

	for (i = 0; i < sb_proxretries.integer; i++) {
		queue.sending_done = false;
		Sys_CreateThread(SB_PingTree_SendQueryThread, (void *) &queue);
		SB_PingTree_RecvQuery(&queue, f);
		if (queue.allrecved) {
			break;
		}
	}

	if (f) {
		SB_Proxylist_Serialize_End(f);
		fclose(f);
	}

	while (!queue.sending_done) {
		// XXX: use semaphore instead
		Sys_MSleep(100);
	}

	for (i = 0; i < queue.items; i++) {
		closesocket(queue.data[i].sock);
	}

	Q_free(queue.data);
}
예제 #6
0
int UDP_Init (void)
{
	struct hostent *local;
	char	buff[MAXHOSTNAMELEN];
	struct qsockaddr addr;
	char *colon;

	if (COM_CheckParm ("-noudp"))
		return -1;

#if 1 // Android
	AndroidGetAddr();
#else
	// determine my name & address
	gethostname(buff, MAXHOSTNAMELEN);
	local = gethostbyname(buff);

	if(!local)
	{
		Con_Printf("Could not gethostbyname(\"%s\")\n", buff);
		return -1;
	}

	myAddr = *(int *)local->h_addr_list[0];

	// if the quake hostname isn't set, set it to the machine name
	if (Q_strcmp(hostname.string, "UNNAMED") == 0)
	{
		buff[15] = 0;
		Cvar_Set ("hostname", buff);
	}
#endif
	if ((net_controlsocket = UDP_OpenSocket (0)) == -1)
		Sys_Error("UDP_Init: Unable to open control socket\n");

	sockaddr_in temp;

	memcpy(&temp, &broadcastaddr, sizeof(temp));

	temp.sin_family = AF_INET;
	temp.sin_addr.s_addr = INADDR_BROADCAST;
	temp.sin_port = htons(net_hostport);

	memcpy(&broadcastaddr, &temp, sizeof(temp));

	UDP_GetSocketAddr (net_controlsocket, &addr);
	Q_strcpy(my_tcpip_address,  UDP_AddrToString (&addr));
	colon = Q_strrchr (my_tcpip_address, ':');
	if (colon)
		*colon = 0;

	Con_Printf("UDP Initialized\n");
	tcpipAvailable = true;

	return net_controlsocket;
}
예제 #7
0
void SB_Proxy_QueryForPingList(const netadr_t *address, proxy_ping_report_callback callback)
{
	socket_t sock;
	char packet[] = PROXY_PINGLIST_QUERY;
	byte buf[PROXY_REPLY_BUFFER_SIZE];
	struct sockaddr_in addr_to, addr_from;
	struct timeval timeout;
	fd_set fd;
	int i, ret;
	socklen_t inaddrlen;
	const char *adrstr = va("%d.%d.%d.%d",
// FIXME IPv4 only
		(int) address->address.ip[0], (int) address->address.ip[1], (int) address->address.ip[2], (int) address->address.ip[3]);

	addr_to.sin_addr.s_addr = inet_addr(adrstr);
	if (addr_to.sin_addr.s_addr == INADDR_NONE) {
		return;
	}
	addr_to.sin_family = AF_INET;
	addr_to.sin_port = address->port;
	sock = UDP_OpenSocket(NA_IPv4, PORT_ANY);
	for (i = 0; i < sb_proxretries.integer; i++) {
		ret = sendto(sock, packet, strlen(packet), 0, (struct sockaddr *)&addr_to, sizeof(struct sockaddr));
		if (ret == -1) // failure, try again
			continue;

_select:
		FD_ZERO(&fd);
		FD_SET(sock, &fd);
		timeout.tv_sec = 0;
		timeout.tv_usec = sb_proxtimeout.integer * 1000;
		ret = select(sock+1, &fd, NULL, NULL, &timeout);
		if (ret <= 0) { // timed out or error
			Com_DPrintf("select() gave errno = %d : %s\n", errno, strerror(errno));
			continue;
		}

		inaddrlen = sizeof(struct sockaddr_in);
		ret = recvfrom(sock, (char *) buf, sizeof(buf), 0, (struct sockaddr *)&addr_from, &inaddrlen);

		if (ret == -1) // failure, try again
			continue;
		if (addr_from.sin_addr.s_addr != addr_to.sin_addr.s_addr) // martian, discard and see if a valid response came in after it
			goto _select;
		if (strncmp("\xff\xff\xff\xffn", (char *) buf, 5) == 0)
			SB_Proxy_ParseReply(buf+5, ret-5, callback);

		break;
	}
	closesocket(sock);
}
예제 #8
0
void NET_ClientConfig (qboolean enable) {
	if (enable) {
		if (ip_sockets[NS_CLIENT] == -1) {
			ip_sockets[NS_CLIENT] = UDP_OpenSocket (qport.value);
			if (ip_sockets[NS_CLIENT] == -1)
				Sys_Error ("Couldn't allocate client socket");
		}
	} else {
		if (ip_sockets[NS_CLIENT] != -1) {
			close (ip_sockets[NS_CLIENT]);
			ip_sockets[NS_CLIENT] = -1;
		}
	}
}
예제 #9
0
void
UDP_Listen(qboolean state)
{
    /* enable listening */
    if (state) {
	if (net_acceptsocket != -1)
	    return;
	if ((net_acceptsocket = UDP_OpenSocket(net_hostport)) == -1)
	    Sys_Error("%s: Unable to open accept socket", __func__);
	return;
    }
    /* disable listening */
    if (net_acceptsocket == -1)
	return;
    UDP_CloseSocket(net_acceptsocket);
    net_acceptsocket = -1;
}
예제 #10
0
void UDP_Listen (qboolean state)
{
	// enable listening
	if (state)
	{
		if (net_acceptsocket != -1)
			return;
		if ((net_acceptsocket = UDP_OpenSocket (net_hostport)) == -1)
			Sys_Error ("UDP_Listen: Unable to open accept socket\n");
		return;
	}

	// disable listening
	if (net_acceptsocket == -1)
		return;
	UDP_CloseSocket (net_acceptsocket);
	net_acceptsocket = -1;
}
예제 #11
0
파일: net_udp.c 프로젝트: luaman/qforge-old
int
UDP_Init ( void )
{
	struct hostent *local;
	char	buff[MAXHOSTNAMELEN];
	struct qsockaddr addr;
	char *colon;

	if (COM_CheckParm ("-noudp"))
		return -1;

	// determine my name & address
	gethostname(buff, MAXHOSTNAMELEN);
	if ((local = gethostbyname(buff)) == NULL)
		myAddr = INADDR_LOOPBACK;
	else
		myAddr = *(int *)local->h_addr_list[0];

	// if the quake hostname isn't set, set it to the machine name
	if (Q_strcmp(hostname->string, "UNNAMED") == 0)
	{
		buff[15] = 0;
		Cvar_Set (hostname, buff);
	}

	if ((net_controlsocket = UDP_OpenSocket (0)) == -1)
		Sys_Error("UDP_Init: Unable to open control socket\n");

	((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET;
	((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
	((struct sockaddr_in *)&broadcastaddr)->sin_port = htons(net_hostport);

	UDP_GetSocketAddr (net_controlsocket, &addr);
	Q_strcpy(my_tcpip_address, UDP_AddrToString (&addr));
	colon = Q_strrchr (my_tcpip_address, ':');
	if (colon)
		*colon = 0;

	Con_Printf("UDP Initialized\n");
	tcpipAvailable = true;

	return net_controlsocket;
}
예제 #12
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);
}
예제 #13
0
파일: net_udp.c 프로젝트: ACIIL/Quake
/*
====================
NET_Init
====================
*/
void NET_Init (int port)
{
	//
	// open the single socket to be used for all communications
	//
	net_socket = UDP_OpenSocket (port);

	//
	// init the message buffer
	//
	net_message.maxsize = sizeof(net_message_buffer);
	net_message.data = net_message_buffer;

	//
	// determine my name & address
	//
	NET_GetLocalAddress ();

	Con_Printf("UDP Initialized\n");
}
예제 #14
0
void NET_InitServer (void)
{
	int port = PORT_SERVER;
	int p;

	p = COM_CheckParm ("-port");
	if (p && p < COM_Argc()) {
		port = atoi(COM_Argv(p+1));
	}

	if (svs.socketip == INVALID_SOCKET) {
		svs.socketip = UDP_OpenSocket (port);
	}

	if (svs.socketip != INVALID_SOCKET) {
		NET_GetLocalAddress (svs.socketip, &net_local_sv_ipadr);
		Cvar_SetROM (&sv_local_addr, NET_AdrToString (net_local_sv_ipadr));
	}
	else {
		// FIXME: is it right???
		Cvar_SetROM (&sv_local_addr, "");
	}

	if (svs.socketip == INVALID_SOCKET) {
#ifdef SERVERONLY
		Sys_Error
#else
		Con_Printf
#endif
			("WARNING: Couldn't allocate server socket\n");
	}

#ifndef SERVERONLY
	// init the message buffer
	SZ_Init (&net_message, net_message_buffer, sizeof(net_message_buffer));
#endif
}
예제 #15
0
파일: net_udp.c 프로젝트: MaddTheSane/Quake
/*
====================
NET_Init
====================
*/
void NET_Init (int port)
{
	//
	// open the single socket to be used for all communications
	//
	net_socket = UDP_OpenSocket (port);

	//
	// init the message buffer
	//
	net_message.maxsize = sizeof(net_message_buffer);
	net_message.data = net_message_buffer;

	//
	// determine my name & address
	//
	NET_GetLocalAddress ();

#if !defined (__APPLE__) && !defined (MACOSX)

	Con_Printf("UDP Initialized\n");
        
#endif /* !__APPLE__ &&Ê!MACOSX */
}
예제 #16
0
int
UDP_Init(void)
{
    int i;
    int err;
    char buff[MAXHOSTNAMELEN];
    char *colon;
    struct hostent *local;
    netadr_t addr;

    if (COM_CheckParm("-noudp"))
	return -1;

    /* determine my name & address, default to loopback */
    myAddr.ip.l = htonl(INADDR_LOOPBACK);
    myAddr.port = htons(DEFAULTnet_hostport);
    err = gethostname(buff, MAXHOSTNAMELEN);
    if (err) {
	Con_Printf("%s: WARNING: gethostname failed (%s)\n", __func__,
		   strerror(errno));
    } else {
	buff[MAXHOSTNAMELEN - 1] = 0;
	local = gethostbyname(buff);
	if (!local) {
	    Con_Printf("%s: WARNING: gethostbyname failed (%s)\n", __func__,
			hstrerror(h_errno));
	} else if (local->h_addrtype != AF_INET) {
	    Con_Printf("%s: address from gethostbyname not IPv4\n", __func__);
	} else {
	    struct in_addr *inaddr = (struct in_addr *)local->h_addr_list[0];
	    myAddr.ip.l = inaddr->s_addr;
	}
    }

    i = COM_CheckParm("-ip");
    if (i && i < com_argc - 1) {
	bindAddr.ip.l = inet_addr(com_argv[i + 1]);
	if (bindAddr.ip.l == INADDR_NONE)
	    Sys_Error("%s: %s is not a valid IP address", __func__,
		      com_argv[i + 1]);
	Con_Printf("Binding to IP Interface Address of %s\n", com_argv[i + 1]);
    } else {
	bindAddr.ip.l = INADDR_NONE;
    }

    i = COM_CheckParm("-localip");
    if (i && i < com_argc - 1) {
	localAddr.ip.l = inet_addr(com_argv[i + 1]);
	if (localAddr.ip.l == INADDR_NONE)
	    Sys_Error("%s: %s is not a valid IP address", __func__,
		      com_argv[i + 1]);
	Con_Printf("Advertising %s as the local IP in response packets\n",
		   com_argv[i + 1]);
    } else {
	localAddr.ip.l = INADDR_NONE;
    }

    net_controlsocket = UDP_OpenSocket(0);
    if (net_controlsocket == -1) {
	Con_Printf("%s: Unable to open control socket, UDP disabled\n",
		   __func__);
	return -1;
    }

    /* myAddr may resolve to 127.0.0.1, see if we can do any better */
    memset (ifname, 0, sizeof(ifname));
    if (myAddr.ip.l == htonl(INADDR_LOOPBACK)) {
	if (udp_scan_iface(net_controlsocket) == 0)
	    Con_Printf ("UDP, Local address: %s (%s)\n",
			NET_AdrToString(&myAddr), ifname);
    }
    if (ifname[0] == 0) {
	Con_Printf ("UDP, Local address: %s\n", NET_AdrToString(&myAddr));
    }

    broadcastaddr.ip.l = INADDR_BROADCAST;
    broadcastaddr.port = htons(net_hostport);

    UDP_GetSocketAddr(net_controlsocket, &addr);
    strcpy(my_tcpip_address, NET_AdrToString(&addr));
    colon = strrchr(my_tcpip_address, ':');
    if (colon)
	*colon = 0;

    Con_Printf("UDP Initialized (%s)\n", my_tcpip_address);
    tcpipAvailable = true;

    return net_controlsocket;
}
예제 #17
0
int UDP_Init (void)
{
	struct hostent *local;
	char*	buff;
	struct qsockaddr addr;
	char *colon;
	
	if (COM_CheckParm ("-noudp"))
		return -1;

    // determine my name & address

    struct ifaddrs *allInterfaces;
    
    if (getifaddrs(&allInterfaces) == 0)
    {
        struct ifaddrs *interface;
        
        for (interface = allInterfaces; interface != NULL; interface = interface->ifa_next)
        {
            unsigned int flags = interface->ifa_flags;
            struct sockaddr *addr = interface->ifa_addr;
            
            if ((flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING))
            {
                if (addr->sa_family == AF_INET)
                {
                    buff = malloc(MAXHOSTNAMELEN + 1);
                    getnameinfo(addr, addr->sa_len, buff, MAXHOSTNAMELEN, NULL, 0, NI_NUMERICHOST);

                    if (net_ipaddressescount >= net_ipaddressessize)
                    {
                        int newsize = net_ipaddressescount + 4;
                        char** newipaddresses = malloc(newsize * sizeof(char*));
                        
                        if (net_ipaddresses != NULL)
                        {
                            memcpy(newipaddresses, net_ipaddresses, net_ipaddressescount * sizeof(char*));
                            
                            free(net_ipaddresses);
                        }
                        
                        net_ipaddresses = newipaddresses;
                        net_ipaddressessize = newsize;
                    }
                    
                    net_ipaddresses[net_ipaddressescount] = buff;
                    net_ipaddressescount++;
                }
            }
        }
    
        freeifaddrs(allInterfaces);
        
        if (net_ipaddressescount == 0)
        {
            return -1;
        }
        
        if (net_ipaddress == NULL)
        {
            buff = net_ipaddresses[net_ipaddressescount - 1];
            local = gethostbyname(buff);
            if (local == NULL)
            {
                return -1;
            }
            myAddr = *(int *)local->h_addr_list[0];
        }
        else
        {
            qboolean found = false;
            
            for (int i = 0; i < net_ipaddressescount; i++)
            {
                buff = net_ipaddresses[i];
                
                if (strcmp(net_ipaddress, buff) == 0)
                {
                    local = gethostbyname(buff);
                    if (local == NULL)
                    {
                        return -1;
                    }
                    myAddr = *(int *)local->h_addr_list[0];
                    
                    found = true;
                }
            }
            
            if (!found)
            {
                return -1;
            }
        }
    }
    else
    {
        return -1;
    }

    // if the quake hostname isn't set, set it to the machine name
	if (Q_strcmp(hostname.string, "UNNAMED") == 0)
	{
		buff[15] = 0;
		Cvar_Set ("hostname", buff);
	}

	if ((net_controlsocket = UDP_OpenSocket (0)) == -1)
		Sys_Error("UDP_Init: Unable to open control socket\n");

	((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET;
	((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
	((struct sockaddr_in *)&broadcastaddr)->sin_port = htons(net_hostport);

	UDP_GetSocketAddr (net_controlsocket, &addr);
	Q_strcpy(my_tcpip_address,  UDP_AddrToString (&addr));
	colon = Q_strrchr (my_tcpip_address, ':');
	if (colon)
		*colon = 0;

	Con_Printf("UDP Initialized\n");
	tcpipAvailable = true;

	return net_controlsocket;
}
예제 #18
0
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;
}
예제 #19
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;
}
예제 #20
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);
}