FS2_Open
Open source remastering of the Freespace 2 engine
psnet2.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 
13 #ifdef _WIN32
14 #include <windows.h>
15 #include <windowsx.h>
16 #include <winsock.h>
17 #include <process.h>
18 #include <ras.h>
19 #include <raserror.h>
20 #else
21 #include <sys/time.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <sys/select.h>
26 #include <errno.h>
27 #include <arpa/inet.h>
28 #include <netdb.h>
29 
30 #define WSAGetLastError() (errno)
31 #endif
32 #include <stdio.h>
33 #include <limits.h>
34 #include <algorithm>
35 
36 #include "globalincs/pstypes.h"
37 #include "network/psnet2.h"
38 #include "network/multi.h"
39 #include "network/multiutil.h"
40 #include "network/multilag.h"
41 #include "osapi/osregistry.h"
42 #include "io/timer.h"
43 #include "network/multi_log.h"
44 #include "network/multi_rate.h"
45 #include "cmdline/cmdline.h"
46 
47 // -------------------------------------------------------------------------------------------------------
48 // PSNET 2 DEFINES/VARS
49 //
50 
53 
55 
57 int Can_broadcast; // can we do broadcasting on our socket?
59 
60 int Tcp_active = 0;
61 
66 
68 
69 // specified their internet connnection type
70 #define NETWORK_CONNECTION_NONE 1
71 #define NETWORK_CONNECTION_DIALUP 2
72 #define NETWORK_CONNECTION_LAN 3
73 
74 // defines and variables to indicate network connection status
75 #define NETWORK_STATUS_NOT_INITIALIZED 1
76 #define NETWORK_STATUS_NO_WINSOCK 2 // winsock failed to initialize
77 #define NETWORK_STATUS_NO_PROTOCOL 3 // TCP/IP doesn't appear to be loaded
78 #define NETWORK_STATUS_NO_RELIABLE 4
79 #define NETWORK_STATUS_RUNNING 5 // everything should be running
80 
81 // defintion of structures that actually leave this machine. psnet_send give us only
82 // the data that we want to send. We will add a header onto this data (packet sequence
83 // number, possibly a checksum). We must include a 2 byte flags variable into both structure
84 // since the receiving end of this packet must know whether or not to checksum the packet.
85 
86 #define MAX_TOP_LAYER_PACKET_SIZE 680
87 
88 // use the pack pragma to pack these structures to 2 byte aligment. Really only needed for
89 // the naked packet.
90 #define MAX_PACKET_BUFFERS 75
91 
92 #pragma pack(push, 2)
93 
97 typedef struct network_packet
98 {
103 
107 typedef struct network_packet_buffer
108 {
110  int len;
114 
124 
125 #pragma pack(pop)
126 
127 
128 #define MAXHOSTNAME 128
129 
130 #define MAX_RECEIVE_BUFSIZE 4096 // 32 K, eh?
131 #define MAX_SEND_RETRIES 20 // number of retries when sending would block
132 #define MAX_LINGER_TIME 0 // in seconds -- when lingering to close a socket
133 
134 //Reliable UDP stuff
135 //*******************************
136 #define MAXNETBUFFERS 150 // Maximum network buffers (For between network and upper level functions, which is
137  // required in case of out of order packets
138 #define NETRETRYTIME 0.75f // Time after sending before we resend
139 #define MIN_NET_RETRYTIME 0.2f
140 #define NETTIMEOUT 30 // Time after receiving the last packet before we drop that user
141 #define NETHEARTBEATTIME 3 // How often to send a heartbeat
142 #define MAXRELIABLESOCKETS 40 // Max reliable sockets to open at once...
143 #define NETBUFFERSIZE 600 // Max size of a network packet
144 
145 #define RELIABLE_CONNECT_TIME 7 // how long we'll wait for a response when doing a reliable connect
146 
148 
149 // Reliable packet stuff
150 #define RNT_ACK 1 // ACK Packet
151 #define RNT_DATA 2 // Data Packet
152 #define RNT_DATA_COMP 3 // Compressed Data Packet
153 #define RNT_REQ_CONN 4 // Requesting a connection
154 #define RNT_DISCONNECT 5 // Disconnecting a connection
155 #define RNT_HEARTBEAT 6 // Heartbeat -- send every NETHEARTBEATTIME
156 #define RNT_I_AM_HERE 7
157 
158 #pragma pack(push, 1)
159 typedef struct {
160  ubyte type; // packet type
162  ushort seq; // sequence packet 0-65535 used for ACKing also
163  ushort data_len; // length of data
164  float send_time; // Time the packet was sent, if an ACK the time the packet being ACK'd was sent.
165  ubyte data[NETBUFFERSIZE]; // Packet data
167 
168 #define RELIABLE_PACKET_HEADER_ONLY_SIZE (sizeof(reliable_header)-NETBUFFERSIZE)
169 #define MAX_PING_HISTORY 10
170 
171 typedef struct {
173 
175 
176 typedef struct {
179 
180 typedef struct {
181  reliable_net_sendbuffer *sbuffers[MAXNETBUFFERS]; // This is an array of pointers for quick sorting
182  unsigned short ssequence[MAXNETBUFFERS]; // This is the sequence number of the given packet
183  float timesent[MAXNETBUFFERS];
184  int send_len[MAXNETBUFFERS];
186  int recv_len[MAXNETBUFFERS];
187  unsigned short rsequence[MAXNETBUFFERS]; // This is the sequence number of the given packet
188  float last_packet_received; // For a given connection, this is the last packet we received
190  SOCKADDR addr; // SOCKADDR of our peer
191  ushort status; // Status of this connection
192  unsigned short oursequence; // This is the next sequence number the application is expecting
193  unsigned short theirsequence; // This is the next sequence number the peer is expecting
194  net_addr m_net_addr; // A FS2 network address structure
195  ubyte connection_type; // IP, modem, etc.
196  float pings[MAX_PING_HISTORY];
198  unsigned int num_ping_samples;
199  float mean_ping;
201 
203 
204 // sockets for TCP (unreliable)
206 
207 // the sockets that the game will use when selecting network type
209 
212 
213 #define CONNECTSEQ 0x142 // Magic number for starting a connection, just so it isn't 0
214 
215 unsigned int Serverconn = 0xffffffff;
216 
217 #pragma pack(pop)
218 //*******************************
219 
220 // top layer buffers
222 
223 // -------------------------------------------------------------------------------------------------------
224 // PSNET 2 FORWARD DECLARATIONS
225 //
226 
227 // if the string is a legally formatted ip string
228 int psnet_is_valid_numeric_ip(char *ip);
229 
230 #ifdef _WIN32
231 // functions to get the status of a RAS connection
232 unsigned int psnet_ras_status();
233 #endif
234 
235 // set some options on a socket
236 void psnet_socket_options( SOCKET sock );
237 
238 // initialize tcp socket
239 int psnet_init_tcp();
240 
241 // get time in seconds
242 float psnet_get_time();
243 
244 // returns the ip address of this machine. use for calling bind() with to associate with the proper
245 // IP address and network device.
246 int psnet_get_ip();
247 
248 // initialize reliable sockets
249 int psnet_init_rel_tcp(int port, int should_listen);
250 
251 // shutdown reliable sockets
252 void psnet_rel_close();
253 
254 // initialize the buffering system
256 
257 // buffer a packet (maintain order!)
259 
260 // get the index of the next packet in order!
262 
263 
264 // -------------------------------------------------------------------------------------------------------
265 // PSNET 2 TOP LAYER FUNCTIONS - these functions simply buffer and store packets based upon type (see PSNET_TYPE_* defines)
266 //
267 
271 int RECVFROM(SOCKET s, char *buf, int len, int flags, sockaddr *from, int *fromlen, int psnet_type)
272 {
274  net_addr addr;
275  int ret;
276  int ret_len;
277 
278  // bad type
279  Assert((psnet_type >= 0) && (psnet_type < PSNET_NUM_TYPES));
280  if((psnet_type < 0) || (psnet_type >= PSNET_NUM_TYPES)){
281  return -1;
282  }
283  l = &Psnet_top_buffers[psnet_type];
284 
285  // if we have no buffer! The user should have made sure this wasn't the case by calling SELECT()
286  ret = psnet_buffer_get_next(l, (ubyte*)buf, &ret_len, &addr);
287  if(!ret){
288  Int3();
289  return -1;
290  }
291 
292  // otherwise, stuff the outgoing data
293  switch ( Socket_type ) {
294  case NET_TCP:
295  ((SOCKADDR_IN*)from)->sin_port = htons(addr.port);
296 #ifdef _WIN32
297  memcpy(&((SOCKADDR_IN*)from)->sin_addr.S_un.S_addr, addr.addr, 4);
298 #else
299  memcpy(&((SOCKADDR_IN*)from)->sin_addr.s_addr, addr.addr, 4);
300 #endif
301  ((SOCKADDR_IN*)from)->sin_family = AF_INET;
302  *fromlen = sizeof(SOCKADDR_IN);
303  break;
304 
305  default:
306  Assert(0);
307  break;
308  }
309 
310  // return bytes read
311  return ret_len;
312 }
313 
317 int SELECT(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout, int psnet_type)
318 {
320 
321  // if this is a check for writability, just return the select
322  if(writefds != NULL){
323  return select(nfds, readfds, writefds, exceptfds, timeout);
324  }
325 
326  // bad type
327  Assert((psnet_type >= 0) && (psnet_type < PSNET_NUM_TYPES));
328  if((psnet_type < 0) || (psnet_type >= PSNET_NUM_TYPES)){
329  return -1;
330  }
331  l = &Psnet_top_buffers[psnet_type];
332 
333  // do we have any buffers in here?
334  if((l->psnet_lowest_id == -1) || (l->psnet_lowest_id > l->psnet_highest_id)){
335  return 0;
336  }
337 
338  // yo
339  return 1;
340 }
341 
345 int SENDTO(SOCKET s, char * buf, int len, int flags, sockaddr *to, int tolen, int psnet_type)
346 {
347  char outbuf[MAX_TOP_LAYER_PACKET_SIZE + 150];
348 
349  // stuff type
350  outbuf[0] = (char)psnet_type;
351  memcpy(&outbuf[1], buf, len);
352 
353  // send it
354  return sendto(s, outbuf, len + 1, flags, (SOCKADDR*)to, tolen);
355 }
356 
361 {
362  // read socket stuff
363  SOCKADDR_IN ip_addr; // UDP/TCP socket structure
364  fd_set rfds;
365  timeval timeout;
366  int read_len;
367  socklen_t from_len;
368  net_addr from_addr;
369  network_naked_packet packet_read;
370 
371  // clear the addresses to remove compiler warnings
372  memset(&ip_addr, 0, sizeof(SOCKADDR_IN));
373 
375  ml_string("Network ==> socket not inited in PSNET_TOP_LAYER_PROCESS");
376  return;
377  }
378 
379  while ( 1 ) {
380  // check if there is any data on the socket to be read. The amount of data that can be
381  // atomically read is stored in len.
382 
383  FD_ZERO(&rfds);
384  FD_SET( Unreliable_socket, &rfds );
385  timeout.tv_sec = 0;
386  timeout.tv_usec = 0;
387 
388 #ifdef _WIN32
389  if ( select( -1, &rfds, NULL, NULL, &timeout) == SOCKET_ERROR ) {
390 #else
391  if ( select( Unreliable_socket + 1, &rfds, NULL, NULL, &timeout) == SOCKET_ERROR ) {
392 #endif
393  ml_printf("Error %d doing a socket select on read", WSAGetLastError());
394  break;
395  }
396 
397  // if the read file descriptor is not set, then bail!
398  if ( !FD_ISSET(Unreliable_socket, &rfds) ){
399  return;
400  }
401 
402  // get data off the socket and process
403  read_len = SOCKET_ERROR;
404  switch ( Socket_type ) {
405  case NET_TCP:
406  from_len = sizeof(SOCKADDR_IN);
407  read_len = recvfrom( Unreliable_socket, (char*)packet_read.data, MAX_TOP_LAYER_PACKET_SIZE, 0, (SOCKADDR*)&ip_addr, &from_len);
408  break;
409 
410  default:
411  Assert(0);
412  return;
413  }
414 
415  // set the from_addr for storage into the packet buffer structure
416  from_addr.type = Socket_type;
417 
418  switch ( Socket_type ) {
419  case NET_TCP:
420  from_addr.port = ntohs( ip_addr.sin_port );
421  memset(from_addr.addr, 0x00, 6);
422 #ifdef _WIN32
423  memcpy(from_addr.addr, &ip_addr.sin_addr.S_un.S_addr, 4); //-V512
424 #else
425  memcpy(from_addr.addr, &ip_addr.sin_addr.s_addr, 4); //-V512
426 #endif
427  break;
428 
429  default:
430  Assert(0);
431  return;
432  // break;
433  }
434 
435  if ( read_len == SOCKET_ERROR ) {
436  ml_string("Socket error on socket_get_data()");
437  break;
438  }
439 
440  // determine the packet type
441  int packet_type = packet_read.data[0];
442  Assertion(((packet_type >= 0) && (packet_type < PSNET_NUM_TYPES)), "Invalid packet_type found. Packet type %d does not exist", packet_type);
443  if((packet_type >= 0) && (packet_type < PSNET_NUM_TYPES)){
444  // buffer the packet
445  psnet_buffer_packet(&Psnet_top_buffers[packet_type], packet_read.data + 1, read_len - 1, &from_addr);
446  }
447  }
448 }
449 
450 
451 // -------------------------------------------------------------------------------------------------------
452 // PSNET 2 FUNCTIONS
453 //
454 
458 void psnet_init( int protocol, int port_num )
459 {
460  int idx;
461  Tcp_active = 0;
462 #ifdef _WIN32
463  const char *internet_connection;
464  WSADATA wsa_data;
465 #endif
466 
467  // GAME PORT INITIALIZATION STUFF
469  ml_string("Skipping psnet_init() because network already running");
470  return;
471  }
472 
473 // sort of a hack; assume unix users are always on LAN :)
474 #ifdef _WIN32
475  internet_connection = os_config_read_string(NULL, "NetworkConnection", "none");
476  if ( !stricmp(internet_connection, NOX("dialup")) ) {
477  ml_string("psnet_init() detected dialup connection");
478 
480  } else if ( !stricmp(internet_connection, NOX("lan")) ) {
481  ml_string("psnet_init() detected lan connection");
482 
484  } else {
485  ml_string("psnet_init() detected no connection");
486 
488  }
489 #else
491 #endif
492 
494 #ifdef _WIN32
495  if (WSAStartup(0x101, &wsa_data )){
496  return;
497  }
498 #endif
499 
500  // get the port for running this game on. Be careful that it cannot be out of bounds
502  if ( (port_num > 1023) && (port_num < USHRT_MAX) ) {
503  Psnet_default_port = (ushort)port_num;
504  }
505 
506  // initialize TCP now
507  Tcp_active = 1;
508  if(!psnet_init_tcp()){
509  ml_printf("Error on TCP startup %d", Tcp_failure_code);
510 
511  Tcp_active = 0;
512  } else {
514  ml_printf("Error on TCP startup %d", Tcp_failure_code);
515 
516  Tcp_active = 0;
517  }
518  }
519 
520  // clear reliable sockets
521  reliable_socket *rsocket;
522  int j;
523  for(j=0; j<MAXRELIABLESOCKETS; j++){
524  rsocket=&Reliable_sockets[j];
525  memset(rsocket,0,sizeof(reliable_socket));
526  }
527 
528  // determine if we've successfully initialized the protocol we want
529  if(!Tcp_active){
531 
532  ml_string("No protocol in psnet_init()!");
533  }
534 
535  // specified network timeout
537  if(Cmdline_timeout > 0){
539  }
540 
541 #ifdef _WIN32
542  // set ras status
543  psnet_ras_status();
544 #endif
545 
547  // set network to be running
549 
550  // determine if our socket can broadcast
552 
553  // initialize all packet type buffers
554  for(idx=0; idx<PSNET_NUM_TYPES; idx++){
555  psnet_buffer_init(&Psnet_top_buffers[idx]);
556  }
557  }
558 }
559 
564 {
566  return;
567  }
568 
569 #ifdef _WIN32
570  WSACancelBlockingCall();
571 
572  if ( TCP_socket != INVALID_SOCKET ) {
573  shutdown( TCP_socket, 1 );
575  }
576 
577  if (WSACleanup()) {
578  }
579 #else
580  if ( TCP_socket != (int)INVALID_SOCKET ) {
581  shutdown( TCP_socket, 1 );
582  close( TCP_socket );
583  }
584 #endif
585 
586  // close down all reliable sockets - this forces them to
587  // send a disconnect to any remote machines
588  psnet_rel_close();
589 
591 }
592 
596 int psnet_use_protocol( int protocol )
597 {
598  socklen_t len;
599  SOCKADDR_IN ip_addr;
600  const char *custom_ip = NULL;
601 
602  // zero out my address
604  memset( &Psnet_my_addr, 0, sizeof(Psnet_my_addr) );
605 
606  // wait until we choose a protocol to determine if we can broadcast
607  Can_broadcast = 0;
608 
609  ml_string("In psnet_use_protocol()");
610 
611  switch ( protocol ) {
612  case NET_TCP:
614  ml_string("Network_status != NETWORK_STATUS_RUNNING in NET_TCP in psnet_use_protocol()");
615  return 0;
616  }
617 
618  // assign the TCP_* sockets to the socket values used elsewhere
620 
622  if(Can_broadcast){
623  ml_string("Psnet : TCP broadcast");
624  }
625 
626  // get the socket name for the TCP_socket, and put it into My_addr
627  len = sizeof(SOCKADDR_IN);
628  if ( getsockname(TCP_socket, (SOCKADDR *)&ip_addr, &len) == SOCKET_ERROR ) {
629  ml_printf("Unable to get sock name for TCP unreliable socket (%d)", WSAGetLastError() );
630  return 0;
631  }
632 
633  // check user-specified IP for getting around NAT
634  custom_ip = os_config_read_string( NOX("Network"), NOX("CustomIP"), NULL );
635 
636  if (custom_ip != NULL) {
637  SOCKADDR_IN custom_address;
638 
639 #ifndef WIN32
640  if ( inet_aton(custom_ip, &custom_address.sin_addr) ) {
641 #else
642  if ( (custom_address.sin_addr.s_addr = inet_addr(custom_ip)) != INADDR_NONE ) {
643 #endif
644  memcpy(&ip_addr.sin_addr, &custom_address.sin_addr, sizeof(custom_address.sin_addr));
645  } else {
646  ml_printf("WARNING => psnet_get_ip() custom IP is invalid: %s", custom_ip);
647  }
648  }
649 
650  memcpy(Psnet_my_addr.addr, &ip_addr.sin_addr, sizeof(ip_addr.sin_addr));
651  Psnet_my_addr.port = Psnet_default_port;
652 
653  ml_string("Psnet using - NET_TCP");
654  break;
655 
656  default:
657  Int3();
658  return 0;
659  }
660 
661  Psnet_my_addr.type = protocol;
662  Socket_type = protocol;
663 
664  return 1;
665 }
666 
671 {
672  // first case is when "none" is selected
674  return NETWORK_ERROR_NO_TYPE;
675  }
676 
677  // first, check the connection status of the network
680 
683  }
684 
685  // network is running -- be sure that the RAS people know to connect if they currently cannot.
686 
688  // if on a dialup connection, be sure that RAS is active.
689  if ( !Ras_connected ) {
691  }
692  } else if ( Psnet_connection == NETWORK_CONNECTION_LAN ) {
693  // if on a LAN, and they have a dialup connection active, return error to indicate that they need
694  // to pick the right connection type
695  if ( Ras_connected ) {
697  }
698  }
699  return NETWORK_ERROR_NONE;
700 }
701 
705 char* psnet_addr_to_string( char * text, net_addr * address )
706 {
707 
709  strcpy( text, XSTR("[no networking]",910) );
710  return text;
711  }
712 
713  in_addr temp_addr;
714 
715  switch ( address->type ) {
716  case NET_TCP:
717  memcpy(&temp_addr.s_addr, address->addr, 4);
718  strcpy( text, inet_ntoa(temp_addr) );
719  break;
720 
721  default:
722  break;
723 
724  } // end switch
725 
726  return text;
727 }
728 
732 void psnet_string_to_addr( net_addr * address, char * text )
733 {
734  struct hostent *he;
735  char str[255], *c, *port;
736  in_addr addr;
737 
739  strcpy( text, XSTR("[no networking]",910) );
740  return;
741  }
742 
743  // copy the text string to local storage to look for ports
744  Assert( strlen(text) < 255 );
745  strcpy_s(str, text);
746  c = strrchr(str, ':');
747  port = NULL;
748  if ( c ) {
749  *c = '\0';
750  port = c+1;
751  }
752 
753  switch ( address->type ) {
754  case NET_TCP:
755  addr.s_addr = inet_addr(str);
756  // if we get INADDR_NONE returns, then we need to try and resolve the host
757  // name
758  if ( addr.s_addr == INADDR_NONE ) {
759  he = gethostbyname( str );
760  // returns a non-null pointer if successful, so get the address
761  if ( he ) {
762  addr.s_addr = ((in_addr *)(he->h_addr))->s_addr; // this is the address in network byte order
763  } else {
764  addr.s_addr = INADDR_NONE;
765  }
766  }
767 
768  memset(address->addr, 0x00, 6);
769  memcpy(address->addr, &addr.s_addr, 4); //-V512
770  if ( port ){
771  address->port = (ushort)(atoi(port));
772  }
773  break;
774 
775  default:
776  Assert(0);
777  break;
778 
779  } // end switch
780 }
781 
785 int psnet_same( net_addr * a1, net_addr * a2 )
786 {
787  return !memcmp(a1->addr, a2->addr, 6) && a1->port == a2->port;
788 }
789 
793 int psnet_send( net_addr * who_to, void * data, int len, int np_index )
794 {
795  // send data unreliably
796  SOCKET send_sock;
797  SOCKADDR_IN sockaddr; // UDP/TCP socket structure
798  int ret, send_len;
799  ubyte iaddr[6], *send_data;
800  short port;
801  fd_set wfds;
802  struct timeval timeout;
803 
804  // always use the unreliable socket
805  send_sock = Unreliable_socket;
806 
808  ml_string("Network ==> Socket not inited in psnet_send");
809  return 0;
810  }
811 
812  if ( psnet_same( who_to, &Psnet_my_addr) ){
813  return 0;
814  }
815 
816  memset(iaddr, 0x00, 6);
817  memcpy(iaddr, who_to->addr, 6);
818 
819  if ( memcmp(iaddr, Null_address, 6) == 0) {
820  ml_string("Network ==> send to address is 0 in psnet_send");
821  return 0;
822  }
823 
824  port = who_to->port;
825 
826  if ( port == 0) {
827  ml_printf("Network ==> destination port %d invalid in psnet_send", port);
828  return 0;
829  }
830 
831  // stuff the data with the type
832  send_data = (ubyte*)data;
833  send_len = len;
834 
835  FD_ZERO(&wfds);
836  FD_SET( send_sock, &wfds );
837  timeout.tv_sec = 0;
838  timeout.tv_usec = 0;
839 
840 #ifdef _WIN32
841  if ( SELECT( -1, NULL, &wfds, NULL, &timeout, PSNET_TYPE_UNRELIABLE) == SOCKET_ERROR ) {
842 #else
843  if ( SELECT( send_sock+1, NULL, &wfds, NULL, &timeout, PSNET_TYPE_UNRELIABLE) == SOCKET_ERROR ) {
844 #endif
845  ml_printf("Error on blocking select for write %d", WSAGetLastError() );
846  return 0;
847  }
848 
849  // if the write file descriptor is not set, then bail!
850  if ( !FD_ISSET(send_sock, &wfds ) ){
851  return 0;
852  }
853 
854  ret = SOCKET_ERROR;
855  switch ( who_to->type ) {
856  case NET_TCP:
857  sockaddr.sin_family = AF_INET;
858  memcpy(&sockaddr.sin_addr.s_addr, iaddr, 4);
859  sockaddr.sin_port = htons(port);
860 
861  multi_rate_add(np_index, "udp(h)", send_len + UDP_HEADER_SIZE);
862  multi_rate_add(np_index, "udp", send_len);
863  ret = SENDTO( send_sock, (char *)send_data, send_len, 0, (SOCKADDR*)&sockaddr, sizeof(sockaddr), PSNET_TYPE_UNRELIABLE );
864  break;
865 
866  default:
867  Assert(0); // unknown protocol
868  break;
869 
870  } // end switch
871 
872  if ( ret != SOCKET_ERROR ) {
873  return 1;
874  }
875  return 0;
876 }
877 
881 int psnet_get( void * data, net_addr * from_addr )
882 {
883  int buffer_size;
884 
885  // try and get a free buffer and return its size
886  if(psnet_buffer_get_next(&Psnet_top_buffers[PSNET_TYPE_UNRELIABLE], (ubyte*)data, &buffer_size, from_addr)){
887  return buffer_size;
888  }
889 
890  // return nothing
891  return 0;
892 }
893 
897 int psnet_broadcast( net_addr * who_to, void * data, int len )
898 {
900  ml_string("Network ==> Socket not inited in psnet_broadcast");
901  return 0;
902  }
903 
904  if ( !Can_broadcast ) {
905  ml_string("Cannot broadcast -- returning without doing anything");
906  return 0;
907  }
908 
909  ubyte broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
910 
911  // broadcasting works on a local subnet which is all we really want to do for now anyway.
912  // we might keep this in as an option for freespace later.
913  switch ( who_to->type ) {
914  case NET_TCP:
915  memcpy(who_to->addr, broadcast, 6);
916  psnet_send(who_to, data, len);
917  break;
918 
919  } // end switch
920 
921  return 1;
922 }
923 
928 {
929  ubyte data[MAX_TOP_LAYER_PACKET_SIZE + 250];
930  net_addr from_addr;
931 
932  while ( psnet_get( data, &from_addr ) > 0 ) ;
933 }
934 
938 int psnet_is_valid_ip_string( char *ip_string, int allow_port )
939 {
940  in_addr addr;
941  struct hostent *host_ent;
942  char str[255], *c;
943 
944  // our addresses may have ports, so make local copy and remove port number
945  Assert( strlen(ip_string) < 255 );
946  strcpy_s(str, ip_string);
947  c = strrchr(str, ':');
948  if ( c ){
949  *c = '\0';
950  }
951 
952  addr.s_addr = inet_addr(ip_string);
953  if ( addr.s_addr != INADDR_NONE ){
954  // make sure the ip string is a valid format string
955  if(psnet_is_valid_numeric_ip(ip_string)){
956  return 1;
957  }
958  }
959 
960  // try name resolution
961  host_ent = gethostbyname( ip_string );
962  if ( !host_ent ){
963  return 0;
964  }
965 
966  // valid host entry so return 1;
967  return 1;
968 }
969 
970 
971 // -------------------------------------------------------------------------------------------------------
972 // PSNET 2 RELIABLE SOCKET FUNCTIONS
973 //
974 
975 void psnet_rel_send_ack(SOCKADDR *raddr, unsigned int sig, ubyte link_type, float time_sent)
976 {
977  int ret, sig_tmp;
978  reliable_header ack_header;
979  ack_header.type = RNT_ACK;
980  ack_header.data_len = sizeof(unsigned int);
981  ack_header.send_time = time_sent;
982  ack_header.send_time = INTEL_FLOAT(&ack_header.send_time);
983  sig_tmp = INTEL_INT(sig);
984  memcpy(&ack_header.data,&sig_tmp,sizeof(unsigned int));
985  switch (link_type) {
986  case NET_TCP:
987  if(!Tcp_active){
988  ml_string("No TCP in rel_send_ack()");
989  return;
990  }
991  ret = SENDTO(Unreliable_socket, (char *)&ack_header, RELIABLE_PACKET_HEADER_ONLY_SIZE+ack_header.data_len, 0, raddr, sizeof(SOCKADDR), PSNET_TYPE_RELIABLE);
992  if (ret == -1) {
993  ml_string("TCP SENDTO failed in rel_send_ack()");
994  }
995  break;
996  default:
997  ml_string("Unknown protocol type in nw_SendReliable()");
998  break;
999  }
1000 }
1001 
1009 {
1010  reliable_header diss_conn_header;
1011 
1012  // if the socket is out of range
1013  if (*sockp >= MAXRELIABLESOCKETS) {
1014  if (*sockp != INVALID_SOCKET) {
1015  ml_printf("Invalid socket id passed to nw_NewCloseSocket() -- %d",*sockp);
1016  }
1017 
1018  return;
1019  }
1020 
1021  ml_printf("Closing socket %d",*sockp);
1022 
1023  // go through every buffer and "free it up(tm)"
1024  int i;
1025  for(i=0;i<MAXNETBUFFERS;i++){
1026  if(Reliable_sockets[*sockp].rbuffers[i]){
1027  if(Reliable_sockets[*sockp].rbuffers[i] != NULL){
1028  vm_free(Reliable_sockets[*sockp].rbuffers[i]);
1029  }
1030  Reliable_sockets[*sockp].rbuffers[i] = NULL;
1031  Reliable_sockets[*sockp].rsequence[i] = 0;
1032  }
1033  if(Reliable_sockets[*sockp].sbuffers[i]){
1034  if(Reliable_sockets[*sockp].sbuffers[i] != NULL){
1035  vm_free(Reliable_sockets[*sockp].sbuffers[i]);
1036  }
1037  Reliable_sockets[*sockp].sbuffers[i] = NULL;
1038  Reliable_sockets[*sockp].rsequence[i] = 0;
1039  }
1040  }
1041 
1042  // send a disconnect packet to the socket on the other end
1043  diss_conn_header.type = RNT_DISCONNECT;
1044  diss_conn_header.seq = CONNECTSEQ;
1045  diss_conn_header.data_len = 0;
1046  if(*sockp==Serverconn){
1047  Serverconn = 0xffffffff;
1048  }
1049  switch ( Reliable_sockets[*sockp].connection_type ) {
1050  case NET_TCP:
1051  if(!Tcp_active){
1052  return;
1053  }
1054  SENDTO(Unreliable_socket, (char *)&diss_conn_header,RELIABLE_PACKET_HEADER_ONLY_SIZE,0,&Reliable_sockets[*sockp].addr,sizeof(SOCKADDR), PSNET_TYPE_RELIABLE);
1055  break;
1056  default:
1057  ml_string("Unknown protocol type in nw_CloseSocket()!");
1058  break;
1059  }
1060  memset(&Reliable_sockets[*sockp],0,sizeof(reliable_socket));
1061  Reliable_sockets[*sockp].status = RNF_UNUSED;
1062 }
1063 
1064 // function to check the status of the reliable socket and try to re-initialize it if necessary.
1065 // win95 seems to have trouble doing a reinit of the socket immediately after close, so this
1066 // function exists to check the status, and reinitialize if we need to
1068 {
1069  return 1;
1070 }
1071 
1075 int psnet_rel_send(PSNET_SOCKET_RELIABLE socketid, ubyte *data, int length, int np_index)
1076 {
1077  int i;
1078  int bytesout = 0;
1079  reliable_socket *rsocket;
1080 
1081  if(socketid >= MAXRELIABLESOCKETS){
1082  ml_printf("Invalid socket id passed to psnet_rel_send() -- %d",socketid);
1083  return -1;
1084  }
1085 
1086  Assert(length < (int)sizeof(reliable_header));
1087  psnet_rel_work();
1088 
1089  rsocket=&Reliable_sockets[socketid];
1090  if(rsocket->status!=RNF_CONNECTED) {
1091  //We can't send because this isn't a connected reliable socket.
1092  ml_printf("Can't send packet because of status %d in nw_SendReliable(). socket = %d",rsocket->status,socketid);
1093  return -1;
1094  }
1095 
1096  // Add the new packet to the sending list and send it.
1097  for(i=0;i<MAXNETBUFFERS;i++){
1098  if(NULL==rsocket->sbuffers[i]){
1099  reliable_header send_header;
1100  int send_this_packet=1;
1101 
1102  rsocket->send_len[i] = length;
1104 
1105  memcpy(rsocket->sbuffers[i]->buffer,data,length);
1106 
1107  send_header.seq = INTEL_SHORT( rsocket->theirsequence );
1108  rsocket->ssequence[i] = rsocket->theirsequence;
1109 
1110  memcpy(send_header.data,data,length);
1111  send_header.data_len = INTEL_SHORT( (ushort)length );
1112  send_header.type = RNT_DATA;
1113  send_header.send_time = psnet_get_time();
1114  send_header.send_time = INTEL_FLOAT( &send_header.send_time ) ;
1115 
1116  if (send_this_packet){
1117  switch ( rsocket->connection_type ){
1118  case NET_TCP:
1119  if(!Tcp_active){
1120  return 0;
1121  }
1122  multi_rate_add(np_index, "tcp(h)", RELIABLE_PACKET_HEADER_ONLY_SIZE+rsocket->send_len[i]);
1123  bytesout = SENDTO(Unreliable_socket, (char *)&send_header,RELIABLE_PACKET_HEADER_ONLY_SIZE+rsocket->send_len[i],0,&rsocket->addr,sizeof(SOCKADDR), PSNET_TYPE_RELIABLE);
1124  break;
1125  default:
1126  ml_string("Unknown protocol type in nw_SendReliable()!");
1127  Int3();
1128  break;
1129  }
1130  }
1131 
1132  if((bytesout==SOCKET_ERROR)&&(WSAEWOULDBLOCK==WSAGetLastError())){
1133  //This will cause it to try to send again next frame. (or sooner)
1134  rsocket->timesent[i] = psnet_get_time()-(NETRETRYTIME*4);
1135  } else {
1136  rsocket->timesent[i] = psnet_get_time();
1137  }
1138 
1139 
1140  rsocket->theirsequence++;
1141  return bytesout;
1142  }
1143  }
1144  ml_printf("PSNET RELIABLE SEND BUFFER OVERRUN. socket = %d",socketid);
1145  return 0;
1146 }
1147 
1148 // Return codes:
1149 // -1 socket not connected
1150 // 0 No packet ready to receive
1151 // >0 Buffer filled with the number of bytes recieved
1152 int psnet_rel_get(PSNET_SOCKET socketid, ubyte *buffer, int max_len)
1153 {
1154  int i;
1155 
1156  reliable_socket *rsocket = NULL;
1157  psnet_rel_work();
1158  if(socketid >= MAXRELIABLESOCKETS){
1159  ml_printf("Invalid socket id passed to nw_NewReceiveReliable() -- %d",socketid);
1160  return -1;
1161  }
1162  rsocket = &Reliable_sockets[socketid];
1163  if( (RNF_CONNECTED!=rsocket->status) && (RNF_LIMBO!=rsocket->status) ){
1164  ml_printf("Can't receive packet because it isn't connected in nw_ReceiveReliable(). socket = %d",socketid);
1165  return 0;
1166  }
1167  //If the buffer position is the position we are waiting for, fill in
1168  //the buffer we received in the call to this function and return true
1169 
1170  for(i=0; i<MAXNETBUFFERS; i++){
1171  if((rsocket->rsequence[i] == rsocket->oursequence) && rsocket->rbuffers[i]){
1172  memcpy(buffer,rsocket->rbuffers[i]->buffer, rsocket->recv_len[i]);
1173  vm_free(rsocket->rbuffers[i]);
1174  rsocket->rbuffers[i] = NULL;
1175  rsocket->rsequence[i] = 0;
1176  rsocket->oursequence++;
1177  return rsocket->recv_len[i];
1178  }
1179  }
1180 
1181  return 0;
1182 }
1183 
1188 {
1189  int i,j;
1190  int rcode = -1;
1191  int max_len = NETBUFFERSIZE;
1192  fd_set read_fds;
1193  TIMEVAL timeout;
1194  static reliable_header rcv_buff;
1195  static SOCKADDR rcv_addr;
1196  int bytesin = 0;
1197  int addrlen = sizeof(SOCKADDR);
1198  timeout.tv_sec=0;
1199  timeout.tv_usec=0;
1200 
1202 
1203  // negotitate initial connection with the server
1204  reliable_socket *rsocket = NULL;
1205  if(Serverconn != 0xffffffff){
1206  //Check to see if we need to send a packet out.
1207  if((Reliable_sockets[Serverconn].status==RNF_LIMBO) && ((Serverconn != 0xffffffff) && fl_abs((psnet_get_time() - Last_sent_iamhere))>NETRETRYTIME) ){
1208  reliable_header conn_header;
1209  //Now send I_AM_HERE packet
1210  conn_header.type = RNT_I_AM_HERE;
1211  conn_header.seq = (ushort)(~CONNECTSEQ);
1212  conn_header.data_len = 0;
1214  int ret = SOCKET_ERROR;
1215  switch ( Reliable_sockets[Serverconn].connection_type ) {
1216  case NET_TCP:
1217  if(!Tcp_active){
1218  ml_string("Unable to use this network connection type in nw_WorkReliable()");
1219  Int3();
1220  return;
1221  }
1222  ret = SENDTO(Unreliable_socket, (char *)&conn_header,RELIABLE_PACKET_HEADER_ONLY_SIZE,0,&Reliable_sockets[Serverconn].addr,sizeof(SOCKADDR), PSNET_TYPE_RELIABLE);
1223  break;
1224  default:
1225  ml_string("Unknown protocol type in nw_WorkReliable()!");
1226  Int3();
1227  break;
1228  }
1229 
1230  if((ret == SOCKET_ERROR) && (WSAEWOULDBLOCK == WSAGetLastError())){
1232  } else {
1233  Reliable_sockets[Serverconn].last_packet_sent = psnet_get_time();
1234  }
1235  }
1236  }
1237 
1238  ubyte link_type;
1239  net_addr d3_rcv_addr;
1240  SOCKADDR_IN *rcvaddr;
1241  int udp_has_data = 0;
1242  do {
1243  rsocket = NULL;
1244  //Check UDP
1245  if(Tcp_active && (Socket_type == NET_TCP)){
1246  FD_ZERO(&read_fds);
1247  FD_SET(Unreliable_socket, &read_fds);
1248 #ifdef _WIN32
1249  udp_has_data = SELECT(0,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_RELIABLE);
1250 #else
1251  udp_has_data = SELECT(Unreliable_socket+1, &read_fds,NULL,NULL,&timeout, PSNET_TYPE_RELIABLE);
1252 #endif
1253  }
1254  bytesin = 0;
1255  addrlen = sizeof(SOCKADDR);
1256 
1257  if(udp_has_data){
1258  SOCKADDR_IN *tcp_addr = (SOCKADDR_IN *)&rcv_addr;
1259  memset(&d3_rcv_addr,0,sizeof(net_addr));
1260  memset(&rcv_addr,0,sizeof(SOCKADDR));
1261  bytesin = RECVFROM(Unreliable_socket, (char *)&rcv_buff,sizeof(reliable_header), 0, (SOCKADDR *)&rcv_addr,&addrlen, PSNET_TYPE_RELIABLE);
1262  rcv_buff.seq = INTEL_SHORT( rcv_buff.seq ); //-V570
1263  rcv_buff.data_len = INTEL_SHORT( rcv_buff.data_len ); //-V570
1264  rcv_buff.send_time = INTEL_FLOAT( &rcv_buff.send_time );
1265  memcpy(d3_rcv_addr.addr, &tcp_addr->sin_addr.s_addr, 4); //-V512
1266  d3_rcv_addr.port = tcp_addr->sin_port;
1267  d3_rcv_addr.type = NET_TCP;
1268  link_type = NET_TCP;
1269  } else {
1270  //Neither socket had data waiting
1271  break;
1272  }
1273 
1274  if(bytesin==-1){
1275  ml_printf("recvfrom returned an error! -- %d",WSAGetLastError());
1276  return;
1277  }
1278  if(bytesin){
1279  //Someone wants to connect, so find a slot
1280  if(rcv_buff.type == RNT_REQ_CONN){
1281  for(i=1; i<MAXRELIABLESOCKETS; i++){
1282  if( (Reliable_sockets[i].status == RNF_CONNECTED) || (Reliable_sockets[i].status == RNF_LIMBO) ){
1283  if(memcmp(&d3_rcv_addr, &Reliable_sockets[i].m_net_addr, sizeof(net_addr)) == 0){
1284  //We already have a reliable link to this user, so we will ignore it...
1285  ml_printf("Received duplicate connection request. %d",i);
1286  psnet_rel_send_ack(&Reliable_sockets[i].addr, rcv_buff.seq, link_type, rcv_buff.send_time);
1287  //We will change this as a hack to prevent later code from hooking us up
1288  rcv_buff.type = 0xff;
1289  continue;
1290  }
1291  }
1292  }
1293  for(i=1; i<MAXRELIABLESOCKETS; i++){
1294  if(Reliable_sockets[i].status == RNF_UNUSED){
1295  //Add the new connection here.
1296  Reliable_sockets[i].connection_type=link_type;
1297  memcpy(&Reliable_sockets[i].m_net_addr, &d3_rcv_addr, sizeof(net_addr));
1298  memcpy(&Reliable_sockets[i].addr ,&rcv_addr, sizeof(SOCKADDR));
1299  Reliable_sockets[i].ping_pos = 0;
1300  Reliable_sockets[i].num_ping_samples = 0;
1301  Reliable_sockets[i].status = RNF_LIMBO;
1302  Reliable_sockets[i].last_packet_received = psnet_get_time();
1303  rsocket = &Reliable_sockets[i];
1304  rcvaddr = (SOCKADDR_IN *)&rcv_addr;
1305  ml_printf("Connect from %s:%d", inet_ntoa(rcvaddr->sin_addr), htons(rcvaddr->sin_port));
1306  break;
1307  }
1308  }
1309  if(i==MAXRELIABLESOCKETS){
1310  //No more connections!
1311  ml_string("Out of incoming reliable connection sockets");
1312  continue;
1313  }
1314  psnet_rel_send_ack(&rsocket->addr, rcv_buff.seq, link_type, rcv_buff.send_time);
1315  }
1316 
1317  //Find out if this is a packet from someone we were expecting a packet.
1318  rcvaddr = (SOCKADDR_IN *)&rcv_addr;
1319  for(i=1; i<MAXRELIABLESOCKETS; i++){
1320  if(memcmp(&d3_rcv_addr,&Reliable_sockets[i].m_net_addr,sizeof(net_addr)) == 0){
1321  rsocket=&Reliable_sockets[i];
1322  break;
1323  }
1324  }
1325  if(NULL == rsocket){
1326  ml_string("Received reliable data from unconnected client.");
1327  ml_printf("Received from %s:%d\n",inet_ntoa(rcvaddr->sin_addr),rcvaddr->sin_port);
1328  continue ;
1329  }
1330  rsocket->last_packet_received = psnet_get_time();
1331 
1332  if(rsocket->status != RNF_CONNECTED){
1333  //Get out of limbo
1334  if(rsocket->status == RNF_LIMBO){
1335  //this is our connection to the server
1336  if(Serverconn != 0xffffffff){
1337  if(rcv_buff.type == RNT_ACK){
1338  ushort *acknum = (ushort *)&rcv_buff.data;
1339  if(*acknum == (~CONNECTSEQ & 0xffff)){
1340  rsocket->status = RNF_CONNECTED;
1341  ml_string("Got ACK for IAMHERE!");
1342  }
1343  continue;
1344  }
1345  } else if(rcv_buff.type == RNT_I_AM_HERE){
1346  rsocket->status = RNF_CONNECTING;
1347  psnet_rel_send_ack(&rsocket->addr, rcv_buff.seq, link_type, rcv_buff.send_time);
1348  ml_string("Got IAMHERE!");
1349  continue;
1350  }
1351  }
1352  if((rcv_buff.type == RNT_DATA) && (Serverconn != 0xffffffff)){
1353  rsocket->status = RNF_CONNECTED;
1354  } else {
1355  rsocket->last_packet_received = psnet_get_time();
1356  continue;
1357  }
1358  }
1359  //Update the last recv variable so we don't need a heartbeat
1360  rsocket->last_packet_received = psnet_get_time();
1361 
1362  if(rcv_buff.type == RNT_HEARTBEAT){
1363  continue;
1364  }
1365  if(rcv_buff.type == RNT_ACK){
1366  //Update ping time
1367  rsocket->num_ping_samples++;
1368 
1369  rsocket->pings[rsocket->ping_pos] = rsocket->last_packet_received - rcv_buff.send_time;
1370  if(rsocket->num_ping_samples >= MAX_PING_HISTORY){
1371  float sort_ping[MAX_PING_HISTORY];
1372  for(int a=0;a<MAX_PING_HISTORY;a++){
1373  sort_ping[a] = rsocket->pings[a];
1374  }
1375 
1376  std::sort(sort_ping, sort_ping + MAX_PING_HISTORY);
1377  rsocket->mean_ping = ((sort_ping[MAX_PING_HISTORY/2]+sort_ping[(MAX_PING_HISTORY/2)+1]))/2;
1378  }
1379  rsocket->ping_pos++;
1380  if(rsocket->ping_pos >= MAX_PING_HISTORY){
1381  rsocket->ping_pos=0;
1382  }
1383 
1384  // if this is an ack for a send buffer on the socket, kill the send buffer. its done
1385  for(i=0; i<MAXNETBUFFERS; i++){
1386  unsigned int *acksig = (unsigned int *)&rcv_buff.data;
1387  if(rsocket){
1388  if(rsocket->sbuffers[i]){
1389  if(rsocket->ssequence[i] == INTEL_INT(*acksig)){
1390  Assert(rsocket->sbuffers[i] != NULL);
1391  vm_free(rsocket->sbuffers[i]);
1392  rsocket->sbuffers[i] = NULL;
1393  rsocket->ssequence[i] = 0;
1394  }
1395  }
1396  }
1397  }
1398  //remove that packet from the send buffer
1399  rsocket->last_packet_received = psnet_get_time();
1400  continue;
1401  }
1402 
1403  if(rcv_buff.type == RNT_DATA_COMP){
1404  //More2Come
1405  //Decompress it. Put it back in the buffer. Process it as RNT_DATA
1406  rcv_buff.type = RNT_DATA;
1407  }
1408  if(rcv_buff.type == RNT_DATA){
1409  //If the data is out of order by >= MAXNETBUFFERS-1 ignore that packet for now
1410  int seqdelta;
1411  seqdelta = rcv_buff.seq - rsocket->oursequence;
1412  if(seqdelta<0) seqdelta = seqdelta*-1;
1413  if(seqdelta>=MAXNETBUFFERS - 1){
1414  ml_string("Received reliable packet out of order!");
1415  //It's out of order, so we won't ack it, which will mean we will get it again soon.
1416  continue;
1417  }
1418  //else move data into the proper buffer position
1419  int savepacket=1;
1420 
1421  if(rsocket->oursequence < (0xffff - (MAXNETBUFFERS-1))){
1422  if (rsocket->oursequence > rcv_buff.seq){
1423  savepacket = 0;
1424  }
1425  } else {
1426  //Sequence is high, so prepare for wrap around
1427  if( ((unsigned short)(rcv_buff.seq + rsocket->oursequence)) > (MAXNETBUFFERS-1)){
1428  savepacket = 0;
1429  }
1430  }
1431 
1432  for(i=0; i<MAXNETBUFFERS; i++){
1433  if( (NULL != rsocket->rbuffers[i]) && (rsocket->rsequence[i] == rcv_buff.seq)){
1434  //Received duplicate packet!
1435  savepacket = 0;
1436  }
1437  }
1438  if(savepacket){
1439  if(rcv_buff.data_len>max_len){
1440  ml_string("Received oversized reliable packet!");
1441  //don't ack it, which will mean we will get it again soon.
1442  continue;
1443  }
1444  for(i=0; i<MAXNETBUFFERS; i++){
1445  if(NULL == rsocket->rbuffers[i]){
1446  rsocket->recv_len[i] = rcv_buff.data_len;
1448  memcpy(rsocket->rbuffers[i]->buffer,rcv_buff.data,rsocket->recv_len[i]);
1449  rsocket->rsequence[i] = rcv_buff.seq;
1450  break;
1451  }
1452  }
1453  }
1454  psnet_rel_send_ack(&rsocket->addr, rcv_buff.seq, link_type, rcv_buff.send_time);
1455  }
1456 
1457  }
1458  } while (udp_has_data>0);
1459 
1460  // Go through each reliable socket that is connected and do any needed work.
1461  for(j=0; j<MAXRELIABLESOCKETS; j++){
1462  rsocket=&Reliable_sockets[j];
1463 
1464  if(Serverconn == 0xffffffff){
1465  if(rsocket->status==RNF_LIMBO){
1467  ml_printf("Reliable (but in limbo) socket (%d) timed out in nw_WorkReliable().",j);
1468  memset(rsocket,0,sizeof(reliable_socket));
1469  rsocket->status = RNF_UNUSED;//Won't work if this is an outgoing connection.
1470  }
1471  }
1472  } else {
1473  if((rsocket->status == RNF_LIMBO) && (fl_abs((psnet_get_time() - First_sent_iamhere)) > Nettimeout)){
1474  rsocket->status = RNF_BROKEN;
1475  ml_printf("Reliable socket (%d) timed out in nw_WorkReliable().",j);
1476  }
1477  }
1478 
1479  if(rsocket->status == RNF_CONNECTED){
1480  float retry_packet_time;
1481  if((rsocket->mean_ping==0) || (rsocket->mean_ping > (NETRETRYTIME*4))){
1482  retry_packet_time = NETRETRYTIME;
1483  } else {
1484  if(rsocket->mean_ping<MIN_NET_RETRYTIME) {
1485  retry_packet_time = (float)MIN_NET_RETRYTIME;
1486  } else {
1487  retry_packet_time = ((float)(float)rsocket->mean_ping * (float)1.25);
1488  }
1489  }
1490  //Iterate through send buffers.
1491  for(i=0;i<MAXNETBUFFERS;i++){
1492  // send again
1493  if((rsocket->sbuffers[i]) && (fl_abs((psnet_get_time() - rsocket->timesent[i])) >= retry_packet_time)) {
1494  reliable_header send_header;
1495  send_header.send_time = psnet_get_time();
1496  send_header.send_time = INTEL_FLOAT( &send_header.send_time );
1497  send_header.seq = INTEL_SHORT( rsocket->ssequence[i] );
1498  memcpy(send_header.data,rsocket->sbuffers[i]->buffer,rsocket->send_len[i]);
1499  send_header.data_len = INTEL_SHORT( (ushort)rsocket->send_len[i] );
1500  send_header.type = RNT_DATA;
1501  rcode = SENDTO(Unreliable_socket, (char *)&send_header, RELIABLE_PACKET_HEADER_ONLY_SIZE + rsocket->send_len[i], 0, &rsocket->addr, sizeof(SOCKADDR), PSNET_TYPE_RELIABLE);
1502 
1503  if((rcode == SOCKET_ERROR) && (WSAEWOULDBLOCK == WSAGetLastError())){
1504  //The packet didn't get sent, flag it to try again next frame
1505  rsocket->timesent[i] = psnet_get_time()-(NETRETRYTIME*4);
1506  } else {
1507  rsocket->last_packet_sent = psnet_get_time();
1508  rsocket->timesent[i] = psnet_get_time();
1509  }
1510 
1511  }//getcwd
1512  }
1513 
1514  if((rsocket->status == RNF_CONNECTED) && (fl_abs((psnet_get_time() - rsocket->last_packet_sent)) > NETHEARTBEATTIME)) {
1515  reliable_header send_header;
1516  send_header.send_time = psnet_get_time();
1517  send_header.send_time = INTEL_FLOAT( &send_header.send_time );
1518  send_header.seq = 0;
1519  send_header.data_len = 0;
1520  send_header.type = RNT_HEARTBEAT;
1521 
1522  rcode = SENDTO(Unreliable_socket, (char *)&send_header, RELIABLE_PACKET_HEADER_ONLY_SIZE, 0, &rsocket->addr, sizeof(SOCKADDR), PSNET_TYPE_RELIABLE);
1523 
1524  if((rcode != SOCKET_ERROR) && (WSAEWOULDBLOCK != WSAGetLastError())){
1525  //It must have been sent
1526  rsocket->last_packet_sent = psnet_get_time();
1527  }
1528  }
1529 
1530  if((rsocket->status == RNF_CONNECTED) && (fl_abs((psnet_get_time() - rsocket->last_packet_received))>Nettimeout)){
1531  //This socket is hosed.....inform someone?
1532  ml_printf("Reliable Socket (%d) timed out in nw_WorkReliable().",j);
1533  rsocket->status = RNF_BROKEN;
1534  }
1535  }
1536  }
1537 }
1538 
1543 {
1544  if(socketid >= MAXRELIABLESOCKETS){
1545  return -1;
1546  }
1547 
1548  return Reliable_sockets[socketid].status;
1549 }
1550 
1556 {
1557  SOCKADDR_IN *ip_addr; // UDP/TCP socket structure
1558 
1559  psnet_rel_work();
1560  int i;
1561  for(i=1; i<MAXRELIABLESOCKETS; i++){
1562  if(Reliable_sockets[i].status == RNF_CONNECTING){
1563  Reliable_sockets[i].status = RNF_CONNECTED;
1564  ml_string("New reliable connection in nw_CheckListenSocket().");
1565 
1566  switch ( Reliable_sockets[i].connection_type ){
1567  case NET_TCP:
1568  ip_addr = (SOCKADDR_IN *)&Reliable_sockets[i].addr;
1569  memset(from_addr, 0x00, sizeof(net_addr));
1570  from_addr->port = ntohs( ip_addr->sin_port );
1571  from_addr->type = NET_TCP;
1572 #ifdef _WIN32
1573  memcpy(from_addr->addr, &ip_addr->sin_addr.S_un.S_addr, 4); //-V512
1574 #else
1575  memcpy(from_addr->addr, &ip_addr->sin_addr.s_addr, 4); //-V512
1576 #endif
1577  break;
1578 
1579  default:
1580  Int3();
1581  break;
1582  }
1583  return i;
1584  }
1585  }
1586  return INVALID_SOCKET;
1587 }
1588 
1594 {
1595  //Send out a RNT_REQ_CONN packet, and wait for it to be acked.
1596  SOCKADDR_IN sockaddr; // UDP/TCP socket structure
1597  SOCKADDR *addr; // pointer to SOCKADDR to make coding easier
1598  SOCKADDR rcv_addr;
1599  int addrlen;
1600  ubyte iaddr[6];
1601  ushort port;
1602  float first_sent_req = 0;
1603  static reliable_header conn_header;
1604  static reliable_header ack_header;
1605  int bytesin;
1606  struct timeval timeout;
1607  fd_set read_fds;
1608  int i;
1609  *socket = INVALID_SOCKET;
1610 
1611  memset(iaddr, 0x00, 6);
1612  memcpy(iaddr, &server_addr->addr, 6);
1613  port = (ushort)(server_addr->port); // Talk to the server listen port
1614 
1615  conn_header.type = RNT_REQ_CONN;
1616  conn_header.seq = CONNECTSEQ;
1617  conn_header.data_len = 0;
1618 
1619  timeout.tv_sec=0;
1620  timeout.tv_usec=0;
1621 
1622  if((server_addr->type == NET_TCP) && (!Tcp_active)){
1623  return;
1624  }
1625  //Flush out any left overs
1626  if(Tcp_active && (Socket_type == NET_TCP)){
1627  FD_ZERO(&read_fds);
1628  FD_SET(Unreliable_socket, &read_fds);
1629 #ifdef _WIN32
1630  while(SELECT(0, &read_fds, NULL, NULL, &timeout, PSNET_TYPE_RELIABLE)){
1631 #else
1632  while(SELECT(Unreliable_socket+1, &read_fds, NULL, NULL, &timeout, PSNET_TYPE_RELIABLE)){
1633 #endif
1634  addrlen = sizeof(SOCKADDR);
1635  bytesin = RECVFROM(Unreliable_socket, (char *)&ack_header,sizeof(reliable_header),0,(SOCKADDR *)&rcv_addr,&addrlen, PSNET_TYPE_RELIABLE);
1636  if(bytesin==-1){
1637  ml_printf("UDP recvfrom returned an error! -- %d",WSAGetLastError());
1638  break;
1639  }
1640  FD_ZERO(&read_fds);
1641  FD_SET(Unreliable_socket, &read_fds);
1642  }
1643  }
1644  memset(&ack_header,0,sizeof(reliable_header));
1645  bytesin = 0;
1646  SOCKET typeless_sock;
1647  net_addr d3_rcv_addr;
1648  memset(&d3_rcv_addr,0,sizeof(net_addr));
1649 
1650  switch ( server_addr->type ){
1651  case NET_TCP:
1652  sockaddr.sin_family = AF_INET;
1653  memcpy(&sockaddr.sin_addr.s_addr, iaddr, 4);
1654  sockaddr.sin_port = htons(port);
1655  addr = (SOCKADDR *)&sockaddr;
1657  ml_printf("Unable to send UDP packet in nw_ConnectToServer()! -- %d",WSAGetLastError());
1658  return;
1659  }
1660  memcpy(d3_rcv_addr.addr, &sockaddr.sin_addr.s_addr, 4); //-V512
1661  d3_rcv_addr.port = sockaddr.sin_port;
1662  d3_rcv_addr.type = NET_TCP;
1663  typeless_sock = Unreliable_socket;
1664  break;
1665 
1666  default:
1667  ml_string("Unknown protocol type in nw_ConnectToServer()!");
1668  Int3();
1669  return;
1670  }
1671 
1672 
1673  first_sent_req = psnet_get_time();
1674 
1675  //Wait until we get a response from the server or we timeout
1676 
1677  do {
1679 
1680  FD_ZERO(&read_fds);
1681  FD_SET(typeless_sock, &read_fds);
1682 #ifdef _WIN32
1683  if(SELECT(0, &read_fds, NULL,NULL,&timeout, PSNET_TYPE_RELIABLE)){
1684 #else
1685  if(SELECT(typeless_sock+1, &read_fds, NULL,NULL,&timeout, PSNET_TYPE_RELIABLE)){
1686 #endif
1687  ml_string("selected() in psnet_rel_connect_to_server()");
1688 
1689  addrlen = sizeof(SOCKADDR);
1690  bytesin = RECVFROM(typeless_sock,(char *)&ack_header,sizeof(reliable_header),0,(SOCKADDR *)&rcv_addr,&addrlen, PSNET_TYPE_RELIABLE);
1691  if(bytesin==-1){
1692  ml_printf("recvfrom returned an error! -- %d",WSAGetLastError());
1693  Int3();
1694  return;
1695  }
1696 
1697  ml_string("received data after select in psnet_rel_connect_to_server()");
1698  if(bytesin){
1699  ml_string("about to check ack_header.type");
1700  if(ack_header.type == RNT_ACK){
1701  short *acknum = (short *)&ack_header.data;
1702  if(*acknum == CONNECTSEQ){
1703  for(i=1; i<MAXRELIABLESOCKETS; i++){
1704  if(Reliable_sockets[i].status==RNF_UNUSED){
1705  //Add the new connection here.
1706  memset(&Reliable_sockets[i],0,sizeof(reliable_socket));
1707  Reliable_sockets[i].connection_type = (ubyte)server_addr->type;
1708  memcpy(&Reliable_sockets[i].m_net_addr,&d3_rcv_addr,sizeof(net_addr));
1709  Reliable_sockets[i].last_packet_received = psnet_get_time();
1710  memcpy(&Reliable_sockets[i].addr,&rcv_addr,sizeof(SOCKADDR));
1711  Reliable_sockets[i].status = RNF_LIMBO;
1712  *socket = i;
1713  ml_string("Successfully connected to server in nw_ConnectToServer().");
1714  //Now send I_AM_HERE packet
1715  conn_header.type = RNT_I_AM_HERE;
1716  conn_header.seq = (ushort)(~CONNECTSEQ);
1717  conn_header.data_len = 0;
1718  Serverconn = i;
1721  int rcode = SENDTO(typeless_sock,(char *)&conn_header,RELIABLE_PACKET_HEADER_ONLY_SIZE,0,addr,sizeof(SOCKADDR), PSNET_TYPE_RELIABLE);
1722  if(rcode == SOCKET_ERROR){
1723  *socket = INVALID_SOCKET;
1724  Reliable_sockets[i].status = RNF_UNUSED;
1725  memset(&Reliable_sockets[i],0,sizeof(reliable_socket));
1726  ml_string("Unable to send packet in nw_ConnectToServer()");
1727  return;
1728  }
1729  Reliable_sockets[i].last_packet_sent = psnet_get_time();
1730  float f;
1731  f = psnet_get_time();
1732  while((fl_abs((psnet_get_time() - f))<2) && (Reliable_sockets[i].status != RNF_CONNECTING)){
1733  psnet_rel_work();
1734  }
1735 
1736  return;
1737  }
1738  }
1739  ml_string("Out of reliable socket space in nw_ConnectToServer().");
1740  return;
1741  } else ml_string("Received out of sequence ACK in nw_ConnectToServer().");
1742  } else ml_string("Received something that isn't an ACK in nw_ConnectToServer().");
1743  } else ml_string("Received 0 bytes from recvfrom() in nw_ConnectToServer().");
1744  }
1745  } while(fl_abs((psnet_get_time() - first_sent_req)) < RELIABLE_CONNECT_TIME);
1746 }
1747 
1752 {
1753  SOCKADDR_IN local_address;
1754 
1755 #ifdef _WIN32
1757  local_address.sin_addr.s_addr = psnet_ras_status();
1758  if(local_address.sin_addr.s_addr == INADDR_NONE){
1759  local_address.sin_addr.s_addr = INADDR_ANY;
1760  }
1761  }
1762  else
1763 #endif // FIXME - always returns INADDR_ANY for LAN
1764  {
1765  // Init local address to zero
1766  local_address.sin_addr.s_addr = INADDR_ANY;
1767  }
1768 
1769  ml_printf("psnet_get_ip() reports IP : %s", inet_ntoa(local_address.sin_addr));
1770 
1771  return local_address.sin_addr.s_addr;
1772 }
1773 
1777 int psnet_init_rel_tcp(int port, int should_listen)
1778 {
1779  // success
1780  return 1;
1781 }
1782 
1784 {
1785  int idx;
1786  PSNET_SOCKET_RELIABLE sock;
1787 
1788  // kill all sockets
1789  for(idx=0; idx<MAXRELIABLESOCKETS; idx++){
1790  if(Reliable_sockets[idx].status != RNF_UNUSED){
1791  sock = idx;
1792  psnet_rel_close_socket(&sock);
1793  }
1794  }
1795 }
1796 
1797 // ------------------------------------------------------------------------------------------------------
1798 // PACKET BUFFERING FUNCTIONS
1799 //
1800 
1805 {
1806  int idx;
1807 
1808  // blast the buffer clean
1809  memset(l->psnet_buffers, 0, sizeof(network_packet_buffer) * MAX_PACKET_BUFFERS);
1810 
1811  // set all buffer sequence #'s to -1
1812  for(idx=0;idx<MAX_PACKET_BUFFERS;idx++){
1814  }
1815 
1816  // initialize the sequence #
1817  l->psnet_seq_number = 0;
1818  l->psnet_lowest_id = -1;
1819  l->psnet_highest_id = -1;
1820 }
1821 
1826 {
1827  int idx;
1828  int found_buf = 0;
1829 
1830  // find the first empty packet
1831  for(idx=0;idx<MAX_PACKET_BUFFERS;idx++){
1832  if(l->psnet_buffers[idx].sequence_number == -1){
1833  found_buf = 1;
1834  break;
1835  }
1836  }
1837 
1838  // if we didn't find the buffer, report an overrun
1839  if(!found_buf){
1840  ml_string("WARNING - Buffer overrun in psnet");
1841  } else {
1842  // copy in the data
1843  memcpy(l->psnet_buffers[idx].data, data, length);
1844  l->psnet_buffers[idx].len = length;
1845  memcpy(&l->psnet_buffers[idx].from_addr, from, sizeof(net_addr));
1847 
1848  // keep track of the highest id#
1850 
1851  // set the lowest id# for the first time
1852  if(l->psnet_lowest_id == -1){
1854  }
1855  }
1856 }
1857 
1862 {
1863  int idx;
1864  int found_buf = 0;
1865 
1866  // if there are no buffers, do nothing
1867  if((l->psnet_lowest_id == -1) || (l->psnet_lowest_id > l->psnet_highest_id)){
1868  return 0;
1869  }
1870 
1871  // search until we find the lowest packet index id#
1872  for(idx=0;idx<MAX_PACKET_BUFFERS;idx++){
1873  // if we found the buffer
1874  if(l->psnet_buffers[idx].sequence_number == l->psnet_lowest_id){
1875  found_buf = 1;
1876  break;
1877  }
1878  }
1879 
1880  // at this point, we should _always_ have found the buffer
1881  Assert(found_buf);
1882 
1883  // copy out the buffer data
1884  memcpy(data, l->psnet_buffers[idx].data, l->psnet_buffers[idx].len);
1885  *length = l->psnet_buffers[idx].len;
1886  memcpy(from, &l->psnet_buffers[idx].from_addr, sizeof(net_addr));
1887 
1888  // now we need to cleanup the packet list
1889 
1890  // mark the buffer as free
1892  l->psnet_lowest_id++;
1893 
1894  return 1;
1895 }
1896 
1897 // -------------------------------------------------------------------------------------------------------
1898 // PSNET 2 FORWARD DEFINITIONS
1899 //
1900 
1905 {
1906  char *token;
1907  char copy[100];
1908  int val1,val2,val3,val4;
1909 
1910  // get the first ip value
1911  strcpy_s(copy,ip);
1912  token = strtok(copy,".");
1913  if(token == NULL){
1914  return 0;
1915  } else {
1916  // get the value of the token
1917  val1 = atoi(token);
1918  if((val1 < 0) || (val1 > 255)){
1919  return 0;
1920  }
1921  }
1922 
1923  // second ip value
1924  token = strtok(NULL,".");
1925  if(token == NULL){
1926  return 0;
1927  } else {
1928  // get the value of the token
1929  val2 = atoi(token);
1930  if((val2 < 0) || (val2 > 255)){
1931  return 0;
1932  }
1933  }
1934 
1935  // third ip value
1936  token = strtok(NULL,".");
1937  if(token == NULL){
1938  return 0;
1939  } else {
1940  // get the value of the token
1941  val3 = atoi(token);
1942  if((val3 < 0) || (val3 > 255)){
1943  return 0;
1944  }
1945  }
1946 
1947  // third ip value
1948  token = strtok(NULL,"");
1949  if(token == NULL){
1950  return 0;
1951  } else {
1952  // get the value of the token
1953  val4 = atoi(token);
1954  if((val4 < 0) || (val4 > 255)){
1955  return 0;
1956  }
1957  }
1958 
1959  // make sure he hasn't entered all 0's
1960  if((val1 == 0) && (val2 == 0) && (val3 == 0) && (val4 == 0)){
1961  return 0;
1962  }
1963 
1964  // valid
1965  return 1;
1966 }
1967 
1968 #ifdef _WIN32 // Dial-Up Networking
1969 // function called from high level FreeSpace code to determine the status of the networking
1970 // code returns one of a handful of macros
1971 
1972 DWORD (__stdcall *pRasEnumConnections)(LPRASCONN lprasconn, LPDWORD lpcb, LPDWORD lpcConnections) = NULL;
1973 DWORD (__stdcall *pRasGetConnectStatus)(HRASCONN hrasconn, LPRASCONNSTATUS lprasconnstatus ) = NULL;
1974 DWORD (__stdcall *pRasGetProjectionInfo)(HRASCONN hrasconn, RASPROJECTION rasprojection, LPVOID lpprojection, LPDWORD lpcb ) = NULL;
1975 
1979 unsigned int psnet_ras_status()
1980 {
1981  int rval;
1982  unsigned long size, num_connections, i, valid_connections = 0;
1983  RASCONN rasbuffer[25];
1984  HINSTANCE ras_handle;
1985  unsigned long rasip=0;
1986  RASPPPIP projection;
1987 
1988  Ras_connected = 0;
1989 
1990  // first, call a LoadLibrary to load the RAS api
1991  ras_handle = LoadLibrary( "rasapi32.dll" );
1992  if ( ras_handle == NULL ) {
1993  return INADDR_ANY;
1994  }
1995 
1996  pRasEnumConnections = (DWORD (__stdcall *)(LPRASCONN, LPDWORD, LPDWORD))GetProcAddress(ras_handle, "RasEnumConnectionsA");
1997  if (!pRasEnumConnections) {
1998  FreeLibrary( ras_handle );
1999  return INADDR_ANY;
2000  }
2001  pRasGetConnectStatus = (DWORD (__stdcall *)(HRASCONN, LPRASCONNSTATUS))GetProcAddress(ras_handle, "RasGetConnectStatusA");
2002  if (!pRasGetConnectStatus) {
2003  FreeLibrary( ras_handle );
2004  return INADDR_ANY;
2005  }
2006  pRasGetProjectionInfo = (DWORD (__stdcall *)(HRASCONN, RASPROJECTION, LPVOID, LPDWORD))GetProcAddress(ras_handle, "RasGetProjectionInfoA");
2007  if (!pRasGetProjectionInfo) {
2008  FreeLibrary( ras_handle );
2009  return INADDR_ANY;
2010  }
2011 
2012  size = sizeof(rasbuffer);
2013  rasbuffer[0].dwSize = sizeof(RASCONN);
2014 
2015  rval = pRasEnumConnections( rasbuffer, &size, &num_connections );
2016  if ( rval ) {
2017  FreeLibrary( ras_handle );
2018  return INADDR_ANY;
2019  }
2020 
2021  // JAS: My computer gets to this point, but I have no RAS connections,
2022  // so just exit
2023  if ( num_connections < 1 ) {
2024  ml_string("Found no RAS connections");
2025  FreeLibrary( ras_handle );
2026  return INADDR_ANY;
2027  }
2028 
2029  ml_printf("Found %d connections", num_connections);
2030 
2031  for (i = 0; i < num_connections; i++ ) {
2032  RASCONNSTATUS status;
2033  unsigned long dummySize;
2034 
2035  // don't count VPNs with the non-LAN connections
2036  if ( !stricmp(rasbuffer[i].szDeviceType, "RASDT_Vpn") ) {
2037  continue;
2038  } else {
2039  valid_connections++;
2040  }
2041 
2042  ml_printf("Connection %d:", i);
2043  ml_printf("Entry Name: %s", rasbuffer[i].szEntryName);
2044  ml_printf("Device Type: %s", rasbuffer[i].szDeviceType);
2045  ml_printf("Device Name: %s", rasbuffer[i].szDeviceName);
2046 
2047  // get the connection status
2048  status.dwSize = sizeof(RASCONNSTATUS);
2049  rval = pRasGetConnectStatus(rasbuffer[i].hrasconn, &status);
2050  if ( rval != 0 ) {
2051  FreeLibrary( ras_handle );
2052  return INADDR_ANY;
2053  }
2054 
2055  // get the projection informatiom
2056  size = sizeof(projection);
2057  projection.dwSize = size;
2058  rval = pRasGetProjectionInfo(rasbuffer[i].hrasconn, RASP_PppIp, &projection, &dummySize );
2059  if ( rval != 0 ) {
2060  FreeLibrary( ras_handle );
2061  return INADDR_ANY;
2062  }
2063 
2064  ml_printf("IP Address: %s", projection.szIpAddress);
2065  }
2066 
2067  if (!valid_connections) {
2068  FreeLibrary( ras_handle );
2069  return INADDR_ANY;
2070  }
2071 
2072  Ras_connected = 1;
2073 
2074  FreeLibrary( ras_handle );
2075  rasip = inet_addr(projection.szIpAddress);
2076  if(rasip==INADDR_NONE){
2077  return INADDR_ANY;
2078  }
2079 
2080  //The ip of the RAS connection
2081  return rasip;
2082 }
2083 #endif // Dial-Up Networking
2084 
2089 {
2090  int broadcast;
2091  int cursize, bufsize;
2092  socklen_t cursizesize;
2093 
2094  // Set the mode of the socket to allow broadcasting.
2095  // Broadcasting was needed when searching for a game in IPX mode.
2096  // Unclear if still needed.
2097  broadcast = 1;
2098  if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (LPSTR)&broadcast, sizeof(broadcast) )){
2099  Can_broadcast = 0;
2100  } else {
2101  Can_broadcast = 1;
2102  }
2103 
2104  // try and increase the size of my receive buffer
2105  bufsize = MAX_RECEIVE_BUFSIZE;
2106 
2107  // set the current size of the receive buffer
2108  cursizesize = sizeof(int);
2109  getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (LPSTR)&cursize, &cursizesize);
2110  setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (LPSTR)&bufsize, sizeof(bufsize));
2111  getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (LPSTR)&cursize, &cursizesize);
2112  ml_printf("Receive buffer set to %d", cursize);
2113 
2114  // set the current size of the send buffer
2115  cursizesize = sizeof(int);
2116  getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (LPSTR)&cursize, &cursizesize);
2117  setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (LPSTR)&bufsize, sizeof(bufsize));
2118  getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (LPSTR)&cursize, &cursizesize);
2119  ml_printf("Send buffer set to %d", cursize);
2120 }
2121 
2126 {
2127  SOCKADDR_IN sockaddr;
2128 
2130 
2131  TCP_socket = socket( AF_INET, SOCK_DGRAM, 0 );
2132  if ( TCP_socket == (int)INVALID_SOCKET ) {
2134  ml_printf("Error on TCP startup %d", Tcp_failure_code);
2135  return 0;
2136  }
2137 
2138  // bind the socket
2139  memset(&sockaddr,0,sizeof(SOCKADDR_IN));
2140  sockaddr.sin_family = AF_INET;
2141  sockaddr.sin_addr.s_addr = psnet_get_ip();
2142  sockaddr.sin_port = htons( Psnet_default_port );
2143  if ( bind(TCP_socket, (SOCKADDR*)&sockaddr, sizeof (sockaddr)) == SOCKET_ERROR) {
2145 
2147  ml_printf("TCP socket already in use! Another instance running? (Try using the \"-port %i\" cmdline option)", Psnet_default_port + 1);
2148  } else {
2149  ml_printf("Couldn't bind TCP socket (%d)! Invalidating TCP", Tcp_failure_code );
2150  }
2151 
2152  return 0;
2153  }
2154 
2155  // set socket options
2158 
2159  // success
2160  return 1;
2161 }
2162 
2167 {
2168  return (float)timer_get_milliseconds() / 1000.0f;
2169 }
2170 
2175 {
2176  // valid socket?
2177  if((socket == 0xffffffff) || (socket >= MAXRELIABLESOCKETS)){
2178  return;
2179  }
2180 
2181  // mark it
2182  Reliable_sockets[socket].last_packet_received = psnet_get_time();
2183 }
ubyte ping_pos
Definition: psnet2.cpp:197
reliable_net_rcvbuffer * rbuffers[MAXNETBUFFERS]
Definition: psnet2.cpp:185
#define NET_TCP
Definition: psnet2.h:29
#define RNT_DISCONNECT
Definition: psnet2.cpp:154
#define MIN_NET_RETRYTIME
Definition: psnet2.cpp:139
int i
Definition: multi_pxo.cpp:466
#define vm_free(ptr)
Definition: pstypes.h:548
#define WSAEWOULDBLOCK
Definition: config.h:131
unsigned short theirsequence
Definition: psnet2.cpp:193
struct network_packet_buffer network_packet_buffer
void psnet_buffer_init(network_packet_buffer_list *l)
Definition: psnet2.cpp:1804
int SENDTO(SOCKET s, char *buf, int len, int flags, sockaddr *to, int tolen, int psnet_type)
Definition: psnet2.cpp:345
#define MAX_RECEIVE_BUFSIZE
Definition: psnet2.cpp:130
uint PSNET_SOCKET_RELIABLE
Definition: multi_xfer.h:20
#define PSNET_NUM_TYPES
Definition: psnet2.h:70
void psnet_mark_received(PSNET_SOCKET_RELIABLE socket)
Definition: psnet2.cpp:2174
#define WSAGetLastError()
Definition: psnet2.cpp:30
Assert(pm!=NULL)
#define NETWORK_ERROR_CONNECT_TO_ISP
Definition: psnet2.h:66
void * HINSTANCE
Definition: config.h:105
#define SOCKADDR_IN
Definition: config.h:124
ushort status
Definition: psnet2.cpp:191
int sequence_number
Definition: psnet2.cpp:99
#define SOCKADDR
Definition: config.h:123
void psnet_rel_close()
Definition: psnet2.cpp:1783
void psnet_rel_work()
Definition: psnet2.cpp:1187
unsigned long * LPDWORD
Definition: config.h:90
#define RNF_BROKEN
Definition: psnet2.h:100
ubyte data[MAX_TOP_LAYER_PACKET_SIZE]
Definition: psnet2.cpp:112
#define RNT_HEARTBEAT
Definition: psnet2.cpp:155
#define RNF_UNUSED
Definition: psnet2.h:98
#define NETWORK_ERROR_NO_PROTOCOL
Definition: psnet2.h:64
void ml_string(const char *string, int add_time)
Definition: multi_log.cpp:131
GLclampf f
Definition: Glext.h:7097
#define INTEL_SHORT(x)
Definition: pstypes.h:389
int Socket_type
Definition: psnet2.cpp:56
#define SOCKET_ERROR
Definition: config.h:138
void psnet_buffer_packet(network_packet_buffer_list *l, ubyte *data, int length, net_addr *from)
Definition: psnet2.cpp:1825
int psnet_rel_send(PSNET_SOCKET_RELIABLE socketid, ubyte *data, int length, int np_index)
Definition: psnet2.cpp:1075
int Tcp_active
Definition: psnet2.cpp:60
#define Assertion(expr, msg,...)
Definition: clang.h:41
#define INVALID_SOCKET
Definition: psnet2.h:53
void psnet_flush()
Definition: psnet2.cpp:927
unsigned short rsequence[MAXNETBUFFERS]
Definition: psnet2.cpp:187
int psnet_get(void *data, net_addr *from_addr)
Definition: psnet2.cpp:881
uint PSNET_SOCKET
Definition: psnet2.h:46
const char * os_config_read_string(const char *section, const char *name, const char *default_value)
Definition: osregistry.cpp:322
#define NETBUFFERSIZE
Definition: psnet2.cpp:143
ubyte addr[6]
Definition: psnet2.h:41
GLsizeiptr size
Definition: Glext.h:5496
#define MAX_PING_HISTORY
Definition: psnet2.cpp:169
#define RNT_ACK
Definition: psnet2.cpp:150
#define Int3()
Definition: pstypes.h:292
#define MAXRELIABLESOCKETS
Definition: psnet2.cpp:142
int psnet_get_ip()
Definition: psnet2.cpp:1751
ubyte connection_type
Definition: psnet2.cpp:195
ushort Psnet_default_port
Definition: psnet2.cpp:67
network_packet_buffer psnet_buffers[MAX_PACKET_BUFFERS]
Definition: psnet2.cpp:119
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
int RECVFROM(SOCKET s, char *buf, int len, int flags, sockaddr *from, int *fromlen, int psnet_type)
Definition: psnet2.cpp:271
int psnet_same(net_addr *a1, net_addr *a2)
Definition: psnet2.cpp:785
net_addr m_net_addr
Definition: psnet2.cpp:194
float First_sent_iamhere
Definition: psnet2.cpp:210
#define RNF_LIMBO
Definition: psnet2.h:103
int recv_len[MAXNETBUFFERS]
Definition: psnet2.cpp:186
#define PSNET_TYPE_RELIABLE
Definition: psnet2.h:72
unsigned int Serverconn
Definition: psnet2.cpp:215
#define NETWORK_STATUS_NO_PROTOCOL
Definition: psnet2.cpp:77
float mean_ping
Definition: psnet2.cpp:199
SOCKET Unreliable_socket
Definition: psnet2.cpp:208
#define NETTIMEOUT
Definition: psnet2.cpp:140
char * LPSTR
Definition: config.h:107
#define NETWORK_STATUS_RUNNING
Definition: psnet2.cpp:79
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
#define RNT_DATA_COMP
Definition: psnet2.cpp:152
SOCKET TCP_socket
Definition: psnet2.cpp:205
ushort data_len
Definition: psnet2.cpp:163
int psnet_buffer_get_next(network_packet_buffer_list *l, ubyte *data, int *length, net_addr *from)
Definition: psnet2.cpp:1861
unsigned short ssequence[MAXNETBUFFERS]
Definition: psnet2.cpp:182
#define MAX_PACKET_BUFFERS
Definition: psnet2.cpp:90
#define NETWORK_CONNECTION_NONE
Definition: psnet2.cpp:70
int Psnet_my_addr_valid
Definition: psnet2.cpp:51
reliable_socket Reliable_sockets[MAXRELIABLESOCKETS]
Definition: psnet2.cpp:202
ubyte Null_address[6]
Definition: psnet2.cpp:54
void ml_printf(const char *format,...)
Definition: multi_log.cpp:112
#define NETRETRYTIME
Definition: psnet2.cpp:138
int psnet_is_valid_ip_string(char *ip_string, int allow_port)
Definition: psnet2.cpp:938
#define MAX_TOP_LAYER_PACKET_SIZE
Definition: psnet2.cpp:86
int Psnet_connection
Definition: psnet2.cpp:65
int Tcp_can_broadcast
Definition: psnet2.cpp:58
#define NETWORK_ERROR_LAN_AND_RAS
Definition: psnet2.h:67
#define NETHEARTBEATTIME
Definition: psnet2.cpp:141
GLboolean GLboolean GLboolean GLboolean a
Definition: Glext.h:5781
#define NETWORK_STATUS_NO_WINSOCK
Definition: psnet2.cpp:76
#define NETWORK_ERROR_NONE
Definition: psnet2.h:61
#define DEFAULT_GAME_PORT
Definition: psnet2.h:36
#define PSNET_TYPE_UNRELIABLE
Definition: psnet2.h:71
float Last_sent_iamhere
Definition: psnet2.cpp:211
ubyte data[MAX_TOP_LAYER_PACKET_SIZE]
Definition: psnet2.cpp:101
#define WSAEADDRINUSE
Definition: config.h:137
int Can_broadcast
Definition: psnet2.cpp:57
int psnet_send(net_addr *who_to, void *data, int len, int np_index)
Definition: psnet2.cpp:793
#define NETWORK_ERROR_NO_WINSOCK
Definition: psnet2.h:63
#define fl_abs(fl)
Definition: floating.h:31
GLuint buffer
Definition: Glext.h:5492
int psnet_get_network_status()
Definition: psnet2.cpp:670
unsigned short oursequence
Definition: psnet2.cpp:192
GLdouble s
Definition: Glext.h:5321
#define SOCKET
Definition: config.h:122
unsigned long DWORD
Definition: config.h:90
int Ras_connected
Definition: psnet2.cpp:64
int psnet_use_protocol(int protocol)
Definition: psnet2.cpp:596
int idx
Definition: multiui.cpp:761
#define RELIABLE_PACKET_HEADER_ONLY_SIZE
Definition: psnet2.cpp:168
timeval TIMEVAL
Definition: config.h:216
unsigned char ubyte
Definition: pstypes.h:62
int multi_rate_add(int np_index, char *type, int size)
const char * XSTR(const char *str, int index)
Definition: localize.cpp:851
GLbitfield GLuint64 timeout
Definition: Glext.h:6725
#define NETWORK_STATUS_NOT_INITIALIZED
Definition: psnet2.cpp:75
#define RNT_I_AM_HERE
Definition: psnet2.cpp:156
#define NOX(s)
Definition: pstypes.h:473
#define RNT_DATA
Definition: psnet2.cpp:151
float pings[MAX_PING_HISTORY]
Definition: psnet2.cpp:196
ubyte buffer[NETBUFFERSIZE]
Definition: psnet2.cpp:177
int send_len[MAXNETBUFFERS]
Definition: psnet2.cpp:184
GLbitfield flags
Definition: Glext.h:6722
#define vm_malloc(size)
Definition: pstypes.h:547
void psnet_init(int protocol, int port_num)
Definition: psnet2.cpp:458
#define INTEL_INT(x)
Definition: pstypes.h:388
#define INTEL_FLOAT(x)
Definition: pstypes.h:391
void PSNET_TOP_LAYER_PROCESS()
Definition: psnet2.cpp:360
int psnet_broadcast(net_addr *who_to, void *data, int len)
Definition: psnet2.cpp:897
ubyte buffer[NETBUFFERSIZE]
Definition: psnet2.cpp:172
#define MAXNETBUFFERS
Definition: psnet2.cpp:136
void psnet_socket_options(SOCKET sock)
Definition: psnet2.cpp:2088
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
#define closesocket(x)
Definition: config.h:128
float timesent[MAXNETBUFFERS]
Definition: psnet2.cpp:183
void psnet_close()
Definition: psnet2.cpp:563
float last_packet_sent
Definition: psnet2.cpp:189
#define RNF_CONNECTING
Definition: psnet2.h:102
GLenum GLuint GLsizei bufsize
Definition: Glext.h:7030
#define RNF_CONNECTED
Definition: psnet2.h:99
void psnet_rel_send_ack(SOCKADDR *raddr, unsigned int sig, ubyte link_type, float time_sent)
Definition: psnet2.cpp:975
uint type
Definition: psnet2.h:39
int psnet_rel_get(PSNET_SOCKET socketid, ubyte *buffer, int max_len)
Definition: psnet2.cpp:1152
unsigned short ushort
Definition: pstypes.h:63
void psnet_rel_connect_to_server(PSNET_SOCKET *socket, net_addr *server_addr)
Definition: psnet2.cpp:1593
int psnet_init_tcp()
Definition: psnet2.cpp:2125
int psnet_rel_get_status(PSNET_SOCKET_RELIABLE socketid)
Definition: psnet2.cpp:1542
ubyte compressed
Definition: psnet2.cpp:161
GLenum GLsizei GLenum GLenum const GLvoid * data
Definition: Gl.h:1509
#define RELIABLE_CONNECT_TIME
Definition: psnet2.cpp:145
int psnet_is_valid_numeric_ip(char *ip)
Definition: psnet2.cpp:1904
int psnet_rel_check_for_listen(net_addr *from_addr)
Definition: psnet2.cpp:1555
float psnet_get_time()
Definition: psnet2.cpp:2166
#define NETWORK_ERROR_NO_TYPE
Definition: psnet2.h:62
float last_packet_received
Definition: psnet2.cpp:188
GLenum GLuint GLenum GLsizei length
Definition: Glext.h:5156
typedef LPVOID
Definition: vddraw.h:119
int SELECT(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout, int psnet_type)
Definition: psnet2.cpp:317
GLenum GLsizei len
Definition: Glext.h:6283
float send_time
Definition: psnet2.cpp:164
#define __stdcall
Definition: config.h:73
net_addr Psnet_my_addr
Definition: psnet2.cpp:52
int Nettimeout
Definition: psnet2.cpp:147
network_packet_buffer_list Psnet_top_buffers[PSNET_NUM_TYPES]
Definition: psnet2.cpp:221
void psnet_string_to_addr(net_addr *address, char *text)
Definition: psnet2.cpp:732
int Tcp_failure_code
Definition: psnet2.cpp:63
int Cmdline_timeout
Definition: cmdline.cpp:281
ushort flags
Definition: psnet2.cpp:100
char * psnet_addr_to_string(char *text, net_addr *address)
Definition: psnet2.cpp:705
struct network_packet network_naked_packet
void psnet_rel_close_socket(PSNET_SOCKET_RELIABLE *sockp)
Definition: psnet2.cpp:1008
#define NETWORK_CONNECTION_LAN
Definition: psnet2.cpp:72
GLenum const GLvoid * addr
Definition: Glext.h:9092
#define RNT_REQ_CONN
Definition: psnet2.cpp:153
int Network_status
Definition: psnet2.cpp:62
unsigned int num_ping_samples
Definition: psnet2.cpp:198
short port
Definition: psnet2.h:42
struct network_packet_buffer_list network_packet_buffer_list
int timer_get_milliseconds()
Definition: timer.cpp:150
int socklen_t
Definition: tcp_socket.cpp:39
reliable_net_sendbuffer * sbuffers[MAXNETBUFFERS]
Definition: psnet2.cpp:181
#define stricmp(s1, s2)
Definition: config.h:271
#define UDP_HEADER_SIZE
Definition: psnet2.h:56
int psnet_init_rel_tcp(int port, int should_listen)
Definition: psnet2.cpp:1777
GLuint address
Definition: Glext.h:8864
const GLubyte * c
Definition: Glext.h:8376
ubyte data[NETBUFFERSIZE]
Definition: psnet2.cpp:165
SOCKADDR addr
Definition: psnet2.cpp:190
#define CONNECTSEQ
Definition: psnet2.cpp:213
#define strcpy_s(...)
Definition: safe_strings.h:67
int psnet_rel_check()
Definition: psnet2.cpp:1067
#define NETWORK_CONNECTION_DIALUP
Definition: psnet2.cpp:71