//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_OpenReliableSocket( int port ){ int newsocket; struct sockaddr_in address; qboolean _true = 0xFFFFFFFF; //IPPROTO_TCP // if ( ( newsocket = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) { WinPrint( "WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); return -1; } //end if memset( (char *) &address, 0, sizeof( address ) ); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl( INADDR_ANY ); address.sin_port = htons( (u_short)port ); if ( bind( newsocket, (void *)&address, sizeof( address ) ) == -1 ) { WinPrint( "WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); closesocket( newsocket ); return -1; } //end if // if ( setsockopt( newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof( int ) ) == -1 ) { WinPrint( "WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); WinPrint( "setsockopt error\n" ); } //end if return newsocket; } //end of the function WINS_OpenReliableSocket
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_OpenSocket( int port ){ int newsocket; struct sockaddr_in address; u_long _true = 1; if ( ( newsocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == SOCKET_ERROR ) { WinPrint( "WINS_OpenSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); return -1; } //end if if ( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR ) { WinPrint( "WINS_OpenSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); closesocket( newsocket ); return -1; } //end if memset( (char *) &address, 0, sizeof( address ) ); address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons( (u_short)port ); if ( bind( newsocket, (void *)&address, sizeof( address ) ) == -1 ) { WinPrint( "WINS_OpenSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); closesocket( newsocket ); return -1; } //end if return newsocket; } //end of the function WINS_OpenSocket
//=========================================================================== // returns the number of bytes recieved // -1 on error // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int Net_Receive( socket_t *sock, netmessage_t *msg ){ int curread; if ( sock->remaining > 0 ) { curread = WINS_Read( sock->socket, &sock->msg.data[sock->msg.size], sock->remaining, NULL ); if ( curread == -1 ) { WinPrint( "Net_Receive: read error\n" ); return -1; } //end if sock->remaining -= curread; sock->msg.size += curread; if ( sock->remaining <= 0 ) { sock->remaining = 0; memcpy( msg, &sock->msg, sizeof( netmessage_t ) ); sock->msg.size = 0; return msg->size - 4; } //end if return 0; } //end if sock->msg.size = WINS_Read( sock->socket, sock->msg.data, 4, NULL ); if ( sock->msg.size == 0 ) { return 0; } if ( sock->msg.size == -1 ) { WinPrint( "Net_Receive: size header read error\n" ); return -1; } //end if //WinPrint("Net_Receive: message size header %d\n", msg->size); sock->msg.read = 0; sock->remaining = NMSG_ReadLong( &sock->msg ); if ( sock->remaining == 0 ) { return 0; } if ( sock->remaining < 0 || sock->remaining > MAX_NETMESSAGE ) { WinPrint( "Net_Receive: invalid message size %d\n", sock->remaining ); return -1; } //end if //try to read the message curread = WINS_Read( sock->socket, &sock->msg.data[sock->msg.size], sock->remaining, NULL ); if ( curread == -1 ) { WinPrint( "Net_Receive: read error\n" ); return -1; } //end if sock->remaining -= curread; sock->msg.size += curread; if ( sock->remaining <= 0 ) { sock->remaining = 0; memcpy( msg, &sock->msg, sizeof( netmessage_t ) ); sock->msg.size = 0; return msg->size - 4; } //end if //the message has not been completely read yet #ifdef _DEBUG printf( "++timo TODO: debug the Net_Receive on big size messages\n" ); #endif return 0; } //end of the function Net_Receive
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void NMSG_WriteByte( netmessage_t *msg, int c ){ if ( c < -128 || c > 127 ) { WinPrint( "NMSG_WriteByte: range error\n" ); } if ( msg->size + 1 >= MAX_NETMESSAGE ) { WinPrint( "NMSG_WriteByte: overflow\n" ); return; } //end if msg->data[msg->size] = c; msg->size++; } //end of the function NMSG_WriteByte
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_Listen( int socket ){ u_long _true = 1; if ( ioctlsocket( socket, FIONBIO, &_true ) == -1 ) { WinPrint( "WINS_Listen: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); return -1; } //end if if ( listen( socket, SOMAXCONN ) == SOCKET_ERROR ) { WinPrint( "WINS_Listen: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); return -1; } //end if return 0; } //end of the function WINS_Listen
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void NMSG_WriteShort( netmessage_t *msg, int c ){ if ( c < ( (short)0x8000 ) || c > (short)0x7fff ) { WinPrint( "NMSG_WriteShort: range error" ); } if ( msg->size + 2 >= MAX_NETMESSAGE ) { WinPrint( "NMSG_WriteShort: overflow\n" ); return; } //end if msg->data[msg->size] = c & 0xff; msg->data[msg->size + 1] = c >> 8; msg->size += 2; } //end of the function NMSG_WriteShort
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_Connect( int socket, struct sockaddr_s *addr ){ int ret; u_long _true2 = 0xFFFFFFFF; ret = connect( socket, (struct sockaddr *)addr, sizeof( struct sockaddr_s ) ); if ( ret == SOCKET_ERROR ) { WinPrint( "WINS_Connect: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); return -1; } //end if if ( ioctlsocket( socket, FIONBIO, &_true2 ) == -1 ) { WinPrint( "WINS_Connect: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); return -1; } //end if return 0; } //end of the function WINS_Connect
char *NMSG_ReadString(netmessage_t * msg) { static char string[2048]; int l, c; l = 0; do { if(msg->read + 1 > msg->size) { msg->readoverflow = qtrue; WinPrint("NMSG_ReadString: read overflow\n"); string[l] = 0; return string; } //end if c = msg->data[msg->read]; msg->read++; if(c == 0) break; string[l] = c; l++; } while(l < sizeof(string) - 1); string[l] = 0; return string; } //end of the function NMSG_ReadString
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== socket_t *Net_Connect(address_t *address, int port) { int newsock; socket_t *sock; sockaddr_t sendaddr; // see if we can resolve the host name WINS_StringToAddr(address->ip, &sendaddr); newsock = WINS_OpenReliableSocket(port); if (newsock == -1) return NULL; sock = Net_AllocSocket(); if (sock == NULL) { WINS_CloseSocket(newsock); return NULL; } //end if sock->socket = newsock; //connect to the host if (WINS_Connect(newsock, &sendaddr) == -1) { Net_FreeSocket(sock); WINS_CloseSocket(newsock); WinPrint("Net_Connect: error connecting\n"); return NULL; } //end if memcpy(&sock->addr, &sendaddr, sizeof(sockaddr_t)); //now we can send messages // return sock; } //end of the function Net_Connect
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== socket_t *Net_ListenSocket(int port) { int newsock; socket_t *sock; newsock = WINS_OpenReliableSocket(port); if (newsock == -1) return NULL; if (WINS_Listen(newsock) == -1) { WINS_CloseSocket(newsock); return NULL; } //end if sock = Net_AllocSocket(); if (sock == NULL) { WINS_CloseSocket(newsock); return NULL; } //end if sock->socket = newsock; WINS_GetSocketAddr(newsock, &sock->addr); WinPrint("listen socket opened at %s\n", WINS_AddrToString(&sock->addr)); // return sock; } //end of the function Net_ListenSocket
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void WINS_Shutdown( void ){ //WINS_Listen(0); WINS_CloseSocket( net_controlsocket ); // WSACleanup(); // WinPrint( "Winsock Shutdown\n" ); } //end of the function WINS_Shutdown
//=========================================================================== // returns the number of bytes read // 0 if no bytes available // -1 on failure // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_Read(int socket, byte *buf, int len, struct sockaddr_s *addr) { int addrlen = sizeof (struct sockaddr_s); int ret, errno; if (addr) { ret = recvfrom(socket, buf, len, 0, (struct sockaddr *)addr, &addrlen); if (ret == -1) { errno = WSAGetLastError(); if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED) return 0; } //end if } //end if else { ret = recv(socket, buf, len, 0); if (ret == SOCKET_ERROR) { errno = WSAGetLastError(); if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED) return 0; } //end if } //end else if (ret == SOCKET_ERROR) { WinPrint("WINS_Read: %s\n", WINS_ErrorMessage(WSAGetLastError())); } //end if return ret; } //end of the function WINS_Read
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void NMSG_WriteString( netmessage_t *msg, char *string ){ if ( msg->size + strlen( string ) + 1 >= MAX_NETMESSAGE ) { WinPrint( "NMSG_WriteString: overflow\n" ); return; } //end if memcpy( &msg->data[msg->size], string, strlen( string ) + 1 ); msg->size += strlen( string ) + 1; } //end of the function NMSG_WriteString
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int Net_Setup(void) { WINS_Init(); // WinPrint("my address is %s\n", WINS_MyAddress()); // return qtrue; } //end of the function Net_Setup
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int NMSG_ReadByte( netmessage_t *msg ){ if ( msg->read + 1 > msg->size ) { msg->readoverflow = qtrue; WinPrint( "NMSG_ReadByte: read overflow\n" ); return 0; } //end if msg->read++; return msg->data[msg->read - 1]; } //end of the function NMSG_ReadByte
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void NMSG_WriteFloat( netmessage_t *msg, float c ){ if ( msg->size + 4 >= MAX_NETMESSAGE ) { WinPrint( "NMSG_WriteLong: overflow\n" ); return; } //end if msg->data[msg->size] = *( (int *)&c ) & 0xff; msg->data[msg->size + 1] = ( *( (int *)&c ) >> 8 ) & 0xff; msg->data[msg->size + 2] = ( *( (int *)&c ) >> 16 ) & 0xff; msg->data[msg->size + 3] = *( (int *)&c ) >> 24; msg->size += 4; } //end of the function NMSG_WriteFloat
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_Accept( int socket, struct sockaddr_s *addr ){ socklen_t addrlen = sizeof( struct sockaddr_s ); int newsocket; qboolean _true = 1; newsocket = accept( socket, (struct sockaddr *)addr, &addrlen ); if ( newsocket == INVALID_SOCKET ) { if ( errno == EAGAIN ) { return -1; } WinPrint( "WINS_Accept: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); return -1; } //end if // if ( setsockopt( newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof( int ) ) == SOCKET_ERROR ) { WinPrint( "WINS_Accept: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); WinPrint( "setsockopt error\n" ); } //end if return newsocket; } //end of the function WINS_Accept
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int NMSG_ReadShort( netmessage_t *msg ){ int c; if ( msg->read + 2 > msg->size ) { msg->readoverflow = qtrue; WinPrint( "NMSG_ReadShort: read overflow\n" ); return 0; } //end if c = (short)( msg->data[msg->read] + ( msg->data[msg->read + 1] << 8 ) ); msg->read += 2; return c; } //end of the function NMSG_ReadShort
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_CloseSocket( int socket ){ /* if (socket == net_broadcastsocket) net_broadcastsocket = 0; */ // shutdown(socket, SD_SEND); if ( closesocket( socket ) == SOCKET_ERROR ) { WinPrint( "WINS_CloseSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); return SOCKET_ERROR; } //end if return 0; } //end of the function WINS_CloseSocket
float NMSG_ReadFloat(netmessage_t * msg) { int c; if(msg->read + 4 > msg->size) { msg->readoverflow = qtrue; WinPrint("NMSG_ReadLong: read overflow\n"); return 0; } //end if c = msg->data[msg->read] + (msg->data[msg->read + 1] << 8) + (msg->data[msg->read + 2] << 16) + (msg->data[msg->read + 3] << 24); msg->read += 4; return *(float *)&c; } //end of the function NMSG_ReadFloat
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_Broadcast( int socket, byte *buf, int len ){ int ret; if ( socket != net_broadcastsocket ) { if ( net_broadcastsocket != 0 ) { WinError( "Attempted to use multiple broadcasts sockets\n" ); } ret = WINS_MakeSocketBroadcastCapable( socket ); if ( ret == -1 ) { WinPrint( "Unable to make socket broadcast capable\n" ); return ret; } } return WINS_Write( socket, buf, len, &broadcastaddr ); } //end of the function WINS_Broadcast
//=========================================================================== // returns qtrue on success or qfalse on failure // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_Write( int socket, byte *buf, int len, struct sockaddr_s *addr ){ int ret, written; ret = 0; if ( addr ) { written = 0; while ( written < len ) { ret = sendto( socket, &buf[written], len - written, 0, (struct sockaddr *)addr, sizeof( struct sockaddr_s ) ); if ( ret == SOCKET_ERROR ) { if ( WSAGetLastError() != EAGAIN ) { return qfalse; } //++timo FIXME: what is this used for? // Sleep(1000); } //end if else { written += ret; } } } //end if else { written = 0; while ( written < len ) { ret = send( socket, buf, len, 0 ); if ( ret == SOCKET_ERROR ) { if ( WSAGetLastError() != EAGAIN ) { return qfalse; } //++timo FIXME: what is this used for? // Sleep(1000); } //end if else { written += ret; } } } //end else if ( ret == SOCKET_ERROR ) { WinPrint( "WINS_Write: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); } //end if return ( ret == len ); } //end of the function WINS_Write
//=========================================================================== // returns the number of bytes read // 0 if no bytes available // -1 on failure // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_Read( int socket, byte *buf, int len, struct sockaddr_s *addr ){ socklen_t addrlen = sizeof( struct sockaddr_s ); int ret; if ( addr ) { ret = recvfrom( socket, buf, len, 0, (struct sockaddr *)addr, &addrlen ); if ( ret == -1 ) { // errno = WSAGetLastError(); if ( errno == EAGAIN || errno == ENOTCONN ) { return 0; } } //end if } //end if else { ret = recv( socket, buf, len, 0 ); // if there's no data on the socket ret == -1 and errno == EAGAIN // MSDN states that if ret == 0 the socket has been closed // man recv doesn't say anything if ( ret == 0 ) { return -1; } if ( ret == SOCKET_ERROR ) { // errno = WSAGetLastError(); if ( errno == EAGAIN || errno == ENOTCONN ) { return 0; } } //end if } //end else if ( ret == SOCKET_ERROR ) { WinPrint( "WINS_Read: %s\n", WINS_ErrorMessage( WSAGetLastError() ) ); } //end if return ret; } //end of the function WINS_Read
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int WINS_Init( void ){ int i; struct hostent *local; char buff[MAXHOSTNAMELEN]; struct sockaddr_s addr; char *p; /* linux doesn't have anything to initialize for the net "Windows .. built for the internet .. the internet .. built with unix" */ #if 0 WORD wVersionRequested; wVersionRequested = MAKEWORD( 2, 2 ); r = WSAStartup( wVersionRequested, &winsockdata ); if ( r ) { WinPrint( "Winsock initialization failed.\n" ); return -1; } #endif /* i = COM_CheckParm ("-udpport"); if (i == 0)*/ net_hostport = DEFAULTnet_hostport; /* else if (i < com_argc-1) net_hostport = Q_atoi (com_argv[i+1]); else Sys_Error ("WINS_Init: you must specify a number after -udpport"); */ // determine my name & address gethostname( buff, MAXHOSTNAMELEN ); local = gethostbyname( buff ); if(local && local->h_addr_list && local->h_addr_list[0]) myAddr = *(int *)local->h_addr_list[0]; else myAddr = inet_addr("127.0.0.1"); // if the quake hostname isn't set, set it to the machine name // if (Q_strcmp(hostname.string, "UNNAMED") == 0) { // see if it's a text IP address (well, close enough) for ( p = buff; *p; p++ ) if ( ( *p < '0' || *p > '9' ) && *p != '.' ) { break; } // if it is a real name, strip off the domain; we only want the host if ( *p ) { for ( i = 0; i < 15; i++ ) if ( buff[i] == '.' ) { break; } buff[i] = 0; } // Cvar_Set ("hostname", buff); } //++timo WTF is that net_controlsocket? it's sole purpose is to retrieve the local IP? if ( ( net_controlsocket = WINS_OpenSocket( 0 ) ) == SOCKET_ERROR ) { WinError( "WINS_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( (u_short)net_hostport ); WINS_GetSocketAddr( net_controlsocket, &addr ); strcpy( my_tcpip_address, WINS_AddrToString( &addr ) ); p = strrchr( my_tcpip_address, ':' ); if ( p ) { *p = 0; } WinPrint( "Winsock Initialized\n" ); return net_controlsocket; } //end of the function WINS_Init