]> icculus.org git repositories - taylor/freespace2.git/blob - src/network/psnet2.cpp
clean up Windows #include's and use winsock2
[taylor/freespace2.git] / src / network / psnet2.cpp
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
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Network/Psnet2.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * C file containing application level network-interface.
16  *
17  * $Log$
18  * Revision 1.14  2005/10/02 09:30:10  taylor
19  * sync up rest of big-endian network changes.  it should at least be as good as what's in FS2_Open now, only better :)
20  *
21  * Revision 1.13  2005/10/01 22:01:28  taylor
22  * some cleanup of earlier big-endian changes
23  *
24  * Revision 1.12  2004/07/04 11:39:06  taylor
25  * fix missing debrief text, crash on exit, path separator's, warning fixes, no GR_SOFT
26  *
27  * Revision 1.11  2004/06/11 01:52:15  tigital
28  * byte-swapping changes for bigendian systems
29  *
30  * Revision 1.10  2003/08/03 16:10:30  taylor
31  * cleanup; compile warning fixes
32  *
33  * Revision 1.9  2002/07/27 19:52:54  relnev
34  * add missing structure packing
35  *
36  * Revision 1.8  2002/06/09 04:41:24  relnev
37  * added copyright header
38  *
39  * Revision 1.7  2002/06/02 05:31:17  relnev
40  * unstub
41  *
42  * Revision 1.6  2002/06/02 02:29:39  relnev
43  * net fixes
44  *
45  * Revision 1.5  2002/05/27 04:04:43  relnev
46  * 155 undefined references left
47  *
48  * Revision 1.4  2002/05/26 21:27:53  theoddone33
49  * More progress (I hate psnet2)
50  *
51  * Revision 1.3  2002/05/26 20:49:54  theoddone33
52  * More progress
53  *
54  * Revision 1.2  2002/05/07 03:16:48  theoddone33
55  * The Great Newline Fix
56  *
57  * Revision 1.1.1.1  2002/05/03 03:28:10  root
58  * Initial import.
59  *
60  * 
61  * 25    9/14/99 2:21p Dave
62  * Fixed observer mode joining and ingame stuff.
63  * 
64  * 24    9/10/99 9:44p Dave
65  * Bumped version # up. Make server reliable connects not have such a huge
66  * timeout. 
67  * 
68  * 23    9/07/99 4:01p Dave
69  * Fixed up a string.tbl paroblem (self destruct message). Make sure IPX
70  * does everything properly (setting up address when binding). Remove
71  * black rectangle background from UI_INPUTBOX.
72  * 
73  * 22    8/26/99 8:51p Dave
74  * Gave multiplayer TvT messaging a heavy dose of sanity. Cheat codes.
75  * 
76  * 21    8/16/99 4:06p Dave
77  * Big honking checkin.
78  * 
79  * 20    7/26/99 5:50p Dave
80  * Revised ingame join. Better? We'll see....
81  * 
82  * 19    7/20/99 1:49p Dave
83  * Peter Drake build. Fixed some release build warnings.
84  * 
85  * 18    7/15/99 9:20a Andsager
86  * FS2_DEMO initial checkin
87  * 
88  * 17    7/03/99 4:08p Dave
89  * Fixed wss_slots size issues. Fixed potentially nasty bug in low level
90  * reliable code.
91  * 
92  * 16    6/25/99 5:02p Jasenw
93  * Removed old debug code.
94  * 
95  * 15    6/07/99 9:51p Dave
96  * Consolidated all multiplayer ports into one.
97  * 
98  * 14    4/30/99 12:18p Dave
99  * Several minor bug fixes.
100  * 
101  * 13    4/27/99 5:55p Dave
102  * Fixed Ras_connected bug with VSDK code.
103  * 
104  * 12    4/27/99 2:59p Dave
105  * Potential fix for reliable socket connection problem.
106  * 
107  * 11    4/23/99 11:07a Dave
108  * Added lots of debug multi.log output to psnet2
109  * 
110  * 10    4/12/99 10:07p Dave
111  * Made network startup more forgiving. Added checkmarks to dogfight
112  * screen for players who hit commit.
113  * 
114  * 9     3/10/99 6:50p Dave
115  * Changed the way we buffer packets for all clients. Optimized turret
116  * fired packets. Did some weapon firing optimizations.
117  * 
118  * 8     3/09/99 6:24p Dave
119  * More work on object update revamping. Identified several sources of
120  * unnecessary bandwidth.
121  * 
122  * 7     3/08/99 7:03p Dave
123  * First run of new object update system. Looks very promising.
124  * 
125  * 6     1/24/99 11:37p Dave
126  * First full rev of beam weapons. Very customizable. Removed some bogus
127  * Int3()'s in low level net code.
128  * 
129  * 5     1/06/99 2:24p Dave
130  * Stubs and release build fixes.
131  * 
132  * 4     11/20/98 11:16a Dave
133  * Fixed up IPX support a bit. Making sure that switching modes and
134  * loading/saving pilot files maintains proper state.
135  * 
136  * 3     11/19/98 4:19p Dave
137  * Put IPX sockets back in psnet. Consolidated all multiplayer config
138  * files into one.
139  * 
140  * 2     11/19/98 8:04a Dave
141  * Full support for D3-style reliable sockets. Revamped packet lag/loss
142  * system, made it receiver side and at the lowest possible level.
143  *
144  * $NoKeywords: $
145  */
146
147 #ifndef PLAT_UNIX
148 #include <winsock2.h>
149 #include <ras.h>
150 #include <raserror.h>
151 #else
152 #include <sys/types.h>
153 #include <sys/socket.h>
154 #include <netinet/in.h>
155 #include <arpa/inet.h>
156 #include <netdb.h>
157 #include <errno.h>
158 #endif
159 #include <stdio.h>
160 #include <limits.h>
161
162 #include "pstypes.h"
163 #include "psnet.h"
164 #include "multi.h"
165 #include "multiutil.h"
166 #include "multilag.h"
167 #include "osregistry.h"
168 #include "timer.h"
169 #include "multi_log.h"
170 #include "multi_rate.h"
171 #include "cmdline.h"
172
173 #ifdef PSNET2
174
175 // -------------------------------------------------------------------------------------------------------
176 // PSNET 2 DEFINES/VARS
177 //
178
179 int             Psnet_my_addr_valid;
180 net_addr_t Psnet_my_addr;
181
182 const ubyte Null_address[4] = { 0x00, 0x00, 0x00, 0x00 };
183
184 int Socket_type;
185 int Can_broadcast;                      // can we do broadcasting on our socket?
186 int Tcp_can_broadcast = 0;
187
188 int Tcp_active = 0;
189
190 int Network_status;
191 int Tcp_failure_code = 0;
192 int Ras_connected;
193 int Psnet_connection;
194
195 ushort  Psnet_default_port;
196
197 // specified their internet connnection type
198 #define NETWORK_CONNECTION_NONE                 1
199 #define NETWORK_CONNECTION_DIALUP               2
200 #define NETWORK_CONNECTION_LAN                  3
201
202 // defines and variables to indicate network connection status
203 #define NETWORK_STATUS_NOT_INITIALIZED  1
204 #define NETWORK_STATUS_NO_WINSOCK               2                       // winsock failed to initialize
205 #define NETWORK_STATUS_NO_PROTOCOL              3                       // TCP/IP doesn't appear to be loaded
206 #define NETWORK_STATUS_NO_RELIABLE              4
207 #define NETWORK_STATUS_RUNNING                  5                       // everything should be running
208
209 // defintion of structures that actually leave this machine.  psnet_send give us only
210 // the data that we want to send.  We will add a header onto this data (packet sequence
211 // number, possibly a checksum).  We must include a 2 byte flags variable into both structure
212 // since the receiving end of this packet must know whether or not to checksum the packet.
213
214 #define MAX_TOP_LAYER_PACKET_SIZE                       680
215
216 // use the pack pragma to pack these structures to 2 byte aligment.  Really only needed for
217 // the naked packet.
218 #define MAX_PACKET_BUFFERS              75
219
220 #ifndef PLAT_UNIX
221 #pragma pack(push, 2)
222 #endif
223
224 // definition for a non-checksum packet
225 typedef struct network_packet
226 {
227         int             sequence_number;
228         ushort  flags;
229         ubyte           data[MAX_TOP_LAYER_PACKET_SIZE];
230 } network_naked_packet;
231
232 // structure definition for our packet buffers
233 typedef struct network_packet_buffer
234 {
235         int             sequence_number;
236         int             len;    
237         net_addr_t      from_addr;
238         ubyte           data[MAX_TOP_LAYER_PACKET_SIZE];
239 } network_packet_buffer;
240
241 // struct for a bunch of network packet buffers
242 typedef struct network_packet_buffer_list {
243         network_packet_buffer psnet_buffers[MAX_PACKET_BUFFERS];
244         int psnet_seq_number;
245         int psnet_lowest_id;
246         int psnet_highest_id;
247 } network_packet_buffer_list;
248
249 #ifndef PLAT_UNIX
250 #pragma pack(pop)
251 #endif
252
253
254 #define MAXHOSTNAME                     128
255
256 #define MAX_RECEIVE_BUFSIZE     4096    // 32 K, eh?
257 #define MAX_SEND_RETRIES                20                      // number of retries when sending would block
258 #define MAX_LINGER_TIME                 0                       // in seconds -- when lingering to close a socket
259
260 //Reliable UDP stuff
261 //*******************************
262 #define MAXNETBUFFERS                   150             // Maximum network buffers (For between network and upper level functions, which is 
263                                                                                                         // required in case of out of order packets
264 #define NETRETRYTIME                            0.75f           // Time after sending before we resend
265 #define MIN_NET_RETRYTIME               0.2f
266 #define NETTIMEOUT                              30                      // Time after receiving the last packet before we drop that user
267 #define NETHEARTBEATTIME                3                       // How often to send a heartbeat
268 #define MAXRELIABLESOCKETS              40                      // Max reliable sockets to open at once...
269 #define NETBUFFERSIZE                   600             // Max size of a network packet
270
271 #define RELIABLE_CONNECT_TIME           7               // how long we'll wait for a response when doing a reliable connect
272
273 int Nettimeout = NETTIMEOUT;
274
275 // Reliable packet stuff
276 #define RNT_ACK                         1                               // ACK Packet
277 #define RNT_DATA                                2                               // Data Packet
278 #define RNT_DATA_COMP           3                               // Compressed Data Packet
279 #define RNT_REQ_CONN                    4                               // Requesting a connection
280 #define RNT_DISCONNECT          5                               // Disconnecting a connection
281 #define RNT_HEARTBEAT           6                               // Heartbeat -- send every NETHEARTBEATTIME
282 #define RNT_I_AM_HERE           7
283
284 #ifndef PLAT_UNIX
285 #pragma pack(push,r_udp)
286 #pragma pack(1)
287 #define PACKED
288 #else
289 #define PACKED __attribute__((packed))
290 #endif
291
292 typedef struct {
293         ubyte                   type;                                   // packet type
294         ubyte                   compressed;                     //
295         ushort          seq;                                    // sequence packet 0-65535 used for ACKing also
296         ushort          data_len;                       // length of data
297         float                   send_time;                      // Time the packet was sent, if an ACK the time the packet being ACK'd was sent.
298         ubyte           data[NETBUFFERSIZE];    // Packet data
299 } PACKED reliable_header;
300
301 #define RELIABLE_PACKET_HEADER_ONLY_SIZE (sizeof(reliable_header)-NETBUFFERSIZE)
302 #define MAX_PING_HISTORY        10
303
304 typedef struct {
305         ubyte buffer[NETBUFFERSIZE];
306
307 } PACKED reliable_net_sendbuffer;
308
309 typedef struct {
310         ubyte buffer[NETBUFFERSIZE];
311 } PACKED reliable_net_rcvbuffer;
312
313 typedef struct {
314         reliable_net_sendbuffer *sbuffers[MAXNETBUFFERS];       // This is an array of pointers for quick sorting
315         unsigned short ssequence[MAXNETBUFFERS];                                // This is the sequence number of the given packet
316         float timesent[MAXNETBUFFERS];
317         int send_len[MAXNETBUFFERS];
318         reliable_net_rcvbuffer  *rbuffers[MAXNETBUFFERS];
319         int recv_len[MAXNETBUFFERS];
320         unsigned short rsequence[MAXNETBUFFERS];                                // This is the sequence number of the given packet
321         float last_packet_received;                                                             // For a given connection, this is the last packet we received
322         float last_packet_sent;
323         struct sockaddr addr;                                                                                                   // struct sockaddr of our peer
324         ushort status;                                                                                                  // Status of this connection
325         unsigned short oursequence;                                                             // This is the next sequence number the application is expecting
326         unsigned short theirsequence;                                                           // This is the next sequence number the peer is expecting
327         net_addr_t      net_addr;                                                                                       // A FS2 network address structure
328         ubyte connection_type;                                                                          // IP, modem, etc.
329         float pings[MAX_PING_HISTORY];
330         ubyte ping_pos;
331         unsigned int num_ping_samples;
332         float mean_ping;        
333 } reliable_socket;
334
335 reliable_socket Reliable_sockets[MAXRELIABLESOCKETS];
336
337 // socket TCP (unreliable)
338 SOCKET TCP_socket;
339
340 // the sockets that the game will use when selecting network type
341 SOCKET Unreliable_socket = INVALID_SOCKET;
342
343 // blah
344 // SOCKET Reliable_UDP_socket = INVALID_SOCKET;
345
346 float First_sent_iamhere = 0;
347 float Last_sent_iamhere = 0;
348
349 #define CONNECTSEQ 0x142                                                                                // Magic number for starting a connection, just so it isn't 0
350
351 unsigned int Serverconn = 0xffffffff;
352
353 #ifndef PLAT_UNIX
354 #pragma pack(pop,r_udp)
355 #endif
356 #undef PACKED
357
358 //*******************************
359
360 // top layer buffers
361 network_packet_buffer_list Psnet_top_buffers[PSNET_NUM_TYPES];
362
363 // -------------------------------------------------------------------------------------------------------
364 // PSNET 2 FORWARD DECLARATIONS
365 //
366
367 // if the string is a legally formatted ip string
368 int psnet_is_valid_numeric_ip(char *ip);
369
370 // functions to get the status of a RAS connection
371 unsigned int psnet_ras_status();
372
373 // set some options on a socket
374 void psnet_socket_options( SOCKET sock );
375
376 // initialize tcp socket
377 int psnet_init_tcp();
378
379 // get time in seconds
380 float psnet_get_time();
381
382 // returns the ip address of this machine. use for calling bind() with to associate with the proper
383 // IP address and network device.
384 int psnet_get_ip();
385
386 // initialize reliable sockets
387 int psnet_init_rel_tcp(int port, int should_listen);
388
389 // shutdown reliable sockets
390 void psnet_rel_close();
391
392 // initialize the buffering system
393 void psnet_buffer_init(network_packet_buffer_list *l);
394
395 // buffer a packet (maintain order!)
396 void psnet_buffer_packet(network_packet_buffer_list *l, ubyte *data, int length, net_addr_t *from);
397
398 // get the index of the next packet in order!
399 int psnet_buffer_get_next(network_packet_buffer_list *l, ubyte *data, int *length, net_addr_t *from);
400
401
402 // -------------------------------------------------------------------------------------------------------
403 // PSNET 2 TOP LAYER FUNCTIONS - these functions simply buffer and store packets based upon type (see PSNET_TYPE_* defines)
404 //
405
406 // wrappers around select() and recvfrom() for lagging/losing data
407 int RECVFROM(SOCKET s, char *buf, int len, int flags, sockaddr *from, int *fromlen, int psnet_type)
408 {
409         network_packet_buffer_list *l;
410         net_addr_t addr;
411         int ret;
412         int ret_len;
413
414         // bad type
415         SDL_assert((psnet_type >= 0) && (psnet_type < PSNET_NUM_TYPES));
416         if((psnet_type < 0) || (psnet_type >= PSNET_NUM_TYPES)){
417                 return -1;
418         }       
419         l = &Psnet_top_buffers[psnet_type];
420
421         // if we have no buffer! The user should have made sure this wasn't the case by calling SELECT()
422         ret = psnet_buffer_get_next(l, (ubyte*)buf, &ret_len, &addr);
423         if(!ret){
424                 Int3();
425                 return -1;
426         }
427
428         // otherwise, stuff the outgoing data
429         ((struct sockaddr_in*)from)->sin_port = htons(addr.port);
430         memcpy(&((struct sockaddr_in*)from)->sin_addr.s_addr, addr.addr, 4);
431         ((struct sockaddr_in*)from)->sin_family = AF_INET;
432         *fromlen = sizeof(struct sockaddr_in);
433
434         // return bytes read
435         return ret_len;
436 }
437
438 // wrappers around select() and recvfrom() for lagging/losing data
439 int SELECT(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout, int psnet_type)
440 {
441         network_packet_buffer_list *l;
442
443         // if this is a check for writability, just return the select 
444         if(writefds != NULL){
445                 return select(nfds, readfds, writefds, exceptfds, timeout);
446         }       
447         
448         // bad type
449         SDL_assert((psnet_type >= 0) && (psnet_type < PSNET_NUM_TYPES));
450         if((psnet_type < 0) || (psnet_type >= PSNET_NUM_TYPES)){
451                 return -1;
452         }       
453         l = &Psnet_top_buffers[psnet_type];     
454
455         // do we have any buffers in here?      
456         if((l->psnet_lowest_id == -1) || (l->psnet_lowest_id > l->psnet_highest_id)){
457                 return 0;
458         }
459
460         // yo
461         return 1;
462 }
463
464 // wrappers around sendto to sorting through different packet types
465 int SENDTO(SOCKET s, char * buf, int len, int flags, sockaddr *to, int tolen, int psnet_type)
466 {       
467         char outbuf[MAX_TOP_LAYER_PACKET_SIZE + 150];           
468
469         // stuff type
470         outbuf[0] = (char)psnet_type;
471         memcpy(&outbuf[1], buf, len);
472
473         // is the socket writeable?
474         
475         // send it
476         return sendto(s, outbuf, len + 1, flags, (struct sockaddr*)to, tolen);
477 }
478
479 // call this once per frame to read everything off of our socket
480 void PSNET_TOP_LAYER_PROCESS()
481 {
482         // read socket stuff
483         struct sockaddr_in ip_addr;                             // UDP/TCP socket structure
484         fd_set  rfds;
485         timeval timeout;
486         int read_len;
487 #ifndef PLAT_UNIX       
488         int from_len;
489 #else
490         socklen_t from_len;
491 #endif
492         net_addr_t      from_addr;      
493         network_naked_packet packet_read;               
494
495         // clear the addresses to remove compiler warnings
496         memset(&ip_addr, 0, sizeof(struct sockaddr_in));
497
498         if ( Network_status != NETWORK_STATUS_RUNNING ) {
499                 ml_printf("Network ==> socket not inited in PSNET_TOP_LAYER_PROCESS\n");
500                 return;
501         }
502
503         while ( 1 ) {           
504                 // check if there is any data on the socket to be read.  The amount of data that can be 
505                 // atomically read is stored in len.
506
507                 FD_ZERO(&rfds);
508                 FD_SET( Unreliable_socket, &rfds );
509                 timeout.tv_sec = 0;
510                 timeout.tv_usec = 0;
511
512                 if ( select( Unreliable_socket+1, &rfds, NULL, NULL, &timeout) == SOCKET_ERROR ) {              
513                         ml_printf("Error %d doing a socket select on read\n", WSAGetLastError());
514                         break;
515                 }
516
517                 // if the read file descriptor is not set, then bail!
518                 if ( !FD_ISSET(Unreliable_socket, &rfds) ){
519                         return;
520                 }
521
522                 // get data off the socket and process
523                 from_len = sizeof(struct sockaddr_in);
524                 read_len = recvfrom( Unreliable_socket, (char*)packet_read.data, MAX_TOP_LAYER_PACKET_SIZE, 0,  (struct sockaddr*)&ip_addr, &from_len);
525
526                 // set the from_addr for storage into the packet buffer structure
527                 from_addr.type = Socket_type;
528                 from_addr.port = ntohs( ip_addr.sin_port );
529                 memcpy(from_addr.addr, &ip_addr.sin_addr.s_addr, 4);
530
531                 if ( read_len == SOCKET_ERROR ) {
532                         // int x = WSAGetLastError();
533                         ml_printf("Socket error on socket_get_data()");
534                         break;
535                 }               
536
537                 // determine the packet type
538                 int packet_type = packet_read.data[0];          
539                 // mprintf(("TOP LAYER PACKET  %d!\n", packet_type));
540                 if((packet_type < 0) || (packet_type >= PSNET_NUM_TYPES)){
541                         Int3();
542                 } else {                
543                         // buffer the packet
544                         psnet_buffer_packet(&Psnet_top_buffers[packet_type], packet_read.data + 1, read_len - 1, &from_addr);
545                 }
546         }
547 }
548
549
550 // -------------------------------------------------------------------------------------------------------
551 // PSNET 2 FUNCTIONS
552 //
553
554 // initialize psnet to use the specified port
555 void psnet_init( int protocol, int port_num )
556 {       
557         const char *internet_connection;
558 #ifndef PLAT_UNIX
559         WSADATA wsa_data;               
560 #endif
561         int idx;
562         Tcp_active = 0;
563
564 #if defined(DEMO) || defined(OEM_BUILD) // not for FS2_DEMO
565         return;
566 #endif
567
568         // GAME PORT INITIALIZATION STUFF
569         if ( Network_status == NETWORK_STATUS_RUNNING ){
570                 ml_string("Skipping psnet_init() because network already running");
571                 return;
572         }
573
574         // 'lan' should be a safe default in 2015
575         internet_connection = os_config_read_string("Network", "NetworkConnection", "LAN");
576
577         if ( !SDL_strcasecmp(internet_connection, NOX("dialup")) ) {
578                 ml_string("psnet_init() detected dialup connection");
579
580                 Psnet_connection = NETWORK_CONNECTION_DIALUP;
581         } else if ( !SDL_strcasecmp(internet_connection, NOX("lan")) ) {
582                 ml_string("psnet_init() detected lan connection");
583
584                 Psnet_connection = NETWORK_CONNECTION_LAN;
585         } else {
586                 ml_string("psnet_init() detected no connection");
587
588                 Psnet_connection = NETWORK_CONNECTION_NONE;
589         }
590
591         Network_status = NETWORK_STATUS_NO_WINSOCK;
592 #ifndef PLAT_UNIX
593         if (WSAStartup(0x101, &wsa_data )){
594                 return;
595         }
596 #endif
597
598         // get the port for running this game on.  Be careful that it cannot be out of bounds
599         Psnet_default_port = DEFAULT_GAME_PORT;
600         if ( (port_num > 1023) && (port_num < USHRT_MAX) ) {
601                 Psnet_default_port = (ushort)port_num;
602         }
603
604         // initialize TCP now   
605         Tcp_active = 1;
606         if(!psnet_init_tcp()){
607                 ml_printf("Error on TCP startup %d\n", Tcp_failure_code);               
608
609                 Tcp_active = 0;
610         } else {
611                 if(!psnet_init_rel_tcp(Psnet_default_port + 1, 0)){
612                         ml_printf("Network", "Error on TCP startup %d\n", Tcp_failure_code);                    
613
614                         Tcp_active = 0;
615                 }
616         }
617
618         // clear reliable sockets
619         reliable_socket *rsocket;
620         int j;  
621         for(j=0; j<MAXRELIABLESOCKETS; j++){
622                 rsocket=&Reliable_sockets[j];
623                 memset(rsocket,0,sizeof(reliable_socket));
624         }
625
626         // determine if we've successfully initialized the protocol we want
627         if ( !Tcp_active ) {
628                 Network_status = NETWORK_STATUS_NO_PROTOCOL;            
629
630                 ml_string("No protocol in psnet_init()!");
631         }
632
633         // specified network timeout    
634         Nettimeout = NETTIMEOUT;
635         if(Cmdline_timeout > 0){
636                 Nettimeout = Cmdline_timeout;
637         }
638
639         // set ras status
640         psnet_ras_status();     
641
642         if(Network_status != NETWORK_STATUS_NO_PROTOCOL){                       
643                 // set network to be running
644                 Network_status = NETWORK_STATUS_RUNNING;        
645         
646                 // determine if our socket can broadcast
647                 Can_broadcast = Tcp_can_broadcast;
648         
649                 // initialize all packet type buffers
650                 for(idx=0; idx<PSNET_NUM_TYPES; idx++){
651                         psnet_buffer_init(&Psnet_top_buffers[idx]);
652                 }
653         }
654 }
655
656 // shutdown psnet
657 void psnet_close()
658 {
659         if ( Network_status != NETWORK_STATUS_RUNNING ){
660                 return;
661         }
662
663 #ifndef PLAT_UNIX
664         WSACancelBlockingCall();                
665 #endif
666
667         if ( TCP_socket != (int)INVALID_SOCKET ) {
668                 shutdown( TCP_socket, 1 );
669                 closesocket( TCP_socket );
670         }
671
672 #ifndef PLAT_UNIX
673         if (WSACleanup())       {
674                 //Warning( LOCATION, "Error closing wsock!\n" );
675         }
676 #endif
677
678         // close down all reliable sockets - this forces them to
679         // send a disconnect to any remote machines     
680         psnet_rel_close();
681         
682         Network_status = NETWORK_STATUS_NOT_INITIALIZED;
683 }
684
685 // set the protocol to use
686 int psnet_use_protocol( int protocol )
687 {
688 #ifndef PLAT_UNIX
689         int len;
690 #else
691         socklen_t len;
692 #endif
693         struct sockaddr_in              ip_addr;
694
695         // zero out my address
696         Psnet_my_addr_valid = 0;
697         memset( &Psnet_my_addr, 0, sizeof(Psnet_my_addr) );
698
699         // wait until we choose a protocol to determine if we can broadcast
700         Can_broadcast = 0;
701
702         ml_string("In psnet_use_protocol()");
703
704         if (protocol != NET_TCP) {
705                 Int3();
706                 return 0;
707         }
708
709
710         if ( Network_status != NETWORK_STATUS_RUNNING ){
711                 ml_string("Network_status != NETWORK_STATUS_RUNNING in NET_TCP in psnet_use_protocol()");
712                 return 0;
713         }
714
715         // assign the TCP_* sockets to the socket values used elsewhere
716         Unreliable_socket = TCP_socket;
717
718         Can_broadcast = Tcp_can_broadcast;
719         if(Can_broadcast){
720                 ml_printf("Psnet : TCP broadcast\n");
721         }
722
723         // get the socket name, and put it into My_addr
724         len = sizeof(struct sockaddr_in);
725         if ( getsockname(TCP_socket, (struct sockaddr *)&ip_addr, &len) == SOCKET_ERROR ) {
726                 ml_printf("Unable to get sock name for TCP unreliable socket (%d)\n", WSAGetLastError() );
727
728                 return 0;
729         }
730
731         memcpy(Psnet_my_addr.addr, &ip_addr.sin_addr, 4);
732         Psnet_my_addr.port = Psnet_default_port;
733
734         ml_printf("Psnet using - NET_TCP\n");
735
736
737         Psnet_my_addr.type = protocol;
738         Socket_type = protocol;
739
740         return 1;
741 }
742
743 // get the status of the network
744 int psnet_get_network_status()
745 {
746         // first case is when "none" is selected
747         if ( Psnet_connection == NETWORK_CONNECTION_NONE ) {
748                 return NETWORK_ERROR_NO_TYPE;
749         }
750
751         // first, check the connection status of the network
752         if ( Network_status == NETWORK_STATUS_NO_WINSOCK )
753                 return NETWORK_ERROR_NO_WINSOCK;
754
755         if ( Network_status == NETWORK_STATUS_NO_PROTOCOL ){
756                 return NETWORK_ERROR_NO_PROTOCOL;
757         }
758         
759         // network is running -- be sure that the RAS people know to connect if they currently cannot.
760         
761         if ( Psnet_connection == NETWORK_CONNECTION_DIALUP ) {
762                 // if on a dialup connection, be sure that RAS is active.
763                 if ( !Ras_connected ) {
764                         return NETWORK_ERROR_CONNECT_TO_ISP;
765                 }
766         } else if ( Psnet_connection == NETWORK_CONNECTION_LAN ) {
767                 // if on a LAN, and they have a dialup connection active, return error to indicate that they need
768                 // to pick the right connection type
769                 if ( Ras_connected ) {
770                         return NETWORK_ERROR_LAN_AND_RAS;
771                 }
772         }
773         return NETWORK_ERROR_NONE;
774 }
775
776 // convert a net_addr to a string
777 char* psnet_addr_to_string( char * text, const int max_textlen, net_addr_t * address )
778 {
779
780         if ( Network_status != NETWORK_STATUS_RUNNING )         {
781                 SDL_strlcpy( text, XSTR("[no networking]",910), max_textlen );
782                 return text;
783         }
784
785         in_addr temp_addr;
786
787         SDL_assert(address->type == NET_TCP);
788
789         memcpy(&temp_addr.s_addr, address->addr, 4);
790         SDL_strlcpy( text, inet_ntoa(temp_addr), max_textlen );
791
792         return text;
793 }
794
795 // convert a string to a net addr
796 void psnet_string_to_addr( net_addr_t * address, char * text, const int max_textlen )
797 {
798         struct hostent *he;
799         char str[255], *c, *port;
800         in_addr addr;
801
802         if ( Network_status != NETWORK_STATUS_RUNNING ) {
803                 SDL_strlcpy( text, XSTR("[no networking]",910), max_textlen );
804                 return;
805         }
806
807         // copy the text string to local storage to look for ports
808         SDL_assert( strlen(text) < 255 );
809         SDL_strlcpy(str, text, SDL_arraysize(str));
810         c = strrchr(str, ':');
811         port = NULL;
812         if ( c ) {
813                 *c = '\0';
814                 port = c+1;
815         }
816
817         SDL_assert(address->type == NET_TCP);
818
819
820         addr.s_addr = inet_addr(str);
821         // if we get INADDR_NONE returns, then we need to try and resolve the host
822         // name
823         if ( addr.s_addr == INADDR_NONE ) {
824                 he = gethostbyname( str );
825                 // returns a non-null pointer if successful, so get the address
826                 if ( he ) {
827                         addr.s_addr = ((in_addr *)(he->h_addr))->s_addr;                        // this is the address in network byte order
828                 } else {
829                         addr.s_addr = INADDR_NONE;
830                 }
831         }
832
833         memcpy(address->addr, &addr.s_addr, 4);
834
835         if ( port ){
836                 address->port = (ushort)(atoi(port));
837         }
838 }
839
840 // compare 2 addresses
841 int psnet_same( net_addr_t * a1, net_addr_t * a2 )
842 {
843         return !memcmp(a1->addr, a2->addr, 4);
844 }
845
846 // send data unreliably
847 int psnet_send( net_addr_t * who_to, void * data, int len, int np_index )
848 {
849         // send data unreliably
850         SOCKET send_sock;
851         struct sockaddr_in sockaddr;                            // UDP/TCP socket structure
852         int ret, send_len;
853         ubyte iaddr[4], *send_data;
854         short port;
855         fd_set  wfds;
856         struct timeval timeout; 
857
858         // always use the reliable socket
859         send_sock = Unreliable_socket;          
860
861         if ( Network_status != NETWORK_STATUS_RUNNING ) {
862                 ml_printf("Network ==> Socket not inited in psnet_send\n");
863                 return 0;
864         }
865
866         if ( psnet_same( who_to, &Psnet_my_addr) ){
867                 return 0;
868         }
869
870         if (who_to->type != NET_TCP) {
871                 Int3();
872                 return 0;
873         }
874
875         memcpy(iaddr, who_to->addr, 4);
876
877         if ( memcmp(iaddr, Null_address, 4) == 0) {
878                 ml_printf("Network ==> send to address is 0 in psnet_send\n");
879                 return 0;
880         }
881
882         port = who_to->port;
883                 
884         if ( port == 0) {
885                 ml_printf("Network ==> destination port %d invalid in psnet_send\n", port);
886                 return 0;
887         }
888
889         // stuff the data with the type 
890         send_data = (ubyte*)data;
891         send_len = len;
892
893         FD_ZERO(&wfds);
894         FD_SET( send_sock, &wfds );
895         timeout.tv_sec = 0;
896         timeout.tv_usec = 0;
897
898         if ( SELECT( send_sock+1, NULL, &wfds, NULL, &timeout, PSNET_TYPE_UNRELIABLE) == SOCKET_ERROR ) {       
899                 ml_printf("Error on blocking select for write %d\n", WSAGetLastError() );
900                 return 0;
901         }
902
903         // if the write file descriptor is not set, then bail!
904         if ( !FD_ISSET(send_sock, &wfds ) ){
905                 return 0;
906         }
907
908         sockaddr.sin_family = AF_INET;
909         memcpy(&sockaddr.sin_addr.s_addr, iaddr, 4);
910         sockaddr.sin_port = htons(port);
911
912         multi_rate_add(np_index, "udp(h)", send_len + UDP_HEADER_SIZE);
913         multi_rate_add(np_index, "udp", send_len);
914         ret = SENDTO( send_sock, (char *)send_data, send_len, 0, (struct sockaddr*)&sockaddr, sizeof(sockaddr), PSNET_TYPE_UNRELIABLE );
915
916         if ( ret != SOCKET_ERROR )      {
917                 return 1;
918         }
919         //Warning( LOCATION, "Couldn't send data (0x%x)!\n", WSAGetLastError() ); 
920         return 0;
921 }
922
923 // get data from the unreliable socket
924 int psnet_get( void * data, net_addr_t * from_addr )
925 {                                       
926         int buffer_size;
927
928         // try and get a free buffer and return its size
929         if(psnet_buffer_get_next(&Psnet_top_buffers[PSNET_TYPE_UNRELIABLE], (ubyte*)data, &buffer_size, from_addr)){
930                 return buffer_size;
931         }
932
933         // return nothing
934         return 0;
935 }
936
937 // broadcast data on unreliable socket
938 int psnet_broadcast( net_addr_t * who_to, void * data, int len )
939 {
940         if ( Network_status != NETWORK_STATUS_RUNNING ) {
941                 ml_printf("Network ==> Socket not inited in psnet_broadcast\n");
942                 return 0;
943         }
944
945         if ( !Can_broadcast ) {
946                 ml_printf("Cannot broadcast -- returning without doing anything\n");
947                 return 0;
948         }
949
950         ubyte broadcast[4] = { 0xff, 0xff, 0xff, 0xff };
951
952         // broadcasting works on a local subnet which is all we really want to do for now anyway.
953         // we might keep this in as an option for freespace later.
954         memcpy(who_to->addr, broadcast, 4);
955         psnet_send(who_to, data, len);
956
957         return 1;
958 }
959
960 // flush all sockets
961 void psnet_flush()
962 {
963         ubyte data[MAX_TOP_LAYER_PACKET_SIZE + 250];
964         net_addr_t from_addr;
965
966         while ( psnet_get( data, &from_addr ) > 0 ) ;
967 }
968
969 // if the passed string is a valid IP string
970 int psnet_is_valid_ip_string( char *ip_string, int allow_port )
971 {
972         in_addr addr;
973         struct hostent *host_ent;
974         char str[255], *c;
975
976         // our addresses may have ports, so make local copy and remove port number
977         SDL_assert( strlen(ip_string) < 255 );
978         SDL_strlcpy(str, ip_string, SDL_arraysize(str));
979         c = strrchr(str, ':');
980         if ( c ){
981                 *c = '\0';
982         }       
983
984         addr.s_addr = inet_addr(ip_string);
985         if ( addr.s_addr != INADDR_NONE ){
986                 // make sure the ip string is a valid format string
987                 if(psnet_is_valid_numeric_ip(ip_string)){
988                         return 1;
989                 }
990         }
991
992         // try name resolution
993         host_ent = gethostbyname( ip_string );
994         if ( !host_ent ){
995                 return 0;
996         }
997
998         // valid host entry so return 1;
999         return 1;
1000 }
1001
1002
1003 // -------------------------------------------------------------------------------------------------------
1004 // PSNET 2 RELIABLE SOCKET FUNCTIONS
1005 //
1006
1007 // compare 2 pings
1008 int psnet_rel_ping_compare( const void *arg1, const void *arg2 )
1009 {
1010         float *ping1 = (float *)arg1;
1011         float *ping2 = (float *)arg2;
1012         
1013         if(*ping1==*ping2) return 0;
1014         else if(*ping1>*ping2) return 1;
1015         else if(*ping1<*ping2) return -1;
1016
1017         return 0;
1018 }
1019
1020 void psnet_rel_send_ack(struct sockaddr *raddr, unsigned int sig, ubyte link_type, float time_sent)
1021 {
1022         int sig_tmp;
1023         reliable_header ack_header;
1024
1025         if (link_type != NET_TCP) {
1026                 Int3();
1027                 return;
1028         }
1029
1030         ack_header.type = RNT_ACK;      
1031         ack_header.data_len = sizeof(unsigned int);
1032         ack_header.send_time = INTEL_FLOAT( time_sent );
1033         sig_tmp = INTEL_INT( sig );
1034         memcpy(&ack_header.data,&sig_tmp,sizeof(unsigned int));
1035
1036         if ( !Tcp_active ) {
1037                 ml_string("No TCP in rel_send_ack()");
1038                 return;
1039         }
1040
1041         SENDTO(Unreliable_socket, (char *)&ack_header, RELIABLE_PACKET_HEADER_ONLY_SIZE+sizeof(unsigned int), 0, raddr, sizeof(struct sockaddr), PSNET_TYPE_RELIABLE);
1042 }
1043
1044 // function to shutdown and close the given socket.  It takes a couple of things into consideration
1045 // when closing, such as possibly reiniting reliable sockets if they are closed here.
1046 void psnet_rel_close_socket( PSNET_SOCKET_RELIABLE *sockp )
1047 {
1048         reliable_header diss_conn_header;
1049
1050         // if the socket is out of range
1051         if(*sockp>=MAXRELIABLESOCKETS)
1052         {
1053                 ml_printf("Invalid socket id passed to nw_NewCloseSocket() -- %d\n",*sockp);
1054                 return;
1055         }       
1056         ml_printf("Closing socket %d\n",*sockp);
1057         
1058         // go through every buffer and "free it up(tm)"
1059         int i;
1060         for(i=0;i<MAXNETBUFFERS;i++){
1061                 if(Reliable_sockets[*sockp].rbuffers[i]){
1062                         if(Reliable_sockets[*sockp].rbuffers[i] != NULL){
1063                                 free(Reliable_sockets[*sockp].rbuffers[i]);
1064                         }
1065                         Reliable_sockets[*sockp].rbuffers[i] = NULL;
1066                         Reliable_sockets[*sockp].rsequence[i] = 0;
1067                 }
1068                 if(Reliable_sockets[*sockp].sbuffers[i]){
1069                         if(Reliable_sockets[*sockp].sbuffers[i] != NULL){
1070                                 free(Reliable_sockets[*sockp].sbuffers[i]);
1071                         }
1072                         Reliable_sockets[*sockp].sbuffers[i] = NULL;
1073                         Reliable_sockets[*sockp].rsequence[i] = 0;
1074                 }
1075         }
1076
1077         // send a disconnect packet to the socket on the other end
1078         diss_conn_header.type = RNT_DISCONNECT;
1079         diss_conn_header.seq = CONNECTSEQ;
1080         diss_conn_header.data_len = 0;
1081         if(*sockp==Serverconn){
1082                 Serverconn = 0xffffffff;
1083         }
1084
1085         if (Reliable_sockets[*sockp].connection_type ==  NET_TCP) {
1086                 SDL_assert(Tcp_active);
1087                 SENDTO(Unreliable_socket, (char *)&diss_conn_header,RELIABLE_PACKET_HEADER_ONLY_SIZE,0,&Reliable_sockets[*sockp].addr,sizeof(struct sockaddr), PSNET_TYPE_RELIABLE);
1088         } else {
1089                 ml_printf("Unknown protocol type in nw_CloseSocket()!\n");
1090                 // Int3();
1091         }
1092
1093         memset(&Reliable_sockets[*sockp],0,sizeof(reliable_socket));
1094         Reliable_sockets[*sockp].status = RNF_UNUSED;   
1095 }
1096
1097 // function to check the status of the reliable socket and try to re-initialize it if necessary.
1098 // win95 seems to have trouble doing a reinit of the socket immediately after close, so this
1099 // function exists to check the status, and reinitialize if we need to
1100 int psnet_rel_check()
1101 {
1102         return 1;
1103 }
1104
1105 // send data reliably
1106 int psnet_rel_send(PSNET_SOCKET_RELIABLE socketid, ubyte *data, int length, int np_index)
1107 {               
1108         int i;
1109         int bytesout = 0;
1110         reliable_socket *rsocket;       
1111         
1112         if(socketid >= MAXRELIABLESOCKETS){
1113                 ml_printf("Invalid socket id passed to psnet_rel_send() -- %d\n",socketid);
1114                 return -1;
1115         }
1116
1117         SDL_assert( length < (int)(sizeof(reliable_header)) );
1118         psnet_rel_work();
1119
1120         rsocket=&Reliable_sockets[socketid];
1121         if(rsocket->status!=RNF_CONNECTED) {
1122                 //We can't send because this isn't a connected reliable socket.
1123                 ml_printf("Can't send packet because of status %d in nw_SendReliable(). socket = %d\n",rsocket->status,socketid);
1124                 return -1;
1125         }
1126         
1127         // Add the new packet to the sending list and send it.
1128         for(i=0;i<MAXNETBUFFERS;i++){
1129                 if(NULL==rsocket->sbuffers[i]){                 
1130                         reliable_header send_header;
1131                         int send_this_packet=1;                 
1132                         
1133                         rsocket->send_len[i] = length;
1134                         rsocket->sbuffers[i] = (reliable_net_sendbuffer *)malloc(sizeof(reliable_net_sendbuffer));
1135                 
1136                         memcpy(rsocket->sbuffers[i]->buffer,data,length);       
1137
1138                         send_header.seq = INTEL_SHORT( rsocket->theirsequence );
1139                         rsocket->ssequence[i] = rsocket->theirsequence;
1140                         
1141                         memcpy(send_header.data,data,length);
1142                         send_header.data_len = INTEL_SHORT( (ushort)length );
1143                         send_header.type = RNT_DATA;
1144                         send_header.send_time = psnet_get_time();
1145                         send_header.send_time = INTEL_FLOAT( send_header.send_time );
1146                         // struct sockaddr_in * rsockaddr = (struct sockaddr_in *)&rsocket->addr;
1147                                         
1148                         if (send_this_packet){
1149                                 if (rsocket->connection_type == NET_TCP) {
1150                                         SDL_assert(Tcp_active);
1151                                         multi_rate_add(np_index, "tcp(h)", RELIABLE_PACKET_HEADER_ONLY_SIZE+rsocket->send_len[i]);
1152                                         bytesout = SENDTO(Unreliable_socket, (char *)&send_header,RELIABLE_PACKET_HEADER_ONLY_SIZE+rsocket->send_len[i],0,&rsocket->addr,sizeof(struct sockaddr), PSNET_TYPE_RELIABLE);
1153                                 } else {
1154                                         ml_printf("Unknown protocol type in nw_SendReliable()!\n");
1155                                         Int3();
1156                                 }               
1157                         }
1158                         int error = WSAGetLastError();
1159                         if((bytesout==SOCKET_ERROR)&&NETCALL_WOULDBLOCK(error)){
1160                                 //This will cause it to try to send again next frame. (or sooner)
1161                                 rsocket->timesent[i] = psnet_get_time()-(NETRETRYTIME*4);
1162                         } else {
1163                                 rsocket->timesent[i] = psnet_get_time();
1164                         }
1165                         
1166                                                 
1167                         rsocket->theirsequence++;
1168                         return bytesout;
1169                 }
1170         }
1171         ml_printf("PSNET RELIABLE SEND BUFFER OVERRUN. socket = %d\n",socketid);        
1172         // Int3();
1173         return 0;
1174 }
1175
1176 // Return codes:
1177 // -1 socket not connected
1178 // 0 No packet ready to receive
1179 // >0 Buffer filled with the number of bytes recieved
1180 int psnet_rel_get(PSNET_SOCKET socketid, ubyte *buffer, int max_len)
1181 {       
1182         int i;
1183         
1184         reliable_socket *rsocket = NULL;
1185         psnet_rel_work();
1186         if(socketid >= MAXRELIABLESOCKETS){
1187                 ml_printf("Invalid socket id passed to nw_NewReceiveReliable() -- %d\n",socketid);
1188                 return -1;
1189         }
1190         rsocket = &Reliable_sockets[socketid];
1191         if( (RNF_CONNECTED!=rsocket->status) && (RNF_LIMBO!=rsocket->status) ){
1192                 ml_printf("Can't receive packet because it isn't connected in nw_ReceiveReliable(). socket = %d\n",socketid);
1193                 return 0;
1194         }
1195         //If the buffer position is the position we are waiting for, fill in 
1196         //the buffer we received in the call to this function and return true                   
1197
1198         for(i=0; i<MAXNETBUFFERS; i++){
1199                 if((rsocket->rsequence[i] == rsocket->oursequence) && rsocket->rbuffers[i]){
1200                         memcpy(buffer,rsocket->rbuffers[i]->buffer, rsocket->recv_len[i]);
1201                         free(rsocket->rbuffers[i]);
1202                         rsocket->rbuffers[i] = NULL;
1203                         rsocket->rsequence[i] = 0;                      
1204                         rsocket->oursequence++;
1205                         return rsocket->recv_len[i];
1206                 }
1207         }
1208
1209         return 0;       
1210 }
1211
1212 // process all active reliable sockets
1213 void psnet_rel_work()
1214 {
1215         int i,j;
1216         int rcode = -1;
1217         int max_len = NETBUFFERSIZE;
1218         fd_set read_fds;                   
1219         struct timeval timeout;
1220         static reliable_header rcv_buff;
1221         static struct sockaddr rcv_addr;
1222         int bytesin = 0;
1223         int addrlen = sizeof(struct sockaddr);
1224         timeout.tv_sec=0;            
1225         timeout.tv_usec=0;
1226
1227         PSNET_TOP_LAYER_PROCESS();
1228                 
1229         // negotitate initial connection with the server
1230         reliable_socket *rsocket = NULL;
1231         if(Serverconn != 0xffffffff){
1232                 //Check to see if we need to send a packet out.
1233                 if((Reliable_sockets[Serverconn].status==RNF_LIMBO) && ((Serverconn != 0xffffffff) && fl_abs((psnet_get_time() - Last_sent_iamhere))>NETRETRYTIME) ){
1234                         reliable_header conn_header;
1235                         //Now send I_AM_HERE packet
1236                         conn_header.type = RNT_I_AM_HERE;
1237                         conn_header.seq = (ushort)(~CONNECTSEQ);
1238                         conn_header.data_len = 0;
1239                         Last_sent_iamhere = psnet_get_time();
1240                         int ret = SOCKET_ERROR;
1241
1242                         if (Reliable_sockets[Serverconn].connection_type == NET_TCP) {
1243                                 SDL_assert(Tcp_active);
1244                                 ret = SENDTO(Unreliable_socket, (char *)&conn_header,RELIABLE_PACKET_HEADER_ONLY_SIZE,0,&Reliable_sockets[Serverconn].addr,sizeof(struct sockaddr), PSNET_TYPE_RELIABLE);
1245                         }
1246
1247                         int error = WSAGetLastError();
1248                         if((ret == SOCKET_ERROR) && NETCALL_WOULDBLOCK(error)){
1249                                 Reliable_sockets[Serverconn].last_packet_sent = psnet_get_time()-NETRETRYTIME;
1250                         } else {
1251                                 Reliable_sockets[Serverconn].last_packet_sent = psnet_get_time();
1252                         }
1253                 }
1254         }
1255
1256         ubyte link_type;
1257         net_addr_t d3_rcv_addr;
1258         struct sockaddr_in *rcvaddr;
1259         int udp_has_data = 0;
1260         do {            
1261                 rsocket = NULL;
1262                 //Check UDP
1263                 FD_ZERO(&read_fds);
1264                 FD_SET(Unreliable_socket, &read_fds);
1265
1266                 udp_has_data = SELECT(Unreliable_socket+1,&read_fds,NULL,NULL,&timeout, PSNET_TYPE_RELIABLE);
1267
1268                 if (udp_has_data <= 0) {
1269                         break;
1270                 }
1271
1272                 addrlen = sizeof(struct sockaddr);
1273                 struct sockaddr_in *tcp_addr = (struct sockaddr_in *)&rcv_addr;
1274                 memset(&d3_rcv_addr,0,sizeof(net_addr_t));
1275                 memset(&rcv_addr,0,sizeof(struct sockaddr));
1276                 bytesin = RECVFROM(Unreliable_socket, (char *)&rcv_buff,sizeof(reliable_header), 0, (struct sockaddr *)&rcv_addr,&addrlen, PSNET_TYPE_RELIABLE);
1277                 rcv_buff.seq = INTEL_SHORT( rcv_buff.seq );
1278                 rcv_buff.data_len = INTEL_SHORT( rcv_buff.data_len );
1279                 rcv_buff.send_time = INTEL_FLOAT( rcv_buff.send_time );
1280                 memcpy(d3_rcv_addr.addr, &tcp_addr->sin_addr.s_addr, 4);
1281                 d3_rcv_addr.port = tcp_addr->sin_port;
1282                 d3_rcv_addr.type = NET_TCP;
1283                 link_type = NET_TCP;
1284
1285                 if(bytesin==-1){
1286                         ml_printf("recvfrom returned an error! -- %d\n",WSAGetLastError());
1287                         //Int3();//See Kevin                    
1288                         return;
1289                 }
1290                 if(bytesin){
1291                         //Someone wants to connect, so find a slot
1292                         if(rcv_buff.type == RNT_REQ_CONN){
1293                                 for(i=1; i<MAXRELIABLESOCKETS; i++){
1294                                         if( (Reliable_sockets[i].status == RNF_CONNECTED) || (Reliable_sockets[i].status == RNF_LIMBO) ){
1295                                                 //if(memcmp(&rcv_addr,&reliable_sockets[i].addr,sizeof(struct sockaddr))==0)
1296                                                 if(memcmp(&d3_rcv_addr, &Reliable_sockets[i].net_addr, sizeof(net_addr_t)) == 0){
1297                                                         //We already have a reliable link to this user, so we will ignore it...
1298                                                         ml_printf("Received duplicate connection request. %d\n",i);
1299                                                         //reliable_sockets[i].last_packet_received = timer_GetTime();
1300                                                         psnet_rel_send_ack(&Reliable_sockets[i].addr, rcv_buff.seq, link_type, rcv_buff.send_time);
1301                                                         //We will change this as a hack to prevent later code from hooking us up
1302                                                         rcv_buff.type = 0xff;
1303                                                         continue;
1304                                                 }
1305                                         }
1306                                 }
1307                                 for(i=1; i<MAXRELIABLESOCKETS; i++){
1308                                         if(Reliable_sockets[i].status == RNF_UNUSED){
1309                                                 //Add the new connection here.
1310                                                 Reliable_sockets[i].connection_type=link_type;
1311                                                 memcpy(&Reliable_sockets[i].net_addr, &d3_rcv_addr, sizeof(net_addr_t));
1312                                                 memcpy(&Reliable_sockets[i].addr ,&rcv_addr, sizeof(struct sockaddr));
1313                                                 Reliable_sockets[i].ping_pos = 0;
1314                                                 Reliable_sockets[i].num_ping_samples = 0;
1315                                                 Reliable_sockets[i].status = RNF_LIMBO;
1316                                                 Reliable_sockets[i].last_packet_received = psnet_get_time();
1317                                                 rsocket = &Reliable_sockets[i];
1318                                                 rcvaddr = (struct sockaddr_in *)&rcv_addr;
1319                                                 ml_printf("Connect from %s:%d\n", inet_ntoa(rcvaddr->sin_addr), htons(rcvaddr->sin_port));
1320                                                 break;
1321                                         }
1322                                 }
1323                                 if(i==MAXRELIABLESOCKETS){
1324                                         //No more connections!
1325                                         ml_printf("Out of incoming reliable connection sockets\n");
1326                                         //Int3();//See Kevin
1327                                         continue;
1328                                 }
1329                                 psnet_rel_send_ack(&rsocket->addr, rcv_buff.seq, link_type, rcv_buff.send_time);                        
1330                         }
1331                         
1332                         //Find out if this is a packet from someone we were expecting a packet.
1333                         rcvaddr = (struct sockaddr_in *)&rcv_addr;
1334                         for(i=1; i<MAXRELIABLESOCKETS; i++){
1335                                 if(memcmp(&d3_rcv_addr,&Reliable_sockets[i].net_addr,sizeof(net_addr_t)) == 0){
1336                                         rsocket=&Reliable_sockets[i];
1337                                         break;
1338                                 }                               
1339                         }
1340                         if(rsocket == NULL){
1341                                 ml_printf("Received reliable data from unconnected client.\n");
1342                                 ml_printf("Received from %s:%d\n",inet_ntoa(rcvaddr->sin_addr),rcvaddr->sin_port);
1343                                 continue ;
1344                         }
1345                         rsocket->last_packet_received = psnet_get_time();
1346                         
1347                         if(rsocket->status != RNF_CONNECTED){
1348                                 //Get out of limbo
1349                                 if(rsocket->status == RNF_LIMBO){
1350                                         //this is our connection to the server
1351                                         if(Serverconn != 0xffffffff){
1352                                                 if(rcv_buff.type == RNT_ACK){
1353                                                         ushort *acknum = (ushort *)&rcv_buff.data;
1354                                                         if(*acknum == (~CONNECTSEQ & 0xffff)){
1355                                                                 rsocket->status = RNF_CONNECTED;
1356                                                                 ml_printf("Got ACK for IAMHERE!\n");
1357                                                         }
1358                                                         continue;
1359                                                 }
1360                                         } else if(rcv_buff.type == RNT_I_AM_HERE){
1361                                                 rsocket->status = RNF_CONNECTING;
1362                                                 psnet_rel_send_ack(&rsocket->addr, rcv_buff.seq, link_type, rcv_buff.send_time);                
1363                                                 ml_printf("Got IAMHERE!\n");
1364                                                 continue;
1365                                         }
1366                                 }
1367                                 if((rcv_buff.type == RNT_DATA) && (Serverconn != 0xffffffff)){
1368                                         rsocket->status = RNF_CONNECTED;
1369                                 } else {                                        
1370                                         rsocket->last_packet_received = psnet_get_time();
1371                                         continue;
1372                                 }                               
1373                         }
1374                         //Update the last recv variable so we don't need a heartbeat
1375                         rsocket->last_packet_received = psnet_get_time();
1376
1377                         if(rcv_buff.type == RNT_HEARTBEAT){
1378                                 continue;
1379                         }
1380                         if(rcv_buff.type == RNT_ACK){
1381                                 //Update ping time
1382                                 rsocket->num_ping_samples++;
1383                                 
1384                                 rsocket->pings[rsocket->ping_pos] = rsocket->last_packet_received - rcv_buff.send_time;                         
1385                                 if(rsocket->num_ping_samples >= MAX_PING_HISTORY){
1386                                         float sort_ping[MAX_PING_HISTORY];
1387                                         for(int a=0;a<MAX_PING_HISTORY;a++){
1388                                                 sort_ping[a] = rsocket->pings[a];
1389                                         }
1390
1391                                         qsort(sort_ping ,MAX_PING_HISTORY, sizeof(float), psnet_rel_ping_compare);
1392                                         rsocket->mean_ping = ((sort_ping[MAX_PING_HISTORY/2]+sort_ping[(MAX_PING_HISTORY/2)+1]))/2;                                     
1393                                 }
1394                                 rsocket->ping_pos++;
1395                                 if(rsocket->ping_pos >= MAX_PING_HISTORY){
1396                                         rsocket->ping_pos=0;                            
1397                                 }
1398
1399                                 // if this is an ack for a send buffer on the socket, kill the send buffer. its done
1400                                 for(i=0; i<MAXNETBUFFERS; i++){
1401                                         unsigned int *acksig = (unsigned int *)&rcv_buff.data;
1402                                         if(rsocket){
1403                                                 if(rsocket->sbuffers[i]){
1404                                                         if(rsocket->ssequence[i] == INTEL_INT(*acksig) ){                                                               
1405                                                                 SDL_assert(rsocket->sbuffers[i] != NULL);
1406                                                                 free(rsocket->sbuffers[i]);
1407                                                                 rsocket->sbuffers[i] = NULL;    
1408                                                                 rsocket->ssequence[i] = 0;
1409                                                         }
1410                                                 }
1411                                         }
1412                                 }
1413                                 //remove that packet from the send buffer
1414                                 rsocket->last_packet_received = psnet_get_time();
1415                                 continue;
1416                         }
1417
1418                         if(rcv_buff.type == RNT_DATA_COMP){
1419                                 //More2Come
1420                                 //Decompress it. Put it back in the buffer. Process it as RNT_DATA
1421                                 rcv_buff.type = RNT_DATA;
1422                         }
1423                         if(rcv_buff.type == RNT_DATA){                          
1424                                 //If the data is out of order by >= MAXNETBUFFERS-1 ignore that packet for now
1425                                 int seqdelta;
1426                                 seqdelta = rcv_buff.seq - rsocket->oursequence;
1427                                 if(seqdelta<0) seqdelta = seqdelta*-1;
1428                                 if(seqdelta>=MAXNETBUFFERS - 1){
1429                                         ml_printf("Received reliable packet out of order!\n");
1430                                         //It's out of order, so we won't ack it, which will mean we will get it again soon.
1431                                         continue;
1432                                 }
1433                                 //else move data into the proper buffer position
1434                                 int savepacket=1;
1435                                 
1436                                 if(rsocket->oursequence < (0xffff - (MAXNETBUFFERS-1))){
1437                                         if (rsocket->oursequence > rcv_buff.seq){
1438                                                 savepacket = 0;
1439                                         }
1440                                 } else {
1441                                         //Sequence is high, so prepare for wrap around
1442                                         if( ((unsigned short)(rcv_buff.seq + rsocket->oursequence)) > (MAXNETBUFFERS-1)){
1443                                                 savepacket = 0; 
1444                                         }
1445                                 }
1446
1447                                 for(i=0; i<MAXNETBUFFERS; i++){
1448                                         if( (NULL != rsocket->rbuffers[i]) && (rsocket->rsequence[i] == rcv_buff.seq)){
1449                                                 //Received duplicate packet!                                            
1450                                                 savepacket = 0;
1451                                         }
1452                                 }
1453                                 if(savepacket){
1454                                         for(i=0; i<MAXNETBUFFERS; i++){
1455                                                 if(NULL == rsocket->rbuffers[i]){                                                       
1456                                                         if(rcv_buff.data_len>max_len){
1457                                                                 rsocket->recv_len[i] = rcv_buff.data_len;
1458                                                         } else {
1459                                                                 rsocket->recv_len[i] = rcv_buff.data_len; 
1460                                                         }
1461                                                         rsocket->rbuffers[i] = (reliable_net_rcvbuffer *)malloc(sizeof(reliable_net_rcvbuffer));
1462                                                         memcpy(rsocket->rbuffers[i]->buffer,rcv_buff.data,rsocket->recv_len[i]);        
1463                                                         rsocket->rsequence[i] = rcv_buff.seq;                                                   
1464                                                         break;
1465                                                 }
1466                                         }
1467                                 }
1468                                 psnet_rel_send_ack(&rsocket->addr, rcv_buff.seq, link_type, rcv_buff.send_time);                
1469                         }
1470                         
1471                 }
1472         } while (udp_has_data > 0);
1473         
1474         // Go through each reliable socket that is connected and do any needed work.
1475         for(j=0; j<MAXRELIABLESOCKETS; j++){
1476                 rsocket=&Reliable_sockets[j];
1477
1478                 if(Serverconn == 0xffffffff){
1479                         if(rsocket->status==RNF_LIMBO){
1480                                 if(fl_abs((psnet_get_time() - rsocket->last_packet_received))>Nettimeout){
1481                                         ml_printf("Reliable (but in limbo) socket (%d) timed out in nw_WorkReliable().\n",j);
1482                                         memset(rsocket,0,sizeof(reliable_socket));
1483                                         rsocket->status = RNF_UNUSED;//Won't work if this is an outgoing connection.
1484                                 }
1485                         }
1486                 } else {
1487                         if((rsocket->status == RNF_LIMBO) && (fl_abs((psnet_get_time() - First_sent_iamhere)) > Nettimeout)){
1488                                 rsocket->status = RNF_BROKEN;
1489                                 ml_printf("Reliable socket (%d) timed out in nw_WorkReliable().\n",j);
1490                         }
1491                 }
1492                 
1493                 if(rsocket->status == RNF_CONNECTED){
1494                         float retry_packet_time;
1495                         if((rsocket->mean_ping==0) || (rsocket->mean_ping > (NETRETRYTIME*4))){
1496                                 retry_packet_time = NETRETRYTIME;
1497                         } else {
1498                                 if(rsocket->mean_ping<MIN_NET_RETRYTIME) {
1499                                         retry_packet_time = (float)MIN_NET_RETRYTIME;                                   
1500                                 } else {
1501                                         retry_packet_time = ((float)(float)rsocket->mean_ping * (float)1.25);                                   
1502                                 }
1503                         }
1504                         //Iterate through send buffers.  
1505                         for(i=0;i<MAXNETBUFFERS;i++){
1506                                 // send again
1507                                 if((rsocket->sbuffers[i]) && (fl_abs((psnet_get_time() - rsocket->timesent[i])) >= retry_packet_time)) {
1508                                         reliable_header send_header;                                    
1509                                         send_header.send_time = psnet_get_time();
1510                                         send_header.send_time = INTEL_FLOAT( send_header.send_time );
1511                                         send_header.seq = INTEL_SHORT( rsocket->ssequence[i] );
1512                                         memcpy(send_header.data,rsocket->sbuffers[i]->buffer,rsocket->send_len[i]);
1513                                         send_header.data_len = INTEL_SHORT( (ushort)rsocket->send_len[i] );
1514                                         send_header.type = RNT_DATA;
1515                                         if(rsocket->connection_type == NET_TCP){
1516                                                 rcode = SENDTO(Unreliable_socket, (char *)&send_header,RELIABLE_PACKET_HEADER_ONLY_SIZE+rsocket->send_len[i],0,&rsocket->addr,sizeof(struct sockaddr), PSNET_TYPE_RELIABLE);
1517                                         }
1518                                         int error = WSAGetLastError();
1519                                         if((rcode == SOCKET_ERROR) && NETCALL_WOULDBLOCK(error)){
1520                                                 //The packet didn't get sent, flag it to try again next frame
1521                                                 rsocket->timesent[i] = psnet_get_time()-(NETRETRYTIME*4);
1522                                         } else {
1523                                                 rsocket->last_packet_sent = psnet_get_time();
1524                                                 rsocket->timesent[i] = psnet_get_time();
1525                                         }
1526                                         
1527                                 }//getcwd
1528                         }
1529
1530                         if((rsocket->status == RNF_CONNECTED) && (fl_abs((psnet_get_time() - rsocket->last_packet_sent)) > NETHEARTBEATTIME)) {
1531                                 reliable_header send_header;                            
1532                                 send_header.send_time = psnet_get_time();
1533                                 send_header.send_time = INTEL_FLOAT( send_header.send_time );
1534                                 send_header.seq = 0;
1535                                 send_header.data_len = 0;
1536                                 send_header.type = RNT_HEARTBEAT;
1537
1538                                 rcode = -1;
1539                                 if(rsocket->connection_type == NET_TCP){
1540                                         rcode = SENDTO(Unreliable_socket, (char *)&send_header,RELIABLE_PACKET_HEADER_ONLY_SIZE,0,&rsocket->addr,sizeof(struct sockaddr), PSNET_TYPE_RELIABLE);
1541                                 }
1542                                 int error = WSAGetLastError();
1543                                 if((rcode != SOCKET_ERROR) && NETCALL_WOULDBLOCK(error)){
1544                                         //It must have been sent
1545                                         rsocket->last_packet_sent = psnet_get_time();
1546                                 }
1547                         }
1548
1549                         if((rsocket->status == RNF_CONNECTED) && (fl_abs((psnet_get_time() - rsocket->last_packet_received))>Nettimeout)){
1550                                 //This socket is hosed.....inform someone?
1551                                 ml_printf("Reliable Socket (%d) timed out in nw_WorkReliable().\n",j);
1552                                 rsocket->status = RNF_BROKEN;
1553                         }
1554                 }
1555         }       
1556 }
1557
1558 // get the status of a reliable socket, see RNF_* defines above
1559 int psnet_rel_get_status(PSNET_SOCKET_RELIABLE socketid)
1560 {       
1561         if(socketid >= MAXRELIABLESOCKETS){             
1562                 return -1;
1563         }
1564
1565         return Reliable_sockets[socketid].status;
1566 }
1567
1568 // function which checks the Listen_socket for possibly incoming requests to be connected.
1569 // returns 0 on error or nothing waiting.  1 if we should try to accept
1570 int psnet_rel_check_for_listen(net_addr_t *from_addr)
1571 {       
1572         struct sockaddr_in *ip_addr;                            // UDP/TCP socket structure
1573         
1574         psnet_rel_work();
1575         int i;
1576         for(i=1; i<MAXRELIABLESOCKETS; i++){
1577                 if(Reliable_sockets[i].status == RNF_CONNECTING){
1578                         Reliable_sockets[i].status = RNF_CONNECTED;
1579                         //memcpy(from_addr,&reliable_sockets[i].addr,sizeof(struct sockaddr));
1580                         ml_printf("New reliable connection in nw_CheckListenSocket().\n");
1581                         
1582                         if (Reliable_sockets[i].connection_type != NET_TCP) {
1583                                 continue;
1584                         }
1585
1586                         ip_addr = (struct sockaddr_in *)&Reliable_sockets[i].addr;
1587                         memset(from_addr, 0x00, sizeof(net_addr_t));
1588                         from_addr->port = ntohs( ip_addr->sin_port );
1589                         from_addr->type = NET_TCP;
1590                         memcpy(from_addr->addr, &ip_addr->sin_addr.s_addr, 4);
1591
1592                         /*
1593                         char dbg_output[50];
1594                         nw_GetNumbersFromHostAddress(from_addr,dbg_output);
1595                         mprintf((0,"Got address from: %s\n",dbg_output));
1596                         */
1597                         return i;
1598                 }
1599         }
1600         return INVALID_SOCKET;  
1601 }
1602
1603 // attacmpt to connect() to the server's tcp socket.  socket parameter is simply assigned to the
1604 // Reliable_socket socket created in psnet_init
1605 void psnet_rel_connect_to_server(PSNET_SOCKET *socket, net_addr_t *server_addr)
1606 {       
1607         //Send out a RNT_REQ_CONN packet, and wait for it to be acked.
1608         struct sockaddr_in sockaddr;                            // UDP/TCP socket structure
1609         struct sockaddr *addr = NULL;                                           // pointer to struct sockaddr to make coding easier
1610         struct sockaddr rcv_addr;
1611         int addrlen;
1612         ubyte iaddr[4];
1613         ushort port;
1614 //      float time_sent_req = 0;
1615         float first_sent_req = 0;
1616         static reliable_header conn_header;
1617         static reliable_header ack_header;
1618         int bytesin;
1619         struct timeval timeout;
1620         fd_set read_fds;
1621         int i;
1622         *socket = INVALID_SOCKET;       
1623         
1624         memcpy(iaddr, &server_addr->addr, 4);
1625         port = (ushort)(server_addr->port);     // Talk to the server listen port
1626         
1627         conn_header.type = RNT_REQ_CONN;
1628         conn_header.seq = CONNECTSEQ;
1629         conn_header.data_len = 0;
1630         
1631         timeout.tv_sec=0;            
1632         timeout.tv_usec=0;
1633
1634         if (server_addr->type != NET_TCP) {
1635                 return;
1636         }
1637
1638         SDL_assert(Tcp_active);
1639
1640         //Flush out any left overs
1641         FD_ZERO(&read_fds);
1642         FD_SET(Unreliable_socket, &read_fds);
1643         while(SELECT(Unreliable_socket+1, &read_fds, NULL, NULL, &timeout, PSNET_TYPE_RELIABLE)){
1644                 addrlen = sizeof(struct sockaddr);
1645                 bytesin = RECVFROM(Unreliable_socket, (char *)&ack_header,sizeof(reliable_header),0,(struct sockaddr *)&rcv_addr,&addrlen, PSNET_TYPE_RELIABLE);
1646                 if(bytesin==-1){
1647                         //Int3();//See Kevin
1648                         ml_printf("UDP recvfrom returned an error! -- %d\n",WSAGetLastError());
1649                         break;
1650                         //return;
1651                 }
1652                 FD_ZERO(&read_fds);
1653                 FD_SET(Unreliable_socket, &read_fds);
1654         }
1655
1656         memset(&ack_header,0,sizeof(reliable_header));
1657         SOCKET typeless_sock = 0;
1658         net_addr_t d3_rcv_addr;
1659         memset(&d3_rcv_addr,0,sizeof(net_addr_t));
1660
1661
1662         sockaddr.sin_family = AF_INET;
1663         memcpy(&sockaddr.sin_addr.s_addr, iaddr, 4);
1664         sockaddr.sin_port = htons(port);
1665         addr = (struct sockaddr *)&sockaddr;
1666         if( SOCKET_ERROR == SENDTO(Unreliable_socket, (char *)&conn_header,RELIABLE_PACKET_HEADER_ONLY_SIZE,0,addr,sizeof(struct sockaddr), PSNET_TYPE_RELIABLE) ){
1667                 ml_printf("Unable to send UDP packet in nw_ConnectToServer()! -- %d\n",WSAGetLastError());
1668                 return;
1669         }
1670         memcpy(d3_rcv_addr.addr, &sockaddr.sin_addr.s_addr, 4);
1671         d3_rcv_addr.port = sockaddr.sin_port;
1672         d3_rcv_addr.type = NET_TCP;
1673         typeless_sock = Unreliable_socket;
1674
1675
1676         first_sent_req = psnet_get_time();
1677 //      time_sent_req = psnet_get_time();
1678         
1679         //Wait until we get a response from the server or we timeout
1680         
1681         do {
1682                 PSNET_TOP_LAYER_PROCESS();
1683
1684                 FD_ZERO(&read_fds);
1685                 FD_SET(typeless_sock, &read_fds);
1686                 if(SELECT(typeless_sock+1, &read_fds, NULL,NULL,&timeout, PSNET_TYPE_RELIABLE)){
1687                         ml_string("selected() in psnet_rel_connect_to_server()");
1688
1689                         addrlen = sizeof(struct sockaddr);
1690                         bytesin = RECVFROM(typeless_sock,(char *)&ack_header,sizeof(reliable_header),0,(struct sockaddr *)&rcv_addr,&addrlen, PSNET_TYPE_RELIABLE);
1691                         if(bytesin==-1){
1692                                 ml_printf("recvfrom returned an error! -- %d\n",WSAGetLastError());
1693                                 Int3();//See Kevin
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].net_addr,&d3_rcv_addr,sizeof(net_addr_t));
1709                                                                 Reliable_sockets[i].last_packet_received = psnet_get_time();
1710                                                                 memcpy(&Reliable_sockets[i].addr,&rcv_addr,sizeof(struct sockaddr));
1711                                                                 Reliable_sockets[i].status = RNF_LIMBO;
1712                                                                 *socket = i;
1713                                                                 ml_printf("Succesfully connected to server in nw_ConnectToServer().\n");
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;
1719                                                                 First_sent_iamhere = psnet_get_time();
1720                                                                 Last_sent_iamhere = psnet_get_time();
1721                                                                 int rcode = SENDTO(typeless_sock,(char *)&conn_header,RELIABLE_PACKET_HEADER_ONLY_SIZE,0,addr,sizeof(struct 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_printf("Unable to send packet in nw_ConnectToServer()\n");
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_printf("Out of reliable socket space in nw_ConnectToServer().\n");
1740                                                 return;                                         
1741                                         } else ml_printf("Received out of sequence ACK in nw_ConnectToServer().\n");
1742                                 } else ml_printf("Received something that isn't an ACK in nw_ConnectToServer().\n");
1743                         } else ml_printf("Received 0 bytes from recvfrom() in nw_ConnectToServer().\n");
1744                 }
1745                 /*
1746                 if((psnet_get_time()-time_sent_req)>2)
1747                 {
1748                         ml_printf("Resending connect request.\n");
1749                         int ret = SENDTO(typeless_sock,(char *)&conn_header,RELIABLE_PACKET_HEADER_ONLY_SIZE,0,addr,sizeof(struct sockaddr), PSNET_TYPE_RELIABLE);
1750                         if(ret != SOCKET_ERROR){
1751                                 time_sent_req = psnet_get_time();
1752                         } else {
1753                                 ml_printf("Error sending connection request! -- %d\n",WSAGetLastError() );
1754                         }
1755                 }
1756                 */
1757
1758         } while(fl_abs((psnet_get_time() - first_sent_req)) < RELIABLE_CONNECT_TIME);   
1759 }
1760
1761 // returns the ip address of this computer
1762 /*
1763 int psnet_rel_get_ip()
1764 {
1765         char local[255];
1766         LPHOSTENT hostent;
1767         struct sockaddr_in local_address;
1768         int ret;
1769         
1770         // Get the local host name
1771         memset(&local_address, 0, sizeof(local_address));
1772         ret = gethostname(local, 255 );
1773         if (ret != SOCKET_ERROR ){
1774                 // Resolve host name for local address
1775                 hostent = gethostbyname((char *)local);
1776                 if ( hostent ){
1777                         local_address.sin_addr.s_addr = *((u_long FAR *)(hostent->h_addr));
1778                 }
1779         } else {
1780                 ml_string("SOCKET_ERROR in psnet_rel_get_ip()!");
1781         }
1782         ml_printf(%s:%d\n", inet_ntoa(rcvaddr->sin_addr), htons(rcvaddr->sin_port)
1783         return local_address.sin_addr.s_addr;
1784 }
1785 */
1786
1787 // returns the ip address of this computer
1788 int psnet_get_ip()
1789 {       
1790         struct sockaddr_in local_address;
1791
1792         if(Psnet_connection == NETWORK_CONNECTION_DIALUP){      
1793                 local_address.sin_addr.s_addr = psnet_ras_status();
1794                 if(local_address.sin_addr.s_addr == INADDR_NONE){
1795                         local_address.sin_addr.s_addr = INADDR_ANY;
1796                 }
1797         } else {
1798                 // Init local address to zero
1799                 local_address.sin_addr.s_addr = INADDR_ANY;                     
1800         }
1801
1802         // NOTE: for memeory checkers, do NOT try to free this
1803         ml_printf("psnet_get_ip() reports IP : %s\n", inet_ntoa(local_address.sin_addr));
1804         
1805         return local_address.sin_addr.s_addr;
1806 }
1807
1808 // initialize reliable sockets
1809 int psnet_init_rel_tcp(int port, int should_listen)
1810 {
1811         /*
1812         struct sockaddr_in sockaddr;
1813
1814         sockaddr.sin_port = htons((ushort)port);
1815         sockaddr.sin_family = AF_INET; 
1816         unsigned int my_ip;
1817         ml_printf("Setting up reliable sockets.\n");
1818
1819         my_ip = psnet_get_ip();
1820
1821         memcpy(&sockaddr.sin_addr.s_addr, &my_ip, sizeof(uint));        
1822                         
1823         Reliable_UDP_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP );
1824         if(INVALID_SOCKET == Reliable_UDP_socket){
1825                 ml_printf("Unable to create reliable UDP socket -- %d\n", WSAGetLastError() );
1826                 
1827                 return 0;
1828         } else if(bind(Reliable_UDP_socket,(struct sockaddr *)&sockaddr,sizeof(struct sockaddr))!=0){
1829                 ml_printf("Unable to bind reliable socket -- %d\n", WSAGetLastError() );
1830                 
1831                 return 0;
1832         }       
1833         
1834         // make any reliable sockets which we create that aren't listening non-blocking sockets
1835         int error;
1836         unsigned long arg;
1837
1838         arg = TRUE;
1839         error = ioctlsocket( Reliable_UDP_socket, FIONBIO, &arg );
1840         if ( error == SOCKET_ERROR ) {
1841                 ml_printf("Unable to make reliable UDP socket non-blocking -- %d\n", WSAGetLastError() );
1842                 
1843                 return 0;
1844         }
1845         */      
1846
1847         // success
1848         return 1;
1849 }
1850
1851 void psnet_rel_close()
1852 {
1853         int idx;
1854         PSNET_SOCKET_RELIABLE sock;
1855
1856         // kill all sockets
1857         for(idx=0; idx<MAXRELIABLESOCKETS; idx++){
1858                 if(Reliable_sockets[idx].status != RNF_UNUSED){
1859                         sock = idx;
1860                         psnet_rel_close_socket(&sock);
1861                 }
1862         }
1863 }
1864
1865 // ------------------------------------------------------------------------------------------------------
1866 // PACKET BUFFERING FUNCTIONS
1867 //
1868
1869 // initialize the buffering system
1870 void psnet_buffer_init(network_packet_buffer_list *l)
1871 {
1872         int idx;
1873         
1874         // blast the buffer clean
1875         memset(l->psnet_buffers, 0, sizeof(network_packet_buffer) * MAX_PACKET_BUFFERS);
1876         
1877         // set all buffer sequence #'s to -1
1878         for(idx=0;idx<MAX_PACKET_BUFFERS;idx++){                
1879                 l->psnet_buffers[idx].sequence_number = -1;
1880         }
1881
1882         // initialize the sequence #
1883         l->psnet_seq_number = 0;
1884         l->psnet_lowest_id = -1;
1885         l->psnet_highest_id = -1;
1886 }
1887
1888 // buffer a packet (maintain order!)
1889 void psnet_buffer_packet(network_packet_buffer_list *l, ubyte *data, int length, net_addr_t *from)
1890 {
1891         int idx;
1892         int found_buf = 0;
1893         
1894         // find the first empty packet
1895         for(idx=0;idx<MAX_PACKET_BUFFERS;idx++){
1896                 if(l->psnet_buffers[idx].sequence_number == -1){
1897                         found_buf = 1;
1898                         break;
1899                 }
1900         }
1901
1902         // if we didn't find the buffer, report an overrun
1903         if(!found_buf){
1904                 ml_printf("WARNING - Buffer overrun in psnet\n");
1905         } else {
1906                 // copy in the data
1907                 memcpy(l->psnet_buffers[idx].data, data, length);
1908                 l->psnet_buffers[idx].len = length;
1909                 memcpy(&l->psnet_buffers[idx].from_addr, from, sizeof(net_addr_t));
1910                 l->psnet_buffers[idx].sequence_number = l->psnet_seq_number;
1911                 
1912                 // keep track of the highest id#
1913                 l->psnet_highest_id = l->psnet_seq_number++;
1914
1915                 // set the lowest id# for the first time
1916                 if(l->psnet_lowest_id == -1){
1917                         l->psnet_lowest_id = l->psnet_highest_id;
1918                 }
1919         }
1920 }
1921
1922 // get the index of the next packet in order!
1923 int psnet_buffer_get_next(network_packet_buffer_list *l, ubyte *data, int *length, net_addr_t *from)
1924 {       
1925         int idx;
1926
1927         // if there are no buffers, do nothing
1928         if((l->psnet_lowest_id == -1) || (l->psnet_lowest_id > l->psnet_highest_id)){
1929                 return 0;
1930         }
1931
1932         // search until we find the lowest packet index id#
1933         for(idx=0;idx<MAX_PACKET_BUFFERS;idx++){
1934                 // if we found the buffer
1935                 if(l->psnet_buffers[idx].sequence_number == l->psnet_lowest_id){
1936                         break;
1937                 }
1938         }
1939
1940         // at this point, we should _always_ have found the buffer
1941         if (idx == MAX_PACKET_BUFFERS) {
1942                 Int3();
1943                 return 0;
1944         }
1945         
1946         // copy out the buffer data
1947         memcpy(data, l->psnet_buffers[idx].data, l->psnet_buffers[idx].len);
1948         *length = l->psnet_buffers[idx].len;
1949         memcpy(from, &l->psnet_buffers[idx].from_addr, sizeof(net_addr_t));
1950
1951         // now we need to cleanup the packet list
1952
1953         // mark the buffer as free
1954         l->psnet_buffers[idx].sequence_number = -1;
1955         l->psnet_lowest_id++;
1956
1957         return 1;
1958 }
1959
1960 // -------------------------------------------------------------------------------------------------------
1961 // PSNET 2 FORWARD DEFINITIONS
1962 //
1963
1964 // if the string is a legally formatted ip string
1965 int psnet_is_valid_numeric_ip(char *ip)
1966 {
1967         char *token;
1968         char copy[100];
1969         int val1,val2,val3,val4;
1970
1971         // get the first ip value
1972         SDL_strlcpy(copy, ip, SDL_arraysize(copy));
1973         token = strtok(copy,".");
1974         if(token == NULL){
1975                 return 0;
1976         } else {
1977                 // get the value of the token
1978                 val1 = atoi(token);
1979                 if((val1 < 0) || (val1 > 255)){
1980                         return 0;
1981                 }
1982         }
1983
1984         // second ip value
1985         token = strtok(NULL,".");
1986         if(token == NULL){
1987                 return 0;
1988         } else {
1989                 // get the value of the token
1990                 val2 = atoi(token);
1991                 if((val2 < 0) || (val2 > 255)){
1992                         return 0;
1993                 }
1994         }
1995
1996         // third ip value
1997         token = strtok(NULL,".");
1998         if(token == NULL){
1999                 return 0;
2000         } else {
2001                 // get the value of the token
2002                 val3 = atoi(token);
2003                 if((val3 < 0) || (val3 > 255)){
2004                         return 0;
2005                 }
2006         }
2007
2008         // third ip value
2009         token = strtok(NULL,"");
2010         if(token == NULL){
2011                 return 0;
2012         } else {
2013                 // get the value of the token
2014                 val4 = atoi(token);
2015                 if((val4 < 0) || (val4 > 255)){
2016                         return 0;
2017                 }
2018         }
2019
2020         // make sure he hasn't entered all 0's
2021         if((val1 == 0) && (val2 == 0) && (val3 == 0) && (val4 == 0)){
2022                 return 0;
2023         }
2024
2025         // valid
2026         return 1;
2027 }
2028
2029 // function called from high level FreeSpace code to determine the status of the networking
2030 // code returns one of a handful of macros
2031 #ifndef PLAT_UNIX
2032 DWORD (__stdcall *pRasEnumConnections)(LPRASCONN lprasconn, LPDWORD lpcb, LPDWORD lpcConnections) = NULL;
2033 DWORD (__stdcall *pRasGetConnectStatus)(HRASCONN hrasconn, LPRASCONNSTATUS lprasconnstatus ) = NULL;
2034 DWORD (__stdcall *pRasGetProjectionInfo)(HRASCONN hrasconn, RASPROJECTION rasprojection, LPVOID lpprojection, LPDWORD lpcb ) = NULL;
2035
2036 // functions to get the status of a RAS connection
2037 unsigned int psnet_ras_status()
2038 {
2039         int rval;
2040         unsigned long size, num_connections, i;
2041         RASCONN rasbuffer[25];
2042         HINSTANCE ras_handle;
2043         unsigned long rasip=0;
2044         RASPPPIP projection;
2045         // int Ras_connected;
2046
2047         Ras_connected = 0;
2048
2049         // first, call a LoadLibrary to load the RAS api
2050         ras_handle = LoadLibrary( (LPCWSTR)"rasapi32.dll" );
2051         if ( ras_handle == NULL ) {
2052                 return INADDR_ANY;
2053         }
2054
2055         pRasEnumConnections = (DWORD (__stdcall *)(LPRASCONN, LPDWORD, LPDWORD))GetProcAddress(ras_handle, "RasEnumConnectionsA");
2056         if (!pRasEnumConnections)       {
2057                 FreeLibrary( ras_handle );
2058                 return INADDR_ANY;
2059         }
2060         pRasGetConnectStatus = (DWORD (__stdcall *)(HRASCONN, LPRASCONNSTATUS))GetProcAddress(ras_handle, "RasGetConnectStatusA");
2061         if (!pRasGetConnectStatus)      {
2062                 FreeLibrary( ras_handle );
2063                 return INADDR_ANY;
2064         }
2065         pRasGetProjectionInfo = (DWORD (__stdcall *)(HRASCONN, RASPROJECTION, LPVOID, LPDWORD))GetProcAddress(ras_handle, "RasGetProjectionInfoA");
2066         if (!pRasGetProjectionInfo)     {
2067                 FreeLibrary( ras_handle );
2068                 return INADDR_ANY;
2069         }
2070
2071         size = sizeof(rasbuffer);
2072         rasbuffer[0].dwSize = sizeof(RASCONN);
2073
2074         rval = pRasEnumConnections( rasbuffer, &size, &num_connections );
2075         if ( rval ) {
2076                 FreeLibrary( ras_handle );
2077                 return INADDR_ANY;
2078         }
2079
2080         // JAS: My computer gets to this point, but I have no RAS connections,
2081         // so just exit
2082         if ( num_connections < 1 )      {
2083                 ml_string("Found no RAS connections");
2084                 FreeLibrary( ras_handle );
2085                 return INADDR_ANY;
2086         }
2087
2088         ml_printf("Found %d connections", num_connections);
2089
2090         for (i = 0; i < num_connections; i++ ) {
2091                 RASCONNSTATUS status;
2092                 unsigned long size;
2093
2094                 ml_printf("Connection %d:", i);
2095                 ml_printf("Entry Name: %s", rasbuffer[i].szEntryName);
2096                 ml_printf("Device Type: %s", rasbuffer[i].szDeviceType);
2097                 ml_printf("Device Name: %s", rasbuffer[i].szDeviceName);
2098
2099                 // get the connection status
2100                 status.dwSize = sizeof(RASCONNSTATUS);
2101                 rval = pRasGetConnectStatus(rasbuffer[i].hrasconn, &status);
2102                 if ( rval != 0 ) {
2103                         FreeLibrary( ras_handle );
2104                         return INADDR_ANY;
2105                 }
2106
2107                 // get the projection informatiom
2108                 size = sizeof(projection);
2109                 projection.dwSize = size;
2110                 rval = pRasGetProjectionInfo(rasbuffer[i].hrasconn, RASP_PppIp, &projection, &size );
2111                 if ( rval != 0 ) {
2112                         FreeLibrary( ras_handle );
2113                         return INADDR_ANY;
2114                 }
2115
2116                 ml_printf("IP Address: %s", projection.szIpAddress);
2117         }
2118
2119         Ras_connected = 1;
2120
2121         FreeLibrary( ras_handle );
2122         rasip = inet_addr((const char *)projection.szIpAddress);
2123         if(rasip==INADDR_NONE){
2124                 return INADDR_ANY;
2125         }
2126
2127         //The ip of the RAS connection
2128         return rasip;
2129 }
2130 #else
2131 unsigned int psnet_ras_status()
2132 {
2133         STUB_FUNCTION;
2134         
2135         return INADDR_ANY;
2136 }
2137 #endif
2138  
2139 // functions to get the status of a RAS connection
2140 /*
2141 void psnet_ras_status()
2142 {
2143         int rval;
2144         unsigned long size, num_connections, i;
2145         RASCONN rasbuffer[25];
2146         HINSTANCE ras_handle;
2147
2148         Ras_connected = 0;
2149
2150         // first, call a LoadLibrary to load the RAS api
2151         ras_handle = LoadLibrary( NOX("rasapi32.dll") );
2152         if ( ras_handle == NULL ) {
2153                 return;
2154         }
2155
2156         pRasEnumConnections = (DWORD (__stdcall *)(LPRASCONN, LPDWORD, LPDWORD))GetProcAddress(ras_handle, NOX("RasEnumConnectionsA"));
2157         if (!pRasEnumConnections)       {
2158                 FreeLibrary( ras_handle );
2159                 return;
2160         }
2161         pRasGetConnectStatus = (DWORD (__stdcall *)(HRASCONN, LPRASCONNSTATUS))GetProcAddress(ras_handle, NOX("RasGetConnectStatusA"));
2162         if (!pRasGetConnectStatus)      {
2163                 FreeLibrary( ras_handle );
2164                 return;
2165         }
2166         pRasGetProjectionInfo = (DWORD (__stdcall *)(HRASCONN, RASPROJECTION, LPVOID, LPDWORD))GetProcAddress(ras_handle, NOX("RasGetProjectionInfoA"));
2167         if (!pRasGetProjectionInfo)     {
2168                 FreeLibrary( ras_handle );
2169                 return;
2170         }
2171
2172         size = sizeof(rasbuffer);
2173         rasbuffer[0].dwSize = sizeof(RASCONN);
2174
2175         rval = pRasEnumConnections( rasbuffer, &size, &num_connections );
2176         if ( rval ) {
2177                 FreeLibrary( ras_handle );
2178                 return;
2179         }
2180
2181         // JAS: My computer gets to this point, but I have no RAS connections,
2182         // so just exit
2183         if ( num_connections < 1 )      {
2184                 ml_printf("Found no connections\n" ); 
2185                 FreeLibrary( ras_handle );
2186                 return;
2187         }
2188
2189         ml_printf("Found %d connections\n", num_connections);
2190
2191         for (i = 0; i < num_connections; i++ ) {
2192                 RASCONNSTATUS status;
2193                 RASPPPIP projection;
2194                 unsigned long size;
2195
2196                 ml_printf("Connection %d:\n", i);
2197                 ml_printf("Entry Name: %s\n", rasbuffer[i].szEntryName);
2198                 ml_printf("Device Type: %s\n", rasbuffer[i].szDeviceType);
2199                 ml_printf("Device Name: %s\n", rasbuffer[i].szDeviceName);
2200
2201                 // get the connection status
2202                 status.dwSize = sizeof(RASCONNSTATUS);
2203                 rval = pRasGetConnectStatus(rasbuffer[i].hrasconn, &status);
2204                 if ( rval != 0 ) {
2205                         FreeLibrary( ras_handle );
2206                         return;
2207                 }
2208
2209                 ml_printf("\tStatus: %s\n", (status.rasconnstate==RASCS_Connected)?"Connected":"Not Connected");
2210
2211                 // get the projection informatiom
2212                 size = sizeof(projection);
2213                 projection.dwSize = size;
2214                 rval = pRasGetProjectionInfo(rasbuffer[i].hrasconn, RASP_PppIp, &projection, &size );
2215                 if ( rval != 0 ) {
2216                         FreeLibrary( ras_handle );
2217                         return;
2218                 }
2219
2220                 ml_printf("IP Address: %s", projection.szIpAddress));
2221         }
2222
2223         Ras_connected = 1;
2224
2225         FreeLibrary( ras_handle );
2226 }
2227 */
2228
2229 // set some options on a socket
2230 void psnet_socket_options( SOCKET sock )
2231 {
2232         int broadcast;//, ret;
2233 #ifndef PLAT_UNIX
2234         int cursize, cursizesize, bufsize; 
2235 #else
2236         socklen_t cursize, cursizesize, bufsize; 
2237 #endif
2238
2239         // Set the mode of the socket to allow broadcasting
2240         broadcast = 1;
2241         if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast) )){
2242                 Can_broadcast = 0;
2243         } else {
2244                 Can_broadcast = 1;
2245         }
2246
2247         // reuseaddr
2248         // setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&broadcast, sizeof(broadcast) );
2249
2250         // try and increase the size of my receive buffer
2251         bufsize = MAX_RECEIVE_BUFSIZE;
2252         
2253         // set the current size of the receive buffer
2254         cursizesize = sizeof(int);
2255         getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&cursize, &cursizesize);
2256         // for ( trysize = bufsize; trysize >= cursize; trysize >>= 1 ) {
2257         /*ret =*/ setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, sizeof(bufsize));
2258         /*if ( ret == SOCKET_ERROR ) {
2259                 int wserr;
2260
2261                 wserr = WSAGetLastError();
2262                 // if ( (wserr == WSAENOPROTOOPT) || (wserr == WSAEINVAL) )
2263                         // break;
2264         }*/
2265         // }
2266         getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&cursize, &cursizesize);
2267         ml_printf("Receive buffer set to %d\n", cursize);
2268
2269         // set the current size of the send buffer
2270         cursizesize = sizeof(int);
2271         getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&cursize, &cursizesize);
2272         // for ( trysize = bufsize; trysize >= cursize; trysize >>= 1 ) {
2273         /*ret =*/ setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize, sizeof(bufsize));
2274         /*if ( ret == SOCKET_ERROR ) {
2275                 int wserr;
2276
2277                 wserr = WSAGetLastError();
2278                 // if ( (wserr == WSAENOPROTOOPT) || (wserr == WSAEINVAL) ){
2279                         // break;
2280                 // }
2281         }*/
2282         getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&cursize, &cursizesize);
2283         ml_printf("Send buffer set to %d\n", cursize);
2284 }
2285
2286 // initialize tcp socket
2287 int psnet_init_tcp()
2288 {       
2289         struct sockaddr_in sockaddr;
2290
2291         TCP_socket = INVALID_SOCKET;    
2292         
2293         TCP_socket = socket( AF_INET, SOCK_DGRAM, 0 );
2294         if ( TCP_socket == (int)INVALID_SOCKET ) {
2295                 Tcp_failure_code = WSAGetLastError();
2296                 ml_printf("Error on TCP startup %d\n", Tcp_failure_code);
2297                 return 0;
2298         }
2299
2300         // bind the socket
2301         memset(&sockaddr,0,sizeof(struct sockaddr_in));
2302         sockaddr.sin_family = AF_INET; 
2303         sockaddr.sin_addr.s_addr = psnet_get_ip();
2304         sockaddr.sin_port = htons( Psnet_default_port );
2305         if ( bind(TCP_socket, (struct sockaddr*)&sockaddr, sizeof (sockaddr)) == SOCKET_ERROR) {
2306                 Tcp_failure_code = WSAGetLastError();
2307                 ml_printf("Couldn't bind TCP socket (%d)! Invalidating TCP\n", Tcp_failure_code ); 
2308                 return 0;
2309         }
2310
2311         // set socket options
2312         psnet_socket_options( TCP_socket );             
2313         Tcp_can_broadcast = Can_broadcast;
2314
2315         // success
2316         return 1;
2317 }
2318
2319 // get time in seconds
2320 float psnet_get_time()
2321 {               
2322         return (float)timer_get_milliseconds() / 1000.0f;
2323 }
2324
2325 // mark a socket as having received data
2326 void psnet_mark_received(PSNET_SOCKET_RELIABLE socket)
2327 {
2328         // valid socket?
2329         if((socket == 0xffffffff) || (socket >= MAXRELIABLESOCKETS)){
2330                 return;
2331         }
2332
2333         // mark it
2334         Reliable_sockets[socket].last_packet_received = psnet_get_time();
2335 }
2336
2337 #endif  //  if PSNET2
2338