void GetMyIP_Windows_Linux_IPV4( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) { int idx = 0; int rns2Socket = socket__(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (rns2Socket >= 0) { // A connected socket is required to get the true ip address // otherwise we are likely to just get 127.0.0.1 // Connect to the public google DNS server sockaddr_in saGoogle; memset(&saGoogle,0,sizeof(sockaddr_in)); saGoogle.sin_family = AF_INET; saGoogle.sin_addr.s_addr=inet_addr__("8.8.8.8"); saGoogle.sin_port = htons(53); connect__(rns2Socket, (const sockaddr*) &saGoogle, sizeof(saGoogle)); sockaddr_in sa; memset(&sa,0,sizeof(sockaddr_in)); socklen_t len = sizeof(sa); getsockname__(rns2Socket, (sockaddr*)&sa, &len); addresses[idx].address.addr4.sin_addr.s_addr=sa.sin_addr.s_addr; idx++; // Disconnect the socket after getting the address memset(&saGoogle,0,sizeof(sockaddr_in)); connect__(rns2Socket, (const sockaddr*) &saGoogle, sizeof(saGoogle)); closesocket__(rns2Socket); } while (idx < MAXIMUM_NUMBER_OF_INTERNAL_IDS) { addresses[idx]=UNASSIGNED_SYSTEM_ADDRESS; idx++; } }
RNS2BindResult RNS2_Berkley::BindSharedIPV4And6( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line ) { (void) file; (void) line; (void) bindParameters; #if RAKNET_SUPPORT_IPV6==1 int ret=0; struct addrinfo hints; struct addrinfo *servinfo=0, *aip; // will point to the results PrepareAddrInfoHints2(&hints); hints.ai_family=bindParameters->addressFamily; char portStr[32]; Itoa(bindParameters->port,portStr,10); // On Ubuntu, "" returns "No address associated with hostname" while 0 works. if (bindParameters->hostAddress && (_stricmp(bindParameters->hostAddress,"UNASSIGNED_SYSTEM_ADDRESS")==0 || bindParameters->hostAddress[0]==0)) { getaddrinfo(0, portStr, &hints, &servinfo); } else { getaddrinfo(bindParameters->hostAddress, portStr, &hints, &servinfo); } // Try all returned addresses until one works for (aip = servinfo; aip != NULL; aip = aip->ai_next) { // Open socket. The address type depends on what // getaddrinfo() gave us. rns2Socket = socket__(aip->ai_family, aip->ai_socktype, aip->ai_protocol); if (rns2Socket == -1) return BR_FAILED_TO_BIND_SOCKET; ret = bind__(rns2Socket, aip->ai_addr, (int) aip->ai_addrlen ); if (ret>=0) { // Is this valid? memcpy(&boundAddress.address.addr6, aip->ai_addr, sizeof(boundAddress.address.addr6)); freeaddrinfo(servinfo); // free the linked-list SetSocketOptions(); SetNonBlockingSocket(bindParameters->nonBlockingSocket); SetBroadcastSocket(bindParameters->setBroadcast); GetSystemAddressIPV4And6( rns2Socket, &boundAddress ); return BR_SUCCESS; } else { closesocket__(rns2Socket); } } return BR_FAILED_TO_BIND_SOCKET; #else return BR_REQUIRES_RAKNET_SUPPORT_IPV6_DEFINE; #endif }
RNS2BindResult RNS2_Berkley::BindSharedIPV4( RNS2_BerkleyBindParameters *bindParameters, const char *file, unsigned int line ) { (void) file; (void) line; int ret; memset(&boundAddress.address.addr4,0,sizeof(sockaddr_in)); boundAddress.address.addr4.sin_port = htons( bindParameters->port ); rns2Socket = (int) socket__( bindParameters->addressFamily, bindParameters->type, bindParameters->protocol ); if (rns2Socket == -1) return BR_FAILED_TO_BIND_SOCKET; SetSocketOptions(); SetNonBlockingSocket(bindParameters->nonBlockingSocket); SetBroadcastSocket(bindParameters->setBroadcast); // Fill in the rest of the address structure boundAddress.address.addr4.sin_family = AF_INET; if (bindParameters->hostAddress && bindParameters->hostAddress[0]) { boundAddress.address.addr4.sin_addr.s_addr = inet_addr__( bindParameters->hostAddress ); } else { // RAKNET_DEBUG_PRINTF("Binding any on port %i\n", port); boundAddress.address.addr4.sin_addr.s_addr = INADDR_ANY; } // bind our name to the socket ret = bind__( rns2Socket, ( struct sockaddr * ) &boundAddress.address.addr4, sizeof( boundAddress.address.addr4 ) ); if ( ret <= -1 ) { #if defined(_WIN32) closesocket__(rns2Socket); return BR_FAILED_TO_BIND_SOCKET; #elif (defined(__GNUC__) || defined(__GCCXML__) ) && !defined(_WIN32) closesocket__(rns2Socket); switch (ret) { case EBADF: RAKNET_DEBUG_PRINTF("bind__(): sockfd is not a valid descriptor.\n"); break; case ENOTSOCK: RAKNET_DEBUG_PRINTF("bind__(): Argument is a descriptor for a file, not a socket.\n"); break; case EINVAL: RAKNET_DEBUG_PRINTF("bind__(): The addrlen is wrong, or the socket was not in the AF_UNIX family.\n"); break; case EROFS: RAKNET_DEBUG_PRINTF("bind__(): The socket inode would reside on a read-only file system.\n"); break; case EFAULT: RAKNET_DEBUG_PRINTF("bind__(): my_addr points outside the user's accessible address space.\n"); break; case ENAMETOOLONG: RAKNET_DEBUG_PRINTF("bind__(): my_addr is too long.\n"); break; case ENOENT: RAKNET_DEBUG_PRINTF("bind__(): The file does not exist.\n"); break; case ENOMEM: RAKNET_DEBUG_PRINTF("bind__(): Insufficient kernel memory was available.\n"); break; case ENOTDIR: RAKNET_DEBUG_PRINTF("bind__(): A component of the path prefix is not a directory.\n"); break; case EACCES: RAKNET_DEBUG_PRINTF("bind__(): Search permission is denied on a component of the path prefix.\n"); break; case ELOOP: RAKNET_DEBUG_PRINTF("bind__(): Too many symbolic links were encountered in resolving my_addr.\n"); break; default: RAKNET_DEBUG_PRINTF("Unknown bind__() error %i.\n", ret); break; } #endif return BR_FAILED_TO_BIND_SOCKET; } GetSystemAddressIPV4(rns2Socket, &boundAddress ); return BR_SUCCESS; }