void host_object::test<7>() { const char* str = "192.168.1.1"; U32 port = 8080, ip; LLHost host; host.set(str,port); ip = ip_string_to_u32(str); ensure("IP address is invalid", (ip == host.getAddress())); ensure("Port Number is invalid", (port == host.getPort())); str = "64.233.187.99"; ip = ip_string_to_u32(str); host.setAddress(str); ensure("IP address is invalid", (ip == host.getAddress())); ip = 0xc098017b; host.setAddress(ip); ensure("IP address is invalid", (ip == host.getAddress())); // should still use the old port ensure("Port Number is invalid", (port == host.getPort())); port = 8084; host.setPort(port); ensure("Port Number is invalid", (port == host.getPort())); // should still use the old address ensure("IP address is invalid", (ip == host.getAddress())); }
void host_object::test<10>() { std::string hostStr = "64.233.167.99"; LLHost host; host.setHostByName(hostStr); ensure("SetHostByName for dotted IP Address failed", host.getAddress() == ip_string_to_u32(hostStr.c_str())); }
LLHost::LLHost(const std::string& ip_and_port) { std::string::size_type colon_index = ip_and_port.find(":"); if (colon_index == std::string::npos) { mIP = ip_string_to_u32(ip_and_port.c_str()); mPort = 0; } else { std::string ip_str(ip_and_port, 0, colon_index); std::string port_str(ip_and_port, colon_index+1); mIP = ip_string_to_u32(ip_str.c_str()); mPort = atol(port_str.c_str()); } }
void host_object::test<3>() { const char* str = "192.168.1.1"; U32 port = 8080; LLHost host(str, port); ensure("IP address could not be processed", (host.getAddress() == ip_string_to_u32(str))); ensure("Port Number is invalid", (port == host.getPort())); }
void host_object::test<4>() { U32 ip = ip_string_to_u32("192.168.1.1"); U32 port = 22; U64 ip_port = (((U64) ip) << 32) | port; LLHost host(ip_port); ensure("IP address is invalid", ip == host.getAddress()); ensure("Port Number is invalid", port == host.getPort()); }
void host_object::test<5>() { std::string ip_port_string = "192.168.1.1:8080"; U32 ip = ip_string_to_u32("192.168.1.1"); U32 port = 8080; LLHost host(ip_port_string); ensure("IP address from IP:port is invalid", ip == host.getAddress()); ensure("Port Number from from IP:port is invalid", port == host.getPort()); }
BOOL LLHost::setHostByName(const std::string& hostname) { hostent *he; std::string local_name(hostname); #if LL_WINDOWS // We may need an equivalent for Linux, but not sure - djs LLStringUtil::toUpper(local_name); #endif he = gethostbyname(local_name.c_str()); if(!he) { U32 ip_address = ip_string_to_u32(hostname.c_str()); he = gethostbyaddr((char *)&ip_address, sizeof(ip_address), AF_INET); } if (he) { mIP = *(U32 *)he->h_addr_list[0]; return TRUE; } else { setAddress(local_name); // In windows, h_errno is a macro for WSAGetLastError(), so store value here S32 error_number = h_errno; switch(error_number) { case TRY_AGAIN: // XXX how to handle this case? llwarns << "LLHost::setAddress(): try again" << llendl; break; case HOST_NOT_FOUND: case NO_ADDRESS: // NO_DATA llwarns << "LLHost::setAddress(): host not found" << llendl; break; case NO_RECOVERY: llwarns << "LLHost::setAddress(): unrecoverable error" << llendl; break; default: llwarns << "LLHost::setAddress(): unknown error - " << error_number << llendl; break; } return FALSE; } }
// Create socket, make non-blocking S32 start_net(S32& socket_out, int& nPort) { int hSocket, nRet; int snd_size = SEND_BUFFER_SIZE; int rec_size = RECEIVE_BUFFER_SIZE; socklen_t buff_size = 4; // Create socket hSocket = socket(AF_INET, SOCK_DGRAM, 0); if (hSocket < 0) { llwarns << "socket() failed" << llendl; return 1; } if (NET_USE_OS_ASSIGNED_PORT == nPort) { // Although bind is not required it will tell us which port we were // assigned to. stLclAddr.sin_family = AF_INET; stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); stLclAddr.sin_port = htons(0); llinfos << "attempting to connect on OS assigned port" << llendl; nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); if (nRet < 0) { llwarns << "Failed to bind on an OS assigned port error: " << nRet << llendl; } else { sockaddr_in socket_info; socklen_t len = sizeof(sockaddr_in); int err = getsockname(hSocket, (sockaddr*)&socket_info, &len); llinfos << "Get socket returned: " << err << " length " << len << llendl; nPort = ntohs(socket_info.sin_port); llinfos << "Assigned port: " << nPort << llendl; } } else { // Name the socket (assign the local port number to receive on) stLclAddr.sin_family = AF_INET; stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); stLclAddr.sin_port = htons(nPort); U32 attempt_port = nPort; llinfos << "attempting to connect on port " << attempt_port << llendl; nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); if (nRet < 0) { // If we got an address in use error... if (errno == EADDRINUSE) { // Try all ports from PORT_DISCOVERY_RANGE_MIN to PORT_DISCOVERY_RANGE_MAX for(attempt_port = PORT_DISCOVERY_RANGE_MIN; attempt_port <= PORT_DISCOVERY_RANGE_MAX; attempt_port++) { stLclAddr.sin_port = htons(attempt_port); llinfos << "trying port " << attempt_port << llendl; nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); if (!((nRet < 0) && (errno == EADDRINUSE))) { break; } } if (nRet < 0) { llwarns << "startNet() : Couldn't find available network port." << llendl; // Fail gracefully in release. return 3; } } // Some other socket error else { llwarns << llformat ("bind() port: %d failed, Err: %s\n", nPort, strerror(errno)) << llendl; // Fail gracefully in release. return 4; } } llinfos << "connected on port " << attempt_port << llendl; nPort = attempt_port; } // Set socket to be non-blocking fcntl(hSocket, F_SETFL, O_NONBLOCK); // set a large receive buffer nRet = setsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, buff_size); if (nRet) { llinfos << "Can't set receive size!" << llendl; } nRet = setsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, buff_size); if (nRet) { llinfos << "Can't set send size!" << llendl; } getsockopt(hSocket, SOL_SOCKET, SO_RCVBUF, (char *)&rec_size, &buff_size); getsockopt(hSocket, SOL_SOCKET, SO_SNDBUF, (char *)&snd_size, &buff_size); llinfos << "startNet - receive buffer size : " << rec_size << llendl; llinfos << "startNet - send buffer size : " << snd_size << llendl; #if LL_LINUX // Turn on recipient address tracking { int use_pktinfo = 1; if( setsockopt( hSocket, SOL_IP, IP_PKTINFO, &use_pktinfo, sizeof(use_pktinfo) ) == -1 ) { llwarns << "No IP_PKTINFO available" << llendl; } else { llinfos << "IP_PKKTINFO enabled" << llendl; } } #endif // Setup a destination address char achMCAddr[MAXADDRSTR] = "127.0.0.1"; /* Flawfinder: ignore */ stDstAddr.sin_family = AF_INET; stDstAddr.sin_addr.s_addr = ip_string_to_u32(achMCAddr); stDstAddr.sin_port = htons(nPort); socket_out = hSocket; return 0; }