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"); }
/* ==================== 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"); }
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"); }
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; } } }
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); }
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; }
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); }
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; } } }
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; }
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; }
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; }
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); }
/* ==================== 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"); }
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 }
/* ==================== 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 */ }
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; }
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; }
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(<); 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); }