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