SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RakNetTypes.cpp
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2019, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
18
19
20 #include "slikenet/types.h"
21 #include "slikenet/assert.h"
22 #include <string.h>
23 #include <stdio.h>
24 #include "slikenet/WindowsIncludes.h"
25 #include "slikenet/WSAStartupSingleton.h"
26 #include "slikenet/SocketDefines.h"
27 #include "slikenet/socket2.h"
28
29
30 #if defined(_WIN32)
31 // extern __int64 _strtoui64(const char*, char**, int); // needed for Code::Blocks. Does not compile on Visual Studio 2010
32 // IP_DONTFRAGMENT is different between winsock 1 and winsock 2. Therefore, Winsock2.h must be linked againt Ws2_32.lib
33 // winsock.h must be linked against WSock32.lib. If these two are mixed up the flag won't work correctly
34 #include "slikenet/WindowsIncludes.h"
35
36 #else
37 #include <sys/socket.h> // used for getnameinfo()
38 #include <netdb.h> // used for getnameinfo()
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
41 #endif
42
43 #include "slikenet/Itoa.h"
44 #include "slikenet/SocketLayer.h"
45 #include "slikenet/SuperFastHash.h"
46 #include <stdlib.h>
47 #include "slikenet/linux_adapter.h"
48 #include "slikenet/osx_adapter.h"
49
50 using namespace SLNet;
51
52 const char *IPV6_LOOPBACK="::1";
53 const char *IPV4_LOOPBACK="127.0.0.1";
54
55 AddressOrGUID::AddressOrGUID( Packet *packet )
56 {
57 rakNetGuid=packet->guid;
58 systemAddress=packet->systemAddress;
59 }
60
61 unsigned long AddressOrGUID::ToInteger( const AddressOrGUID &aog )
62 {
63 if (aog.rakNetGuid!=UNASSIGNED_RAKNET_GUID)
64 return RakNetGUID::ToUint32(aog.rakNetGuid);
65 return SystemAddress::ToInteger(aog.systemAddress);
66 }
67 const char *AddressOrGUID::ToString(bool writePort) const
68 {
69 if (rakNetGuid!=UNASSIGNED_RAKNET_GUID)
70 return rakNetGuid.ToString();
71 return systemAddress.ToString(writePort);
72 }
73 void AddressOrGUID::ToString(bool writePort, char *dest) const
74 {
75 if (rakNetGuid != UNASSIGNED_RAKNET_GUID)
76 return rakNetGuid.ToString(dest);
77 return systemAddress.ToString(writePort, dest);
78 }
79 void AddressOrGUID::ToString(bool writePort, char *dest, size_t destLength) const
80 {
81 if (rakNetGuid!=UNASSIGNED_RAKNET_GUID)
82 return rakNetGuid.ToString(dest,destLength);
83 return systemAddress.ToString(writePort,dest,destLength);
84 }
85 bool SLNet::NonNumericHostString( const char *host )
86 {
87 // Return false if IP address. Return true if domain
88 unsigned int i=0;
89 while (host[i])
90 {
91 // IPV4: natpunch.jenkinssoftware.com
92 // IPV6: fe80::7c:31f7:fec4:27de%14
93 if ((host[i]>='g' && host[i]<='z') ||
94 (host[i]>='G' && host[i]<='Z'))
95 return true;
96 ++i;
97 }
98 return false;
99 }
100
101 SocketDescriptor::SocketDescriptor() {
102 #ifdef __native_client__
103 blockingSocket=false;
104 #else
105 blockingSocket=true;
106 #endif
107 port=0; hostAddress[0]=0; remotePortRakNetWasStartedOn_PS3_PSP2=0; extraSocketOptions=0; socketFamily=AF_INET;}
108 SocketDescriptor::SocketDescriptor(unsigned short _port, const char *_hostAddress)
109 {
110 #ifdef __native_client__
111 blockingSocket=false;
112 #else
113 blockingSocket=true;
114 #endif
115 remotePortRakNetWasStartedOn_PS3_PSP2=0;
116 port=_port;
117 if (_hostAddress)
118 strcpy_s(hostAddress, _hostAddress);
119 else
120 hostAddress[0]=0;
121 extraSocketOptions=0;
122 socketFamily=AF_INET;
123 }
124
125 // Defaults to not in peer to peer mode for NetworkIDs. This only sends the localSystemAddress portion in the BitStream class
126 // This is what you want for client/server, where the server assigns all NetworkIDs and it is unnecessary to transmit the full structure.
127 // For peer to peer, this will transmit the systemAddress of the system that created the object in addition to localSystemAddress. This allows
128 // Any system to create unique ids locally.
129 // All systems must use the same value for this variable.
130 //bool RAK_DLL_EXPORT NetworkID::peerToPeerMode=false;
131
132 SystemAddress& SystemAddress::operator = ( const SystemAddress& input )
133 {
134 memcpy(&address, &input.address, sizeof(address));
135 systemIndex = input.systemIndex;
136 debugPort = input.debugPort;
137 return *this;
138 }
139 bool SystemAddress::EqualsExcludingPort( const SystemAddress& right ) const
140 {
141 return (address.addr4.sin_family==AF_INET && address.addr4.sin_addr.s_addr==right.address.addr4.sin_addr.s_addr)
142 #if RAKNET_SUPPORT_IPV6==1
143 || (address.addr4.sin_family==AF_INET6 && memcmp(address.addr6.sin6_addr.s6_addr, right.address.addr6.sin6_addr.s6_addr, sizeof(address.addr6.sin6_addr.s6_addr))==0)
144 #endif
145 ;
146 }
147 unsigned short SystemAddress::GetPort(void) const
148 {
149 return ntohs(address.addr4.sin_port);
150 }
151 unsigned short SystemAddress::GetPortNetworkOrder(void) const
152 {
153 return address.addr4.sin_port;
154 }
155 void SystemAddress::SetPortHostOrder(unsigned short s)
156 {
157 address.addr4.sin_port=htons(s);
158 debugPort=s;
159 }
160 void SystemAddress::SetPortNetworkOrder(unsigned short s)
161 {
162 address.addr4.sin_port=s;
163 debugPort=ntohs(s);
164 }
165 bool SystemAddress::operator==( const SystemAddress& right ) const
166 {
167 return address.addr4.sin_port == right.address.addr4.sin_port && EqualsExcludingPort(right);
168 }
169
170 bool SystemAddress::operator!=( const SystemAddress& right ) const
171 {
172 return (*this==right)==false;
173 }
174
175 bool SystemAddress::operator>( const SystemAddress& right ) const
176 {
177 if (address.addr4.sin_port == right.address.addr4.sin_port)
178 {
179 #if RAKNET_SUPPORT_IPV6==1
180 if (address.addr4.sin_family==AF_INET)
181 return address.addr4.sin_addr.s_addr>right.address.addr4.sin_addr.s_addr;
182 return memcmp(address.addr6.sin6_addr.s6_addr, right.address.addr6.sin6_addr.s6_addr, sizeof(address.addr6.sin6_addr.s6_addr))>0;
183 #else
184 return address.addr4.sin_addr.s_addr>right.address.addr4.sin_addr.s_addr;
185 #endif
186 }
187 return address.addr4.sin_port>right.address.addr4.sin_port;
188 }
189
190 bool SystemAddress::operator<( const SystemAddress& right ) const
191 {
192 if (address.addr4.sin_port == right.address.addr4.sin_port)
193 {
194 #if RAKNET_SUPPORT_IPV6==1
195 if (address.addr4.sin_family==AF_INET)
196 return address.addr4.sin_addr.s_addr<right.address.addr4.sin_addr.s_addr;
197 return memcmp(address.addr6.sin6_addr.s6_addr, right.address.addr6.sin6_addr.s6_addr, sizeof(address.addr6.sin6_addr.s6_addr))>0;
198 #else
199 return address.addr4.sin_addr.s_addr<right.address.addr4.sin_addr.s_addr;
200 #endif
201 }
202 return address.addr4.sin_port<right.address.addr4.sin_port;
203 }
204 int SystemAddress::size(void)
205 {
206 #if RAKNET_SUPPORT_IPV6==1
207 return sizeof(sockaddr_in6) + sizeof(char);
208 #else
209 return sizeof(uint32_t) + sizeof(unsigned short) + sizeof(char);
210 #endif
211 }
212 unsigned long SystemAddress::ToInteger( const SystemAddress &sa )
213 {
214 unsigned int lastHash = SuperFastHashIncremental ((const char*) & sa.address.addr4.sin_port, sizeof(sa.address.addr4.sin_port), sizeof(sa.address.addr4.sin_port) );
215 #if RAKNET_SUPPORT_IPV6==1
216 if (sa.address.addr4.sin_family==AF_INET)
217 return SuperFastHashIncremental ((const char*) & sa.address.addr4.sin_addr.s_addr, sizeof(sa.address.addr4.sin_addr.s_addr), lastHash );
218 else
219 return SuperFastHashIncremental ((const char*) & sa.address.addr6.sin6_addr.s6_addr, sizeof(sa.address.addr6.sin6_addr.s6_addr), lastHash );
220 #else
221 return SuperFastHashIncremental ((const char*) & sa.address.addr4.sin_addr.s_addr, sizeof(sa.address.addr4.sin_addr.s_addr), lastHash );
222 #endif
223 }
224 unsigned char SystemAddress::GetIPVersion(void) const
225 {
226 if (address.addr4.sin_family==AF_INET)
227 return 4;
228 return 6;
229 }
230 unsigned int SystemAddress::GetIPPROTO(void) const
231 {
232 #if RAKNET_SUPPORT_IPV6==1
233 if (address.addr4.sin_family==AF_INET)
234 return IPPROTO_IP;
235 return IPPROTO_IPV6;
236 #else
237 return IPPROTO_IP;
238 #endif
239 }
240 void SystemAddress::SetToLoopback(void)
241 {
242 SetToLoopback(GetIPVersion());
243 }
244 void SystemAddress::SetToLoopback(unsigned char ipVersion)
245 {
246 if (ipVersion==4)
247 {
248 FromString(IPV4_LOOPBACK, 0, ipVersion);
249 }
250 else
251 {
252 FromString(IPV6_LOOPBACK, 0, ipVersion);
253 }
254 }
255 bool SystemAddress::IsLoopback(void) const
256 {
257 if (GetIPVersion()==4)
258 {
259 // unsigned long l = htonl(address.addr4.sin_addr.s_addr);
260 if (htonl(address.addr4.sin_addr.s_addr)==2130706433)
261 return true;
262 if (address.addr4.sin_addr.s_addr==0)
263 return true;
264 }
265 #if RAKNET_SUPPORT_IPV6==1
266 else
267 {
268 const static char localhost[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
269 if (memcmp(&address.addr6.sin6_addr, localhost, 16)==0)
270 return true;
271 }
272 #endif
273 return false;
274 }
275 void SystemAddress::ToString_Old(bool writePort, char *dest, char portDelineator) const
276 {
277 if (*this == UNASSIGNED_SYSTEM_ADDRESS)
278 {
279 #pragma warning(push)
280 #pragma warning(disable:4996)
281 strcpy(dest, "UNASSIGNED_SYSTEM_ADDRESS");
282 #pragma warning(pop)
283 return;
284 }
285
286 char portStr[2];
287 portStr[0] = portDelineator;
288 portStr[1] = 0;
289
290 in_addr in;
291 in.s_addr = address.addr4.sin_addr.s_addr;
292 char buf[1024];
293 inet_ntop(AF_INET, &in, buf, 1024);
294 #pragma warning(push)
295 #pragma warning(disable:4996)
296 strcpy(dest, buf);
297 #pragma warning(pop)
298 if (writePort)
299 {
300 #pragma warning(push)
301 #pragma warning(disable:4996)
302 strcat(dest, portStr);
303 #pragma warning(pop)
304 Itoa(GetPort(), dest + strlen(dest), 10);
305 }
306 }
307
308 void SystemAddress::ToString_Old(bool writePort, char *dest, size_t destLength, char portDelineator) const
309 {
310 if (*this==UNASSIGNED_SYSTEM_ADDRESS)
311 {
312 strcpy_s(dest, destLength, "UNASSIGNED_SYSTEM_ADDRESS");
313 return;
314 }
315
316 char portStr[2];
317 portStr[0]=portDelineator;
318 portStr[1]=0;
319
320 in_addr in;
321 in.s_addr = address.addr4.sin_addr.s_addr;
322 inet_ntop(AF_INET, &in, dest, destLength);
323 if (writePort)
324 {
325 strcat_s(dest, destLength, portStr);
326 Itoa(GetPort(), dest+strlen(dest), 10);
327 }
328
329 }
330 const char *SystemAddress::ToString(bool writePort, char portDelineator) const
331 {
332 static unsigned char strIndex=0;
333 #if RAKNET_SUPPORT_IPV6==1
334 static const size_t strLength=INET6_ADDRSTRLEN+5+1;
335 #else
336 static const size_t strLength=22+5+1;
337 #endif
338 static char str[8][strLength];
339
340 unsigned char lastStrIndex=strIndex;
341 strIndex++;
342 ToString(writePort, str[lastStrIndex&7], strLength, portDelineator);
343 return (char*) str[lastStrIndex&7];
344 }
345 #if RAKNET_SUPPORT_IPV6==1
346 void SystemAddress::ToString_New(bool writePort, char *dest, char portDelineator) const
347 {
348 int ret;
349 (void)ret;
350
351 if (*this == UNASSIGNED_SYSTEM_ADDRESS)
352 {
353 #pragma warning(push)
354 #pragma warning(disable:4996)
355 strcpy(dest, "UNASSIGNED_SYSTEM_ADDRESS");
356 #pragma warning(pop)
357 return;
358 }
359
360 if (address.addr4.sin_family == AF_INET)
361 {
362 ret = getnameinfo((struct sockaddr *) &address.addr4, sizeof(struct sockaddr_in), dest, 22, NULL, 0, NI_NUMERICHOST);
363 }
364 else
365 {
366 ret = getnameinfo((struct sockaddr *) &address.addr6, sizeof(struct sockaddr_in6), dest, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
367 }
368 if (ret != 0)
369 {
370 dest[0] = 0;
371 }
372
373 if (writePort)
374 {
375 unsigned char ch[2];
376 ch[0] = portDelineator;
377 ch[1] = 0;
378 #pragma warning(push)
379 #pragma warning(disable:4996)
380 strcat(dest, (const char*)ch);
381 #pragma warning(pop)
382 Itoa(ntohs(address.addr4.sin_port), dest + strlen(dest), 10);
383 }
384 }
385 void SystemAddress::ToString_New(bool writePort, char *dest, size_t destLength, char portDelineator) const
386 {
387 int ret;
388 (void) ret;
389
390 if (*this==UNASSIGNED_SYSTEM_ADDRESS)
391 {
392 strcpy_s(dest, destLength, "UNASSIGNED_SYSTEM_ADDRESS");
393 return;
394 }
395
396 if (address.addr4.sin_family==AF_INET)
397 {
398 ret=getnameinfo((struct sockaddr *) &address.addr4, sizeof(struct sockaddr_in), dest, 22, NULL, 0, NI_NUMERICHOST);
399 }
400 else
401 {
402 ret=getnameinfo((struct sockaddr *) &address.addr6, sizeof(struct sockaddr_in6), dest, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
403 }
404 if (ret!=0)
405 {
406 dest[0]=0;
407 }
408
409 if (writePort)
410 {
411 unsigned char ch[2];
412 ch[0]=portDelineator;
413 ch[1]=0;
414 strcat_s(dest, destLength, (const char*) ch);
415 Itoa(ntohs(address.addr4.sin_port), dest+strlen(dest), 10);
416 }
417 }
418 #endif // #if RAKNET_SUPPORT_IPV6!=1
419 void SystemAddress::ToString(bool writePort, char *dest, char portDelineator) const
420 {
421 #if RAKNET_SUPPORT_IPV6!=1
422 ToString_Old(writePort, dest, portDelineator);
423 #else
424 ToString_New(writePort, dest, portDelineator);
425 #endif // #if RAKNET_SUPPORT_IPV6!=1
426 }
427 void SystemAddress::ToString(bool writePort, char *dest, size_t destLength, char portDelineator) const
428 {
429
430 #if RAKNET_SUPPORT_IPV6!=1
431 ToString_Old(writePort,dest,destLength,portDelineator);
432 #else
433 ToString_New(writePort,dest,destLength,portDelineator);
434 #endif // #if RAKNET_SUPPORT_IPV6!=1
435 }
436 SystemAddress::SystemAddress()
437 {
438 address.addr4.sin_family=AF_INET;
439 // used for operator ==
440 memset(&address,0,sizeof(address)); address.addr4.sin_family=AF_INET;
441 systemIndex=(SystemIndex)-1;
442 debugPort=0;
443 }
444 SystemAddress::SystemAddress(const char *str)
445 {
446 address.addr4.sin_family=AF_INET;
447 SetPortHostOrder(0);
448 FromString(str);
449 systemIndex=(SystemIndex)-1;
450 }
451 SystemAddress::SystemAddress(const char *str, unsigned short port)
452 {
453 address.addr4.sin_family=AF_INET;
454 FromStringExplicitPort(str,port);
455 systemIndex=(SystemIndex)-1;
456 }
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495 void SystemAddress::FixForIPVersion(const SystemAddress &boundAddressToSocket)
496 {
497 char str[128];
498 ToString(false,str,static_cast<size_t>(128));
499 // TODO - what about 255.255.255.255?
500 if (strcmp(str, IPV6_LOOPBACK)==0)
501 {
502 if (boundAddressToSocket.GetIPVersion()==4)
503 {
504 FromString(IPV4_LOOPBACK,0,4);
505 }
506 }
507 else if (strcmp(str, IPV4_LOOPBACK)==0)
508 {
509 #if RAKNET_SUPPORT_IPV6==1
510 if (boundAddressToSocket.GetIPVersion()==6)
511 {
512 FromString(IPV6_LOOPBACK,0,6);
513 }
514 #endif
515
516 // if (boundAddressToSocket.GetIPVersion()==4)
517 // {
518 // // Some kind of bug with sendto: returns "The requested address is not valid in its context." if loopback doesn't have the same IP address
519 // address.addr4.sin_addr.s_addr=boundAddressToSocket.address.addr4.sin_addr.s_addr;
520 // }
521 }
522 }
523 bool SystemAddress::IsLANAddress(void)
524 {
525 // return address.addr4.sin_addr.S_un.S_un_b.s_b1==10 || address.addr4.sin_addr.S_un.s_b1==192;
526 #if defined(__WIN32__)
527 return address.addr4.sin_addr.S_un.S_un_b.s_b1==10 || address.addr4.sin_addr.S_un.S_un_b.s_b1==192;
528 #else
529 return (address.addr4.sin_addr.s_addr >> 24) == 10 || (address.addr4.sin_addr.s_addr >> 24) == 192;
530 #endif
531 }
532 bool SystemAddress::SetBinaryAddress(const char *str, char portDelineator)
533 {
534 size_t delimiterPos = 0;
535 size_t stringLength = strlen(str);
536 for (; delimiterPos < stringLength; ++delimiterPos) {
537 if (str[delimiterPos] == portDelineator) {
538 break; // found location of port delimiter
539 }
540 }
541
542 if (NonNumericHostString(str)) {
543 //const char *ip = ( char* ) SocketLayer::DomainNameToIP( str );
544 char ip[65];
545 ip[0]=0;
546
547 // copy the plain hostname (excluding the (optional) port part)
548 // #med - change OP_NEW_ARRAY to support size_t type
549 char* hostname = OP_NEW_ARRAY<char>(static_cast<int>(delimiterPos + 1), _FILE_AND_LINE_);
550 strncpy_s(hostname, delimiterPos + 1, str, delimiterPos);
551 RakNetSocket2::DomainNameToIP(hostname, ip);
552 OP_DELETE_ARRAY(hostname, _FILE_AND_LINE_);
553
554 if (ip[0] != '\0') {
555 inet_pton(AF_INET, ip, &address.addr4.sin_addr.s_addr);
556 }
557 else {
558 *this = UNASSIGNED_SYSTEM_ADDRESS;
559 return false;
560 }
561 }
562 else {
563 // Split the string into the first part, and the : part
564 char IPPart[22];
565 // Only write the valid parts, don't change existing if invalid
566 // binaryAddress=UNASSIGNED_SYSTEM_ADDRESS.binaryAddress;
567 // port=UNASSIGNED_SYSTEM_ADDRESS.port;
568 size_t index = 0;
569 // #med - revise this --- if the hostname length > 22 we'd reject it rather than skipping what is beyond the max length...
570 for (; index < delimiterPos && index < 22; ++index) {
571 if (str[index]!='.' && (str[index]<'0' || str[index]>'9')) {
572 break;
573 }
574 IPPart[index]=str[index];
575 }
576 IPPart[index]=0;
577 if (index > 0) {
578 inet_pton(AF_INET, IPPart, &address.addr4.sin_addr.s_addr);
579 }
580 }
581
582 char portPart[10];
583 portPart[0] = '\0';
584 if (str[delimiterPos] != '\0') {
585 size_t portIndex;
586 ++delimiterPos; // skip the delimiter
587 for (portIndex = 0; portIndex < 10 && str[delimiterPos] != '\0'; ++delimiterPos, ++portIndex) {
588 if (str[delimiterPos] < '0' || str[delimiterPos] > '9') {
589 break;
590 }
591
592 portPart[portIndex] = str[delimiterPos];
593 }
594 portPart[portIndex] = '\0';
595 }
596 if (portPart[0] != '\0') {
597 // #med - missing / insufficient port range range
598 address.addr4.sin_port = htons((unsigned short)atoi(portPart));
599 // #med - not set in IPv6 mode
600 debugPort = ntohs(address.addr4.sin_port);
601 }
602 return true;
603 }
604
605 bool SystemAddress::FromString(const char *str, char portDelineator, int ipVersion)
606 {
607 #if RAKNET_SUPPORT_IPV6!=1
608 (void) ipVersion;
609 return SetBinaryAddress(str,portDelineator);
610 #else
611 if (str==0)
612 {
613 memset(&address,0,sizeof(address));
614 address.addr4.sin_family=AF_INET;
615 return true;
616 }
617 #if RAKNET_SUPPORT_IPV6==1
618 char ipPart[INET6_ADDRSTRLEN];
619 #else
620 char ipPart[INET_ADDRSTRLEN];
621 #endif
622 char portPart[32];
623
624 // TODO - what about 255.255.255.255?
625 if (ipVersion==4 && strcmp(str, IPV6_LOOPBACK)==0)
626 {
627 strcpy_s(ipPart,IPV4_LOOPBACK);
628 }
629 else if (ipVersion==6 && strcmp(str, IPV4_LOOPBACK)==0)
630 {
631 address.addr4.sin_family=AF_INET6;
632 strcpy_s(ipPart,IPV6_LOOPBACK);
633 }
634
635 int i = 0;
636 for (; i < sizeof(ipPart) && str[i] != '\0'; ++i) {
637 if (str[i] == portDelineator) {
638 // #med - missing error checking, if portPart is non-numeric and/or exceeds max allowed port value
639 int j = 0;
640 ++i; // skip the delimiter
641 for (; j < sizeof(portPart) && str[i] != '\0'; ++i, ++j) {
642 portPart[j] = str[i];
643 }
644 portPart[j] = '\0';
645 i = i - j - 1; // reset the position to the last position, so the trailing '\0'-terminator is set correctly below
646 break;
647 }
648 ipPart[i] = str[i];
649 }
650 ipPart[i] = '\0';
651
652 // needed for getaddrinfo
653 WSAStartupSingleton::AddRef();
654
655 // This could be a domain, or a printable address such as "192.0.2.1" or "2001:db8:63b3:1::3490"
656 // I want to convert it to its binary representation
657 addrinfo hints, *servinfo=0;
658 memset(&hints, 0, sizeof hints);
659 hints.ai_socktype = SOCK_DGRAM;
660 if (ipVersion==6)
661 hints.ai_family = AF_INET6;
662 else if (ipVersion==4)
663 hints.ai_family = AF_INET;
664 else
665 hints.ai_family = AF_UNSPEC;
666 getaddrinfo(ipPart, "", &hints, &servinfo);
667 if (servinfo==0)
668 {
669 if (ipVersion==6)
670 {
671 ipVersion=4;
672 hints.ai_family = AF_UNSPEC;
673 getaddrinfo(ipPart, "", &hints, &servinfo);
674 if (servinfo==0)
675 return false;
676 }
677 else
678 return false;
679 }
680 RakAssert(servinfo);
681
682 unsigned short oldPort = address.addr4.sin_port;
683 #if RAKNET_SUPPORT_IPV6==1
684 if (servinfo->ai_family == AF_INET)
685 {
686 // if (ipVersion==6)
687 // {
688 // address.addr4.sin_family=AF_INET6;
689 // memset(&address.addr6,0,sizeof(address.addr6));
690 // memcpy(address.addr6.sin6_addr.s6_addr+12,&((struct sockaddr_in *)servinfo->ai_addr)->sin_addr.s_addr,sizeof(unsigned long));
691 // }
692 // else
693 // {
694 address.addr4.sin_family=AF_INET;
695 memcpy(&address.addr4, (struct sockaddr_in *)servinfo->ai_addr,sizeof(struct sockaddr_in));
696 // }
697 }
698 else
699 {
700 address.addr4.sin_family=AF_INET6;
701 memcpy(&address.addr6, (struct sockaddr_in6 *)servinfo->ai_addr,sizeof(struct sockaddr_in6));
702 }
703 #else
704 address.addr4.sin_family=AF_INET4;
705 memcpy(&address.addr4, (struct sockaddr_in *)servinfo->ai_addr,sizeof(struct sockaddr_in));
706 #endif
707
708 freeaddrinfo(servinfo); // free the linked list
709
710 // needed for getaddrinfo
711 WSAStartupSingleton::Deref();
712
713 // PORT
714 if (portPart[0])
715 {
716 address.addr4.sin_port=htons((unsigned short) atoi(portPart));
717 debugPort=ntohs(address.addr4.sin_port);
718 }
719 else
720 {
721 address.addr4.sin_port=oldPort;
722 }
723
724 return true;
725 #endif // #if RAKNET_SUPPORT_IPV6!=1
726 }
727 bool SystemAddress::FromStringExplicitPort(const char *str, unsigned short port, int ipVersion)
728 {
729 bool b = FromString(str,(char) 0,ipVersion);
730 if (b==false)
731 {
732 *this=UNASSIGNED_SYSTEM_ADDRESS;
733 return false;
734 }
735 address.addr4.sin_port=htons(port);
736 debugPort=ntohs(address.addr4.sin_port);
737 return true;
738 }
739 void SystemAddress::CopyPort( const SystemAddress& right )
740 {
741 address.addr4.sin_port=right.address.addr4.sin_port;
742 debugPort=right.debugPort;
743 }
744 RakNetGUID::RakNetGUID()
745 {
746 systemIndex=(SystemIndex)-1;
747 *this=UNASSIGNED_RAKNET_GUID;
748 }
749 bool RakNetGUID::operator==( const RakNetGUID& right ) const
750 {
751 return g==right.g;
752 }
753 bool RakNetGUID::operator!=( const RakNetGUID& right ) const
754 {
755 return g!=right.g;
756 }
757 bool RakNetGUID::operator > ( const RakNetGUID& right ) const
758 {
759 return g > right.g;
760 }
761 bool RakNetGUID::operator < ( const RakNetGUID& right ) const
762 {
763 return g < right.g;
764 }
765 const char *RakNetGUID::ToString(void) const
766 {
767 static unsigned char strIndex=0;
768 static char str[8][64];
769
770 unsigned char lastStrIndex=strIndex;
771 strIndex++;
772 ToString(str[lastStrIndex&7], 64);
773 return (char*) str[lastStrIndex&7];
774 }
775 void RakNetGUID::ToString(char *dest) const
776 {
777 if (*this == UNASSIGNED_RAKNET_GUID)
778 #pragma warning(push)
779 #pragma warning(disable:4996)
780 strcpy(dest, "UNASSIGNED_RAKNET_GUID");
781 #pragma warning(pop)
782 else
783 //sprintf_s(dest, destLength, "%u.%u.%u.%u.%u.%u", g[0], g[1], g[2], g[3], g[4], g[5]);
784 #pragma warning(push)
785 #pragma warning(disable:4996)
786 sprintf(dest, "%" PRINTF_64_BIT_MODIFIER "u", (long long unsigned int) g);
787 #pragma warning(pop)
788 // sprintf_s(dest, destLength, "%u.%u.%u.%u.%u.%u", g[0], g[1], g[2], g[3], g[4], g[5]);
789 }
790 void RakNetGUID::ToString(char *dest, size_t destLength) const
791 {
792 if (*this==UNASSIGNED_RAKNET_GUID)
793 strcpy_s(dest, destLength, "UNASSIGNED_RAKNET_GUID");
794 else
795 //sprintf_s(dest, destLength, "%u.%u.%u.%u.%u.%u", g[0], g[1], g[2], g[3], g[4], g[5]);
796 sprintf_s(dest, destLength, "%" PRINTF_64_BIT_MODIFIER "u", (long long unsigned int) g);
797 // sprintf_s(dest, destLength, "%u.%u.%u.%u.%u.%u", g[0], g[1], g[2], g[3], g[4], g[5]);
798 }
799 bool RakNetGUID::FromString(const char *source)
800 {
801 if (source==0)
802 return false;
803
804
805
806 #if defined(WIN32)
807 g=_strtoui64(source, NULL, 10);
808
809
810 #else
811 // Changed from g=strtoull(source,0,10); for android
812 g=strtoull(source, (char **)NULL, 10);
813 #endif
814 return true;
815
816 }
817 unsigned long RakNetGUID::ToUint32( const RakNetGUID &g )
818 {
819 return ((unsigned long) (g.g >> 32)) ^ ((unsigned long) (g.g & 0xFFFFFFFF));
820 }