OpenMoHAA 0.82.0
Loading...
Searching...
No Matches
gsPlatformSocket.c
1
3#include "gsPlatformSocket.h"
4#include "gsPlatformUtil.h"
5#include "gsMemory.h"
6
7// mj-ToDo: remove these and include the files int the linker instead.
8// removing reference to other platforms.
9// remove all plat specific code from here, move it to the platspecific files.
10
11// Include platform separated functions
12#if defined(_X360)
13 #include "x360/gsSocketX360.c"
14#elif defined(_XBOX)
15 #include "xbox/gsSocketXBox.c"
16#elif defined(_WIN32)
17 #include "win32/gsSocketWin32.c"
18#elif defined(_LINUX)
19 //#include "linux/gsSocketLinux.c"
20#elif defined(_MACOSX)
21 //#include "macosx/gsSocketMacOSX.c"
22#elif defined(_NITRO)
23 #include "nitro/gsSocketNitro.c"
24#elif defined(_PS2)
25 #include "ps2/gsSocketPs2.c"
26#elif defined(_PS3)
27 #include "ps3/gsSocketPs3.c"
28 #include <sys/select.h>
29#elif defined(_PSP)
30 #include "psp/gsSocketPSP.c"
31#elif defined(_REVOLUTION)
32 #include "revolution/gsSocketRevolution.c"
33#else
34 #error "Missing or unsupported platform"
35#endif
36
37
38// Disable compiler warnings for issues that are unavoidable.
40#if defined(_MSC_VER) // DevStudio
41 // Level4, "conditional expression is constant".
42 // Occurs with use of the MS provided macro FD_SET
43 #pragma warning ( disable: 4127 )
44#endif // _MSC_VER
45
46
47
50int SetSockBlocking(SOCKET sock, int isblocking)
51{
52 int rcode;
53
54#if defined(_REVOLUTION)
55 int val;
56
57 val = SOFcntl(sock, SO_F_GETFL, 0);
58
59 if(isblocking)
60 val &= ~SO_O_NONBLOCK;
61 else
62 val |= SO_O_NONBLOCK;
63
64 rcode = SOFcntl(sock, SO_F_SETFL, val);
65#elif defined(_NITRO)
66 int val;
67
68 val = SOC_Fcntl(sock, SOC_F_GETFL, 0);
69
70 if(isblocking)
71 val &= ~SOC_O_NONBLOCK;
72 else
73 val |= SOC_O_NONBLOCK;
74
75 rcode = SOC_Fcntl(sock, SOC_F_SETFL, val);
76#else
77 #if defined(_PS2) || defined(_PS3)
78 // EENet requires int
79 // SNSystems requires int
80 // Insock requires int
81 // PS3 requires int
82 gsi_i32 argp;
83 #else
84 unsigned long argp;
85 #endif
86
87 if(isblocking)
88 argp = 0;
89 else
90 argp = 1;
91
92 #ifdef _PS2
93 #ifdef SN_SYSTEMS
94 rcode = setsockopt(sock, SOL_SOCKET, (isblocking) ? SO_BIO : SO_NBIO, &argp, sizeof(argp));
95 #endif
96
97 #ifdef EENET
98 rcode = setsockopt(sock, SOL_SOCKET, SO_NBIO, &argp, sizeof(argp));
99 #endif
100
101 #ifdef INSOCK
102 if (isblocking)
103 argp = -1;
104 else
105 argp = 5; //added longer timeout to 5ms
106 sceInsockSetRecvTimeout(sock, argp);
107 sceInsockSetSendTimeout(sock, argp);
108 sceInsockSetShutdownTimeout(sock, argp);
109 GSI_UNUSED(sock);
110 rcode = 0;
111 #endif
112 #elif defined(_PSP)
113 rcode = setsockopt(sock, SCE_NET_INET_SOL_SOCKET, SCE_NET_INET_SO_NBIO, &argp, sizeof(argp));
114 #elif defined(_PS3)
115 rcode = setsockopt(sock, SOL_SOCKET, SO_NBIO, &argp, sizeof(argp));
116 #else
117 rcode = ioctlsocket(sock, FIONBIO, &argp);
118 #endif
119#endif
120
121 if(rcode == 0)
122 {
123 gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment,
124 "SetSockBlocking: Set socket %d to %s\r\n", (unsigned int)sock, isblocking ? "blocking":"non-blocking");
125 return 1;
126 }
127
128 gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment,
129 "SetSockBlocking failed: tried to set socket %d to %s\r\n", (unsigned int)sock, isblocking ? "blocking":"non-blocking");
130 return 0;
131}
132
133int SetSockBroadcast(SOCKET sock)
134{
135#if !defined(INSOCK) && !defined(_NITRO) && !defined(_REVOLUTION)
136 int optval = 1;
137 if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0)
138 return 0;
139#else
140 GSI_UNUSED(sock);
141#endif
142
143 return 1;
144}
145
146int DisableNagle(SOCKET sock)
147{
148#if defined(_WIN32) || defined(_UNIX)
149 int rcode;
150 int noDelay = 1;
151
152 rcode = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&noDelay, sizeof(int));
153 return gsiSocketIsError(rcode);
154#else
155 GSI_UNUSED(sock);
156
157 // not supported
158 return 0;
159#endif // moved this to here to silence VC warning
160}
161
162
163#ifndef INSOCK
164 int SetReceiveBufferSize(SOCKET sock, int size)
165 {
166 int rcode;
167 rcode = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (const char *)&size, sizeof(int));
168 return gsiSocketIsNotError(rcode);
169 }
170
171 int SetSendBufferSize(SOCKET sock, int size)
172 {
173 int rcode;
174 rcode = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char *)&size, sizeof(int));
175 return gsiSocketIsNotError(rcode);
176 }
177
178 int GetReceiveBufferSize(SOCKET sock)
179 {
180 int rcode;
181 int size;
182 int len;
183
184 len = sizeof(size);
185
186 rcode = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&size, &len);
187
188 if(gsiSocketIsError(rcode))
189 return -1;
190
191 return size;
192 }
193
194 int GetSendBufferSize(SOCKET sock)
195 {
196 int rcode;
197 int size;
198 int len;
199
200 len = sizeof(size);
201
202 rcode = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&size, &len);
203
204 if(gsiSocketIsError(rcode))
205 return -1;
206
207 return size;
208 }
209
210 // Formerly known as ghiSocketSelect
211#ifdef SN_SYSTEMS
212 #undef FD_SET
213 #define FD_SET(s,p) ((p)->array[((s) - 1) >> SN_FD_SHR] |= \
214 (unsigned int)(1 << (((s) - 1) & SN_FD_BITS)) )
215
216#endif
217#endif
218
219#if !defined(_NITRO) && !defined(INSOCK) && !defined(_REVOLUTION)
220 int GSISocketSelect(SOCKET theSocket, int* theReadFlag, int* theWriteFlag, int* theExceptFlag)
221 {
222 fd_set aReadSet;
223 fd_set aWriteSet;
224 fd_set aExceptSet;
225 fd_set * aReadFds = NULL;
226 fd_set * aWriteFds = NULL;
227 fd_set * aExceptFds = NULL;
228 int aResult;
229// 04-13-2005, Saad Nader
230// Added case for SN Systems that would
231// handle errors after performing selects.
232#ifdef SN_SYSTEMS
233 int aOut, aOutLen = sizeof(aOut);
234#endif
235
236 struct timeval aTimeout = { 0, 0 };
237
238 if (theSocket == INVALID_SOCKET)
239 return -1;
240
241 // Setup the parameters.
243 if(theReadFlag != NULL)
244 {
245 FD_ZERO(&aReadSet);
246 FD_SET(theSocket,&aReadSet);
247 aReadFds = &aReadSet;
248 }
249 if(theWriteFlag != NULL)
250 {
251 FD_ZERO(&aWriteSet);
252 FD_SET(theSocket, &aWriteSet);
253 aWriteFds = &aWriteSet;
254 }
255 if(theExceptFlag != NULL)
256 {
257 FD_ZERO(&aExceptSet);
258 FD_SET(theSocket, &aExceptSet);
259 aExceptFds = &aExceptSet;
260 }
261#ifdef _PS3
262 // to do, port what is below in the else
263//int socketselect(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
264 aResult = socketselect(FD_SETSIZE, aReadFds, aWriteFds, aExceptFds, &aTimeout);
265#else
266 // Perform the select
267 aResult = select(FD_SETSIZE, aReadFds, aWriteFds, aExceptFds, &aTimeout);
268#endif
269 if(gsiSocketIsError(aResult))
270 return -1;
271
272// 04-13-2005, Saad Nader
273// Added case for SN Systems that would
274// handle errors after performing selects.
275#ifdef SN_SYSTEMS
276 getsockopt(theSocket, SOL_SOCKET, SO_ERROR, (char *)&aOut, &aOutLen);
277 if (aOut != 0)
278 {
279 return 0;
280 }
281#endif
282 // Check results.
284 if(theReadFlag != NULL)
285 {
286 if((aResult > 0) && FD_ISSET(theSocket, aReadFds))
287 *theReadFlag = 1;
288 else
289 *theReadFlag = 0;
290 }
291 if(theWriteFlag != NULL)
292 {
293 if((aResult > 0) && FD_ISSET(theSocket, aWriteFds))
294 *theWriteFlag = 1;
295 else
296 *theWriteFlag = 0;
297 }
298 if(theExceptFlag != NULL)
299 {
300 if((aResult > 0) && FD_ISSET(theSocket, aExceptFds))
301 *theExceptFlag = 1;
302 else
303 *theExceptFlag = 0;
304 }
305 return aResult; // 0 or 1 at this point
306 }
307#endif // !nitro && !revolution && !insock
308
309
310// Return 1 for immediate recv, otherwise 0
311int CanReceiveOnSocket(SOCKET sock)
312{
313 int aReadFlag = 0;
314 if (1 == GSISocketSelect(sock, &aReadFlag, NULL, NULL))
315 return aReadFlag;
316
317 // SDKs expect 0 on SOCKET_ERROR
318 return 0;
319}
320
321// Return 1 for immediate send, otherwise 0
322int CanSendOnSocket(SOCKET sock)
323{
324 int aWriteFlag = 0;
325 if (1 == GSISocketSelect(sock, NULL, &aWriteFlag, NULL))
326 return aWriteFlag;
327
328 // SDKs expect 0 on SOCKET_ERROR
329 return 0;
330}
331
332
333#if defined(_PS3) || defined (_PSP)
334
335#else
336
337HOSTENT * getlocalhost(void)
338{
339#ifdef EENET
340 #define MAX_IPS 5
341
342 static HOSTENT localhost;
343 static char * aliases = NULL;
344 static char * ipPtrs[MAX_IPS + 1];
345 static unsigned int ips[MAX_IPS];
346
347 struct sceEENetIfname * interfaces;
348 struct sceEENetIfname * interface;
349 int num;
350 int i;
351 int count;
352 int len;
353 u_short flags;
354 IN_ADDR address;
355
356 // initialize the host
357 localhost.h_name = "localhost";
358 localhost.h_aliases = &aliases;
359 localhost.h_addrtype = AF_INET;
360 localhost.h_length = 0;
361 localhost.h_addr_list = ipPtrs;
362
363 // get the local interfaces
364 sceEENetGetIfnames(NULL, &num);
365 interfaces = (struct sceEENetIfname *)gsimalloc(num * sizeof(struct sceEENetIfname));
366 if(!interfaces)
367 return NULL;
368 sceEENetGetIfnames(interfaces, &num);
369
370 // loop through the interfaces
371 count = 0;
372 for(i = 0 ; i < num ; i++)
373 {
374 // the next interface
375 interface = &interfaces[i];
376 //printf("eenet%d: %s\n", i, interface->ifn_name);
377
378 // get the flags
379 len = sizeof(flags);
380 if(sceEENetGetIfinfo(interface->ifn_name, sceEENET_IFINFO_IFFLAGS, &flags, &len) != 0)
381 continue;
382 //printf("eenet%d flags: 0x%X\n", i, flags);
383
384 // check for up, running, and non-loopback
385 if(!(flags & (IFF_UP|IFF_RUNNING)) || (flags & IFF_LOOPBACK))
386 continue;
387 //printf("eenet%d: up and running, non-loopback\n", i);
388
389 // get the address
390 len = sizeof(address);
391 if(sceEENetGetIfinfo(interface->ifn_name, sceEENET_IFINFO_ADDR, &address, &len) != 0)
392 continue;
393 //printf("eenet%d: %s\n", i, inet_ntoa(address));
394
395 // add this address
396 ips[count] = address.s_addr;
397 ipPtrs[count] = (char *)&ips[count];
398 count++;
399 }
400
401 // free the interfaces
402 gsifree(interfaces);
403
404 // check that we got at least one IP
405 if(!count)
406 return NULL;
407
408 // finish filling in the host struct
409 localhost.h_length = (gsi_u16)sizeof(ips[0]);
410 ipPtrs[count] = NULL;
411
412 return &localhost;
413
415 // INSOCK
416#elif defined(INSOCK)
417 // Global storage
418 #define MAX_IPS sceLIBNET_MAX_INTERFACE
419 static HOSTENT localhost;
420 static char * aliases = NULL;
421 static char * ipPtrs[MAX_IPS + 1];
422 static unsigned int ips[MAX_IPS];
423
424 // Temp storage
425 int aInterfaceIdArray[MAX_IPS];
426 int aNumInterfaces = 0;
427 int aInterfaceNum = 0;
428 int aCount = 0;
429
430 // Get the list of interfaces
431 aNumInterfaces = sceInetGetInterfaceList(&gGSIInsockClientData,
432 &gGSIInsockSocketBuffer, aInterfaceIdArray, MAX_IPS);
433 if (aNumInterfaces < 1)
434 return NULL;
435
436 // initialize the HOSTENT
437 localhost.h_name = "localhost";
438 localhost.h_aliases = &aliases;
439 localhost.h_addrtype = AF_INET;
440 localhost.h_addr_list = ipPtrs;
441
442 // Look up each address and copy into the HOSTENT structure
443 aCount = 0; // count of valid interfaces
444 for (aInterfaceNum = 0; aInterfaceNum < aNumInterfaces; aInterfaceNum++)
445 {
446 sceInetAddress_t anAddr;
447 int result = sceInetInterfaceControl(&gGSIInsockClientData, &gGSIInsockSocketBuffer,
448 aInterfaceIdArray[aInterfaceNum], sceInetCC_GetAddress,
449 &anAddr, sizeof(anAddr));
450 if (result == 0)
451 {
452 // Add this interface to the array
453 memcpy(&ips[aCount], anAddr.data, sizeof(ips[aCount]));
454 ips[aCount] = htonl(ips[aCount]);
455 ipPtrs[aCount] = (char*)&ips[aCount];
456 aCount++;
457 }
458 }
459
460 // Set the final hostent data, then return
461 localhost.h_length = (gsi_u16)sizeof(ips[0]);
462 ipPtrs[aCount] = NULL;
463 return &localhost;
464
465#elif defined(_NITRO)
466 #define MAX_IPS 5
467
468 static HOSTENT localhost;
469 static char * aliases = NULL;
470 static char * ipPtrs[MAX_IPS + 1];
471 static unsigned int ips[MAX_IPS];
472
473 int count = 0;
474
475 localhost.h_name = "localhost";
476 localhost.h_aliases = &aliases;
477 localhost.h_addrtype = AF_INET;
478 localhost.h_length = 0;
479 localhost.h_addr_list = (u8 **)ipPtrs;
480
481 ips[count] = 0;
482 IP_GetAddr(NULL, (u8*)&ips[count]);
483 if(ips[count] == 0)
484 return NULL;
485 ipPtrs[count] = (char *)&ips[count];
486 count++;
487
488 localhost.h_length = (gsi_u16)sizeof(ips[0]);
489 ipPtrs[count] = NULL;
490
491 return &localhost;
492
493#elif defined(_REVOLUTION)
494 #define MAX_IPS 5
495 static HOSTENT aLocalHost;
496 static char * aliases = NULL;
497 int aNumOfIps, i;
498 int aSizeNumOfIps;
499 static IPAddrEntry aAddrs[MAX_IPS];
500 int aAddrsSize, aAddrsSizeInitial;
501 static u8 * ipPtrs[MAX_IPS + 1];
502 static unsigned int ips[MAX_IPS];
503 int ret;
504 aSizeNumOfIps = sizeof(aNumOfIps);
505 ret = SOGetInterfaceOpt(NULL, SO_SOL_CONFIG, SO_CONFIG_IP_ADDR_NUMBER, &aNumOfIps, &aSizeNumOfIps);
506 if (ret != 0)
507 return NULL;
508
509 aAddrsSize = (int)(MAX_IPS * sizeof(IPAddrEntry));
510 aAddrsSizeInitial = aAddrsSize;
511 ret = SOGetInterfaceOpt(NULL, SO_SOL_CONFIG, SO_CONFIG_IP_ADDR_TABLE, &aAddrs, &aAddrsSize);
512 if (ret != 0)
513 return NULL;
514
515 if (aAddrsSize != aAddrsSizeInitial)
516 {
517 aNumOfIps = aAddrsSize / (int)sizeof(IPAddrEntry);
518 }
519
520 aLocalHost.h_name = "localhost";
521 aLocalHost.h_aliases = &aliases;
522 aLocalHost.h_addrtype = AF_INET;
523 aLocalHost.h_length = SO_IP4_ALEN;
524
525 for (i = 0; i < MAX_IPS; i++)
526 {
527 if (i < aNumOfIps)
528 {
529 memcpy(&ips[i], &aAddrs[i].addr, sizeof(aAddrs[i].addr));
530 ipPtrs[i] = (u8 *)&ips[i];
531 }
532 else
533 ipPtrs[i] = NULL;
534 }
535 aLocalHost.h_addr_list = ipPtrs;
536
537 return &aLocalHost;
538
539#elif defined(_X360)
540 XNADDR addr;
541 DWORD rcode;
542 static HOSTENT localhost;
543 static char * ipPtrs[2];
544 static IN_ADDR ip;
545
546 while((rcode = XNetGetTitleXnAddr(&addr)) == XNET_GET_XNADDR_PENDING)
547 msleep(1);
548
549 if((rcode == XNET_GET_XNADDR_NONE) || (rcode == XNET_GET_XNADDR_TROUBLESHOOT))
550 return NULL;
551
552 localhost.h_name = "localhost";
553 localhost.h_aliases = NULL;
554 localhost.h_addrtype = AF_INET;
555 localhost.h_length = (gsi_u16)sizeof(IN_ADDR);
556 localhost.h_addr_list = (gsi_i8 **)ipPtrs;
557
558 ip = addr.ina;
559 ipPtrs[0] = (char *)&ip;
560 ipPtrs[1] = NULL;
561
562 return &localhost;
563
564#elif defined(_XBOX)
565 return NULL;
566
567
568#else
569 char hostname[256] = "";
570
571 // get the local host's name
572 gethostname(hostname, sizeof(hostname));
573
574 // return the host for that name
575 return gethostbyname(hostname);
576#endif
577}
578#endif
579
580int IsPrivateIP(IN_ADDR * addr)
581{
582 int b1;
583 int b2;
584 unsigned int ip;
585
586 // get the first 2 bytes
587 ip = ntohl(addr->s_addr);
588 b1 = (int)((ip >> 24) & 0xFF);
589 b2 = (int)((ip >> 16) & 0xFF);
590
591 // 10.X.X.X
592 if(b1 == 10)
593 return 1;
594
595 // 172.16-31.X.X
596 if((b1 == 172) && ((b2 >= 16) && (b2 <= 31)))
597 return 1;
598
599 // 192.168.X.X
600 if((b1 == 192) && (b2 == 168))
601 return 1;
602
603 return 0;
604}
605
606gsi_u32 gsiGetBroadcastIP(void)
607{
608#if defined(_NITRO)
609 gsi_u32 ip;
610 IP_GetBroadcastAddr(NULL, (u8*)&ip);
611 return ip;
612
613#elif defined(_REVOLUTION)
614 /*
615 int length;
616 gsi_u32 ip;
617
618 length = (gsi_u32)sizeof(ip);
619
620 // IP_GetBroadcastAddr replaced by SOGetInterfaceOpt
621 // IP_GetBroadcastAddr(NULL, (u8*)&ip);
622 SOGetInterfaceOpt(NULL, SO_SOL_IP, SO_INADDR_BROADCAST, (u8*)&ip, &length);
623 */
624 IPAddrEntry* addrtbl;
625 int addrnum;
626 int ret;
627 int length;
628 gsi_u32 ip;
629 length = (int)sizeof( addrnum );
630
631 ret = SOGetInterfaceOpt(NULL,
632 SO_SOL_CONFIG,
633 SO_CONFIG_IP_ADDR_NUMBER,
634 (u8*)&addrnum, &length);
635
636 if( ret >= 0 )
637 return 0xFFFFFFFF;
638
639
640 length = (int)(sizeof( IPAddrEntry ) * addrnum);
641
642 addrtbl = (IPAddrEntry*)gsimalloc( (u32)length );
643
644 if( addrtbl == NULL )
645 return 0xFFFFFFFF;
646
647 ret = SOGetInterfaceOpt(NULL,
648 SO_SOL_CONFIG,
649 SO_CONFIG_IP_ADDR_TABLE,
650 (u8*)addrtbl,
651 &length);
652
653 if( ret < 0 )
654 {
655 gsifree( addrtbl );
656 return 0xFFFFFFFF;
657 }
658
659 ip = (u32)(addrtbl->bcastAddr[3]
660 | (addrtbl->bcastAddr[2] << 8)
661 | (addrtbl->bcastAddr[1] << 16)
662 | (addrtbl->bcastAddr[0] << 24));
663
664 gsifree( addrtbl );
665
666
667 return ip;
668
669 return ip;
670
671#else
672 return 0xFFFFFFFF;
673#endif
674}
675
676
679
680// Re-enable previously disabled compiler warnings
682#if defined(_MSC_VER)
683#pragma warning ( default: 4127 )
684#endif // _MSC_VER
685