/* ================== idTCP::Init ================== */ bool idTCP::Init( const char *host, short port ) { unsigned long _true = 1; struct sockaddr 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 ); Net_NetadrToSockadr( &address, &sadr ); if ( fd ) { common->Warning( "idTCP::Init: already initialized?" ); } if ( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET ) { fd = 0; common->Printf( "ERROR: idTCP::Init: socket: %s\n", NET_ErrorString() ); return false; } if ( connect( fd, &sadr, sizeof(sadr)) == SOCKET_ERROR ) { common->Printf( "ERROR: idTCP::Init: connect: %s\n", NET_ErrorString() ); closesocket( fd ); fd = 0; return false; } // make it non-blocking if( ioctlsocket( fd, FIONBIO, &_true ) == SOCKET_ERROR ) { common->Printf( "ERROR: idTCP::Init: ioctl FIONBIO: %s\n", NET_ErrorString() ); closesocket( fd ); fd = 0; return false; } common->DPrintf( "Opened TCP connection\n" ); return true; }
/* ================== Net_SendUDPPacket ================== */ void Net_SendUDPPacket( int netSocket, int length, const void *data, const netadr_t to ) { int ret; struct sockaddr 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] = ((struct sockaddr_in *)&addr)->sin_addr.s_addr; *(short *)&socksBuf[8] = ((struct sockaddr_in *)&addr)->sin_port; memcpy( &socksBuf[10], data, length ); ret = sendto( netSocket, socksBuf, length+10, 0, &socksRelayAddr, sizeof(socksRelayAddr) ); } else { ret = sendto( netSocket, (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 ) ) { return; } char buf[1024]; sprintf( buf, "Net_SendUDPPacket: %s\n", NET_ErrorString() ); OutputDebugString( buf ); } }
/* ======================== 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 = WSAGetLastError(); // some PPP links do not allow broadcasts and return an error if( ( err == WSAEADDRNOTAVAIL ) && ( to.type == NA_BROADCAST ) ) { return; } // NOTE: WSAEWOULDBLOCK 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() ); } }