/* ================== idPort::GetPacket ================== */ bool idPort::GetPacket( netadr_t &net_from, void *data, int &size, int maxSize ) { int ret; struct sockaddr_in from; int fromlen; if ( !netSocket ) { return false; } fromlen = sizeof( from ); ret = recvfrom( netSocket, data, maxSize, 0, (struct sockaddr *) &from, (socklen_t *) &fromlen ); if ( ret == -1 ) { if (errno == EWOULDBLOCK || errno == ECONNREFUSED) { // those commonly happen, don't verbose return false; } common->DPrintf( "idPort::GetPacket recvfrom(): %s\n", strerror( errno ) ); return false; } assert( ret < maxSize ); SockadrToNetadr( &from, &net_from ); size = ret; return true; }
void NET_GetLocalAddress (int socket, netadr_t *out) { char buff[512]; struct sockaddr_storage address; size_t namelen; netadr_t adr = {0}; qbool notvalid = false; strlcpy (buff, "localhost", sizeof (buff)); gethostname (buff, sizeof (buff)); buff[sizeof(buff) - 1] = 0; if (!NET_StringToAdr (buff, &adr)) //urm NET_StringToAdr ("127.0.0.1", &adr); namelen = sizeof(address); if (getsockname (socket, (struct sockaddr *)&address, (socklen_t *)&namelen) == -1) { notvalid = true; NET_StringToSockaddr("0.0.0.0", (struct sockaddr_storage *)&address); // Sys_Error ("NET_Init: getsockname:", strerror(qerrno)); } SockadrToNetadr(&address, out); if (!*(int*)out->ip) //socket was set to auto *(int *)out->ip = *(int *)adr.ip; //change it to what the machine says it is, rather than the socket. #ifndef SERVERONLY if (notvalid) Com_Printf_State (PRINT_FAIL, "Couldn't detect local ip\n"); else Com_Printf_State (PRINT_OK, "IP address %s\n", NET_AdrToString (*out)); #endif }
qboolean NET_GetPacket (void) { int ret; struct sockaddr_in from; int fromlen; fromlen = sizeof(from); ret = recvfrom (net_socket,(char *) huffbuff, sizeof(net_message_buffer), 0, (struct sockaddr *)&from, &fromlen); if (ret == -1) { int errno = WSAGetLastError(); if (errno == WSAEWOULDBLOCK) return false; Sys_Error ("NET_GetPacket: %s", strerror(errno)); } SockadrToNetadr (&from, &net_from); if (ret == sizeof(net_message_buffer) ) { Con_Printf ("Oversize packet from %s\n", NET_AdrToString (net_from)); return false; } LastCompMessageSize += ret;//keep track of bytes actually received for debugging HuffDecode(huffbuff, (unsigned char *)net_message_buffer,ret,&ret); net_message.cursize = ret; return ret; }
qboolean NET_GetPacket (void) { int ret; struct sockaddr_in from; int fromlen; fromlen = sizeof(from); ret = recvfrom (net_socket, (char *)net_message_buffer, sizeof(net_message_buffer), 0, (struct sockaddr *)&from, &fromlen); SockadrToNetadr (&from, &net_from); if (ret == -1) { int my_errno = WSAGetLastError(); if (my_errno == WSAEWOULDBLOCK) return false; if (my_errno == WSAEMSGSIZE) { Con_Printf ("Warning: Oversize packet from %s\n", NET_AdrToString (net_from)); return false; } Sys_Error ("NET_GetPacket: %d %s", my_errno, strerror(my_errno)); } net_message.cursize = ret; if (ret == sizeof(net_message_buffer) ) { Con_Printf ("Oversize packet from %s\n", NET_AdrToString (net_from)); return false; } return (qboolean)(ret > 0); }
qboolean NET_GetPacket (netsrc_t sock) { int ret; struct sockaddr_in from; int fromlen; int net_socket; if (NET_GetLoopPacket (sock)) return true; net_socket = ip_sockets[sock]; if (net_socket == -1) return false; fromlen = sizeof(from); ret = recvfrom (net_socket, net_message_buffer, sizeof(net_message_buffer), 0, (struct sockaddr *)&from, &fromlen); if (ret == -1) { if (errno == EWOULDBLOCK) return false; if (errno == ECONNREFUSED) return false; Sys_Printf ("NET_GetPacket: %s\n", strerror(errno)); return false; } net_message.cursize = ret; SockadrToNetadr (&from, &net_from); return ret; }
int UDP_GetSocketAddr(int socket, netadr_t *addr) { struct sockaddr_in saddr; socklen_t len = sizeof(saddr); memset(&saddr, 0, len); getsockname(socket, (struct sockaddr *)&saddr, &len); /* * The returned IP is embedded in our repsonse to a broadcast request for * server info from clients. The server admin may wish to advertise a * specific IP for various reasons, so allow the "default" address * returned by the OS to be overridden. */ if (localAddr.ip.l != INADDR_NONE) saddr.sin_addr.s_addr = localAddr.ip.l; else { struct in_addr a = saddr.sin_addr; if (!a.s_addr || a.s_addr == htonl(INADDR_LOOPBACK)) saddr.sin_addr.s_addr = myAddr.ip.l; } SockadrToNetadr(&saddr, addr); return 0; }
bool NET_StringToAdr (const char *s, netadr_t *a) { struct hostent *h; struct sockaddr_in sadr; char *colon; char copy[256]; memset (&sadr, 0, sizeof(sadr)); sadr.sin_family = AF_INET; sadr.sin_port = 0; strncpy (copy, s, sizeof(copy) - 1); copy[sizeof(copy) - 1] = 0; // strip off a trailing :port if present for (colon = copy ; *colon ; colon++) if (*colon == ':') { *colon = 0; sadr.sin_port = htons(atoi(colon+1)); } if (! (h = gethostbyname(copy)) ) return 0; *(int *)&sadr.sin_addr = *(int *)h->h_addr_list[0]; SockadrToNetadr (&sadr, a); return true; }
/* ============= Sys_StringToAdr ============= */ qboolean Sys_StringToAdr( const char *s, netadr_t *a, netadrtype_t family ) { struct sockaddr_storage sadr; sa_family_t fam; switch ( family ) { case NA_IP: fam = AF_INET; break; case NA_IP6: fam = AF_INET6; break; default: fam = AF_UNSPEC; break; } if ( !Sys_StringToSockaddr( s, ( struct sockaddr * ) &sadr, sizeof( sadr ), fam ) ) { return qfalse; } SockadrToNetadr( ( struct sockaddr * ) &sadr, a ); return qtrue; }
/* ============= Sys_StringToAdr idnewt 192.246.40.70 ============= */ qboolean Sys_StringToAdr( const char *s, netadr_t *a ) { struct sockaddr sadr; if ( !Sys_StringToSockaddr( s, &sadr ) ) { return qfalse; } SockadrToNetadr( &sadr, a ); return qtrue; }
/* ============= Sys_StringToAdr ============= */ bool Sys_StringToNetAdr( const char *s, netadr_t * a, bool doDNSResolve ) { struct sockaddr_in sadr; if ( !StringToSockaddr( s, &sadr, doDNSResolve ) ) { return false; } SockadrToNetadr( &sadr, a ); return true; }
/* ================== idPort::GetPacketBlocking ================== */ bool idPort::GetPacketBlocking( netadr_t &net_from, void *data, int &size, int maxSize, int timeout ) { fd_set set; struct timeval tv; int ret; if ( !netSocket ) { return false; } if ( timeout < 0 ) { return GetPacket( net_from, data, size, maxSize ); } FD_ZERO( &set ); FD_SET( netSocket, &set ); tv.tv_sec = timeout / 1000; tv.tv_usec = ( timeout % 1000 ) * 1000; ret = select( netSocket+1, &set, NULL, NULL, &tv ); if ( ret == -1 ) { if ( errno == EINTR ) { common->DPrintf( "idPort::GetPacketBlocking: select EINTR\n" ); return false; } else { common->Error( "idPort::GetPacketBlocking: select failed: %s\n", strerror( errno ) ); } } if ( ret == 0 ) { // timed out return false; } struct sockaddr_in from; int fromlen; fromlen = sizeof( from ); ret = recvfrom( netSocket, data, maxSize, 0, (struct sockaddr *)&from, (socklen_t *)&fromlen ); if ( ret == -1 ) { // there should be no blocking errors once select declares things are good common->DPrintf( "idPort::GetPacketBlocking: %s\n", strerror( errno ) ); return false; } assert( ret < maxSize ); SockadrToNetadr( &from, &net_from ); size = ret; return true; }
qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) { int ret; struct sockaddr_in from; int fromlen; int net_socket; int protocol; int err; for ( protocol = 0 ; protocol < 2 ; protocol++ ) { /* if ( protocol == 0 ) { //net_socket = ip_socket; } else { //net_socket = ipx_socket; } */ net_socket = (protocol == 0) ? *(int*)0x80E688C : *(int*)0x83C8700; if ( !net_socket ) { continue; } fromlen = sizeof( from ); ret = recvfrom( net_socket, net_message->data, net_message->maxsize , 0, (struct sockaddr *)&from, &fromlen ); SockadrToNetadr( &from, net_from ); // bk000305: was missing net_message->readcount = 0; if ( ret == -1 ) { err = errno; if ( err == EWOULDBLOCK || err == ECONNREFUSED ) { continue; } //Com_Printf( "NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString( *net_from ) ); continue; } if ( ret == net_message->maxsize ) { Com_Printf( "Oversize packet from %s\n", NET_AdrToString( *net_from ) ); continue; } net_message->cursize = ret; SV_NocPacket(*net_from, net_message); return qtrue; } return qfalse; }
qboolean NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { int ret; struct sockaddr_storage from; socklen_t fromlen; int net_socket; int protocol; int err; if (NET_GetLoopPacket (sock, net_from, net_message)) return true; for (protocol = 0 ; protocol < 3 ; protocol++) { if (protocol == 0) net_socket = ip_sockets[sock]; else if (protocol == 1) net_socket = ip6_sockets[sock]; else net_socket = ipx_sockets[sock]; if (!net_socket) continue; fromlen = sizeof(from); ret = recvfrom (net_socket, net_message->data, net_message->maxsize, 0, (struct sockaddr *)&from, &fromlen); SockadrToNetadr (&from, net_from); if (ret == -1) { err = errno; if (err == EWOULDBLOCK || err == ECONNREFUSED) continue; Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(), NET_AdrToString(*net_from)); continue; } if (ret == net_message->maxsize) { Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from)); continue; } net_message->cursize = ret; return true; } return false; }
int UDP_Read(int socket, void *buf, int len, netadr_t *addr) { struct sockaddr_in saddr; socklen_t addrlen = sizeof(saddr); int ret; ret = recvfrom(socket, buf, len, 0, (struct sockaddr *)&saddr, &addrlen); SockadrToNetadr(&saddr, addr); if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED)) return 0; return ret; }
qbool NET_GetUDPPacket (netsrc_t netsrc, netadr_t *from_adr, sizebuf_t *message) { int ret, err; struct sockaddr_storage from = {0}; socklen_t fromlen; int socket = NET_GetSocket(netsrc, false); if (socket == INVALID_SOCKET) return false; fromlen = sizeof(from); ret = recvfrom (socket, (char *)message->data, message->maxsize, 0, (struct sockaddr *)&from, &fromlen); SockadrToNetadr (&from, from_adr); if (ret == -1) { err = qerrno; if (err == EWOULDBLOCK) return false; // common error, does not spam in logs. if (err == EMSGSIZE) { Con_DPrintf ("Warning: Oversize packet from %s\n", NET_AdrToString (*from_adr)); return false; } if (err == ECONNABORTED || err == ECONNRESET) { Con_DPrintf ("Connection lost or aborted\n"); return false; } Con_Printf ("NET_GetPacket: recvfrom: (%i): %s\n", err, strerror(err)); return false; } if (ret >= message->maxsize) { Con_Printf ("Oversize packet from %s\n", NET_AdrToString (*from_adr)); return false; } message->cursize = ret; return ret; }
/* ============= NET_StringToAdr localhost idnewt idnewt:28000 192.246.40.70 192.246.40.70:28000 ============= */ qboolean NET_StringToAdr (const char *s, netadr_t *a) { struct sockaddr sadr; if (!Q_stricmp(s, "localhost")) { memset (a, 0, sizeof(*a)); a->type = NA_LOOPBACK; return true; } if (!NET_StringToSockaddr (s, &sadr)) return false; SockadrToNetadr (&sadr, a); return true; }
int NET_GetPacket (void) { int ret; struct sockaddr_in from; socklen_t fromlen; fromlen = sizeof(from); net_message.clear(); ret = recvfrom (net_socket, (char *)net_message.ptr(), net_message.maxsize(), 0, (struct sockaddr *)&from, &fromlen); if (ret == -1) { #ifdef _WIN32 errno = WSAGetLastError(); if (errno == WSAEWOULDBLOCK) return false; if (errno == WSAECONNRESET) return false; if (errno == WSAEMSGSIZE) { Printf (PRINT_HIGH, "Warning: Oversize packet from %s\n", NET_AdrToString (net_from)); return false; } Printf (PRINT_HIGH, "NET_GetPacket: %s\n", strerror(errno)); return false; #else if (errno == EWOULDBLOCK) return false; if (errno == ECONNREFUSED) return false; Printf (PRINT_HIGH, "NET_GetPacket: %s\n", strerror(errno)); return false; #endif } net_message.setcursize(ret); SockadrToNetadr (&from, &net_from); return ret; }
/* <d2eca> ../engine/net_ws.c:483 */ qboolean NET_StringToAdr(const char *s, netadr_t *a) { struct sockaddr sadr; if (Q_strcmp(s, "localhost")) { if (!NET_StringToSockaddr(s, &sadr)) { return FALSE; } SockadrToNetadr(&sadr, a); } else { Q_memset(a, 0, sizeof(netadr_t)); a->type = NA_LOOPBACK; } return TRUE; }
qbool NET_StringToAdr (const char *s, netadr_t *a) { struct sockaddr_storage sadr; #ifndef SERVERONLY if (!strcmp(s, "local")) { memset(a, 0, sizeof(*a)); a->type = NA_LOOPBACK; return true; } #endif if (!NET_StringToSockaddr (s, &sadr)) return false; SockadrToNetadr (&sadr, a); return true; }
qboolean NET_StringToAdr(char *s, netadr_t *a) { struct sockaddr_storage sadr; memset(a, 0, sizeof(*a)); if (!strcmp(s, "localhost")) { a->type = NA_LOOPBACK; return true; } if (!NET_StringToSockaddr(s, &sadr)) { return false; } SockadrToNetadr(&sadr, a); return true; }
qboolean NET_GetPacket (void) { int ret; struct sockaddr_in from; unsigned int fromlen; fromlen = sizeof(from); ret = (int) recvfrom (net_socket, net_message_buffer, sizeof(net_message_buffer), 0, (struct sockaddr *)&from, &fromlen); if (ret == -1) { if (errno == EWOULDBLOCK) return false; if (errno == ECONNREFUSED) return false; Sys_Printf ("NET_GetPacket: %s\n", strerror(errno)); return false; } net_message.cursize = ret; SockadrToNetadr (&from, &net_from); return ret; }
/* ============= NET_StringToAdr localhost idnewt idnewt:28000 192.246.40.70 192.246.40.70:28000 ============= */ qboolean NET_StringToAdr (const char *s, netadr_t *a) { struct sockaddr sadr; if (!strcmp (s, "localhost")) { memset (a, 0, sizeof(*a)); //r1: should need some kind of ip data to prevent comparisons with empty ips? a->ip[0] = 127; a->ip[3] = 1; a->port = PORT_SERVER; a->type = NA_LOOPBACK; return true; } if (!NET_StringToSockaddr (s, &sadr)) return false; SockadrToNetadr (&sadr, a); return true; }
static int udp_scan_iface(int sock) { struct ifconf ifc; struct ifreq *ifr; char buf[8192]; int i, n; struct sockaddr_in *iaddr; if (COM_CheckParm("-noifscan")) return -1; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) { Con_Printf("%s: SIOCGIFCONF failed\n", __func__); return -1; } ifr = ifc.ifc_req; n = ifc.ifc_len / sizeof(struct ifreq); for (i = 0; i < n; i++) { if (ioctl(sock, SIOCGIFADDR, &ifr[i]) == -1) continue; iaddr = (struct sockaddr_in *)&ifr[i].ifr_addr; Con_DPrintf("%s: %s\n", ifr[i].ifr_name, inet_ntoa(iaddr->sin_addr)); if (iaddr->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { SockadrToNetadr(iaddr, &myAddr); strcpy (ifname, ifr[i].ifr_name); return 0; } } return -1; }
qboolean NET_StringToAdr (char *s, netadr_t *a) { struct hostent *h; struct sockaddr_in sadr; char *colon, copy[128]; if (!strcmp(s, "local")) { memset(a, 0, sizeof(*a)); a->type = NA_LOOPBACK; return true; } memset (&sadr, 0, sizeof(sadr)); sadr.sin_family = AF_INET; sadr.sin_port = 0; strcpy (copy, s); // strip off a trailing :port if present for (colon = copy; *colon; colon++) { if (*colon == ':') { *colon = 0; sadr.sin_port = htons((short)atoi(colon+1)); } } if (copy[0] >= '0' && copy[0] <= '9') { *(int *)&sadr.sin_addr = inet_addr(copy); } else { if ((h = gethostbyname(copy)) == 0) return 0; *(int *)&sadr.sin_addr = *(int *)h->h_addr_list[0]; } SockadrToNetadr (&sadr, a); return true; }
/* NET_StringToAdr idnewt idnewt:28000 192.246.40.70 192.246.40.70:28000 */ qboolean NET_StringToAdr (const char *s, netadr_t *a) { static dstring_t *copy; char *colon; struct hostent *h; AF_address_t sadr; if (!copy) copy = dstring_new (); memset (&sadr, 0, sizeof (sadr)); sadr.s4.sin_family = AF_INET; sadr.s4.sin_port = 0; dstring_copystr (copy, s); // strip off a trailing :port if present for (colon = copy->str; *colon; colon++) if (*colon == ':') { *colon = 0; sadr.s4.sin_port = htons ((unsigned short) atoi (colon + 1)); } if (copy->str[0] >= '0' && copy->str[0] <= '9') { int addr = inet_addr (copy->str); memcpy (&sadr.s4.sin_addr, &addr, ADDR_SIZE); } else { if (!(h = gethostbyname (copy->str))) return 0; memcpy (&sadr.s4.sin_addr, h->h_addr_list[0], ADDR_SIZE); } SockadrToNetadr (&sadr, a); return true; }
/* ============= NET_StringToAdr idnewt idnewt:28000 192.246.40.70 192.246.40.70:28000 ============= */ qboolean NET_StringToAdr (char *s, netadr_t *a) { struct hostent *h; struct sockaddr_in sadr; char *colon; char copy[128]; memset (&sadr, 0, sizeof(sadr)); sadr.sin_family = AF_INET; sadr.sin_port = 0; strcpy (copy, s); // strip off a trailing :port if present for (colon = copy ; *colon ; colon++) if (*colon == ':') { *colon = 0; sadr.sin_port = htons(atoi(colon+1)); } if (copy[0] >= '0' && copy[0] <= '9') { *(int *)&sadr.sin_addr = inet_addr(copy); } else { if (! (h = gethostbyname(copy)) ) return 0; *(int *)&sadr.sin_addr = *(int *)h->h_addr_list[0]; } SockadrToNetadr (&sadr, a); return true; }
qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) { int ret; struct sockaddr from; int fromlen; int net_socket; int protocol; int err; for( protocol = 0 ; protocol < 2 ; protocol++ ) { if( protocol == 0 ) { net_socket = ip_socket; } else { net_socket = ipx_socket; } if( !net_socket ) { continue; } fromlen = sizeof(from); recvfromCount++; // performance check ret = recvfrom( net_socket, (char *)net_message->data, net_message->maxsize, 0, (struct sockaddr *)&from, &fromlen ); if (ret == SOCKET_ERROR) { err = WSAGetLastError(); if( err == WSAEWOULDBLOCK || err == WSAECONNRESET ) { continue; } Com_Printf( "NET_GetPacket: %s\n", NET_ErrorString() ); continue; } if ( net_socket == ip_socket ) { memset( ((struct sockaddr_in *)&from)->sin_zero, 0, 8 ); } if ( usingSocks && net_socket == ip_socket && memcmp( &from, &socksRelayAddr, fromlen ) == 0 ) { if ( ret < 10 || net_message->data[0] != 0 || net_message->data[1] != 0 || net_message->data[2] != 0 || net_message->data[3] != 1 ) { continue; } net_from->type = NA_IP; net_from->ip[0] = net_message->data[4]; net_from->ip[1] = net_message->data[5]; net_from->ip[2] = net_message->data[6]; net_from->ip[3] = net_message->data[7]; net_from->port = *(short *)&net_message->data[8]; net_message->readcount = 10; } else { SockadrToNetadr( &from, net_from ); net_message->readcount = 0; } if( ret == net_message->maxsize ) { Com_Printf( "Oversize packet from %s\n", NET_AdrToString (*net_from) ); continue; } net_message->cursize = ret; return qtrue; } return qfalse; }
/* ================== Sys_GetPacket Never called by the game logic, just the system event queing ================== */ qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) { int ret; struct sockaddr_storage from; socklen_t fromlen; int err; if ( ip_socket != INVALID_SOCKET ) { fromlen = sizeof( from ); ret = recvfrom( ip_socket, ( void * ) net_message->data, net_message->maxsize, 0, ( struct sockaddr * ) &from, &fromlen ); if ( ret == SOCKET_ERROR ) { err = socketError; if ( err != EAGAIN && err != ECONNRESET ) { Com_Printf(_( "NET_GetPacket: %s\n"), NET_ErrorString() ); } } else { memset( ( ( struct sockaddr_in * ) &from )->sin_zero, 0, 8 ); if ( usingSocks && memcmp( &from, &socksRelayAddr, fromlen ) == 0 ) { if ( ret < 10 || net_message->data[ 0 ] != 0 || net_message->data[ 1 ] != 0 || net_message->data[ 2 ] != 0 || net_message->data[ 3 ] != 1 ) { return qfalse; } net_from->type = NA_IP; net_from->ip[ 0 ] = net_message->data[ 4 ]; net_from->ip[ 1 ] = net_message->data[ 5 ]; net_from->ip[ 2 ] = net_message->data[ 6 ]; net_from->ip[ 3 ] = net_message->data[ 7 ]; net_from->port = * ( short * ) &net_message->data[ 8 ]; net_message->readcount = 10; } else { SockadrToNetadr( ( struct sockaddr * ) &from, net_from ); net_message->readcount = 0; } if ( ret == net_message->maxsize ) { Com_Printf(_( "Oversize packet from %s\n"), NET_AdrToString( *net_from ) ); return qfalse; } net_message->cursize = ret; return qtrue; } } if ( ip6_socket != INVALID_SOCKET ) { fromlen = sizeof( from ); ret = recvfrom( ip6_socket, ( void * ) net_message->data, net_message->maxsize, 0, ( struct sockaddr * ) &from, &fromlen ); if ( ret == SOCKET_ERROR ) { err = socketError; if ( err != EAGAIN && err != ECONNRESET ) { Com_Printf(_( "NET_GetPacket: %s\n"), NET_ErrorString() ); } } else { SockadrToNetadr( ( struct sockaddr * ) &from, net_from ); net_message->readcount = 0; if ( ret == net_message->maxsize ) { Com_Printf(_( "Oversize packet from %s\n"), NET_AdrToString( *net_from ) ); return qfalse; } net_message->cursize = ret; return qtrue; } } if ( multicast6_socket != INVALID_SOCKET && multicast6_socket != ip6_socket ) { fromlen = sizeof( from ); ret = recvfrom( multicast6_socket, ( void * ) net_message->data, net_message->maxsize, 0, ( struct sockaddr * ) &from, &fromlen ); if ( ret == SOCKET_ERROR ) { err = socketError; if ( err != EAGAIN && err != ECONNRESET ) { Com_Printf(_( "NET_GetPacket: %s\n"), NET_ErrorString() ); } } else { SockadrToNetadr( ( struct sockaddr * ) &from, net_from ); net_message->readcount = 0; if ( ret == net_message->maxsize ) { Com_Printf(_( "Oversize packet from %s\n"), NET_AdrToString( *net_from ) ); return qfalse; } net_message->cursize = ret; return qtrue; } } return qfalse; }
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; }