/* ======================== Net_SendUDPPacket ======================== */ void Net_SendUDPPacket( int netSocket, int length, const void* data, const netadr_t to ) { int ret; sockaddr_in addr; if( !netSocket ) { return; } Net_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] = addr.sin_addr.s_addr; *( short* )&socksBuf[8] = addr.sin_port; memcpy( &socksBuf[10], data, length ); ret = sendto( netSocket, socksBuf, length + 10, 0, ( sockaddr* )&socksRelayAddr, sizeof( socksRelayAddr ) ); } else { ret = sendto( netSocket, ( const char* )data, length, 0, ( sockaddr* )&addr, sizeof( addr ) ); } if( ret == SOCKET_ERROR ) { int err = Net_GetLastError(); // some PPP links do not allow broadcasts and return an error if( ( err == D3_NET_EADDRNOTAVAIL ) && ( to.type == NA_BROADCAST ) ) { return; } // NOTE: EWOULDBLOCK used to be silently ignored, // but that means the packet will be dropped so I don't feel it's a good thing to ignore idLib::Printf( "UDP sendto error - packet dropped: %s\n", NET_ErrorString() ); } }
bool SocketIsReady( SOCKET sock ) { timeval tv; fd_set mask; bool ready = false; do { Net_SetLastError( 0 ); FD_ZERO( &mask ); FD_SET( sock, &mask ); tv.tv_sec = 0; tv.tv_usec = 0; ready = select( sock + 1, &mask, 0, 0, &tv ) == 1; } while ( Net_GetLastError() == EINTR ); return ready; }
/* ======================== Net_GetUDPPacket ======================== */ bool Net_GetUDPPacket( int netSocket, netadr_t& net_from, char* data, int& size, int maxSize ) { int ret; sockaddr_in from; socklen_t fromlen; int err; if( !netSocket ) { return false; } fromlen = sizeof( from ); ret = recvfrom( netSocket, data, maxSize, 0, ( sockaddr* )&from, &fromlen ); if( ret == SOCKET_ERROR ) { err = Net_GetLastError(); if( err == D3_NET_EWOULDBLOCK || err == D3_NET_ECONNRESET ) { return false; } idLib::Printf( "Net_GetUDPPacket: %s\n", NET_ErrorString() ); return false; } #if 0 // TODO: WTF was this about? // DG: ip_socket is never initialized, so this is dead code // - and if netSocket is 0 (so this would be true) recvfrom above will already fail if( static_cast<unsigned int>( netSocket ) == ip_socket ) { memset( from.sin_zero, 0, sizeof( from.sin_zero ) ); } if( usingSocks && static_cast<unsigned int>( netSocket ) == ip_socket && memcmp( &from, &socksRelayAddr, fromlen ) == 0 ) { if( ret < 10 || data[0] != 0 || data[1] != 0 || data[2] != 0 || data[3] != 1 ) { return false; } net_from.type = NA_IP; net_from.ip[0] = data[4]; net_from.ip[1] = data[5]; net_from.ip[2] = data[6]; net_from.ip[3] = data[7]; net_from.port = *( short* )&data[8]; memmove( data, &data[10], ret - 10 ); } else { #endif // 0 Net_SockadrToNetadr( &from, &net_from ); #if 0 // this is ugly, but else astyle is confused } #endif if( ret > maxSize ) { idLib::Printf( "Net_GetUDPPacket: oversize packet from %s\n", Sys_NetAdrToString( net_from ) ); return false; } size = ret; return true; }