28 #include <sys/types.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <graphlab/logger/assertions.hpp>
33 #include <graphlab/util/net_util.hpp>
37 bool str_to_ip(
const char* c, uint32_t& out) {
38 if (c == NULL)
return false;
39 else return inet_pton(AF_INET, c, &out) > 0;
42 bool ip_to_str(uint32_t ip, std::string& out) {
43 char ipstring[INET_ADDRSTRLEN] = {0};
44 const char* ret = inet_ntop(AF_INET, &ip, ipstring, INET_ADDRSTRLEN);
45 if (ret == NULL)
return false;
46 out = std::string(ipstring);
54 if (ip == 0)
return "127.0.0.1";
57 bool ip_conversion_success = ip_to_str(ip, out);
58 ASSERT_TRUE(ip_conversion_success);
65 char* c_subnet_id = getenv(
"GRAPHLAB_SUBNET_ID");
66 char* c_subnet_mask = getenv(
"GRAPHLAB_SUBNET_MASK");
67 uint32_t subnet_id = 0;
68 uint32_t subnet_mask = 0;
69 std::string str_subnet_id, str_subnet_mask;
71 if (c_subnet_id != NULL) {
72 if (!str_to_ip(c_subnet_id, subnet_id)) {
73 std::cout <<
"Unable to convert GRAPHLAB_SUBNET_ID to a valid address. Cannot continue\n";
77 if (c_subnet_mask != NULL) {
78 if (!str_to_ip(c_subnet_mask, subnet_mask)) {
79 std::cout <<
"Unable to convert GRAPHLAB_SUBNET_MASK to a valid address. Cannot continue\n";
88 if (c_subnet_id == NULL && c_subnet_mask != NULL) {
90 std::cout <<
"GRAPHLAB_SUBNET_MASK specified, but GRAPHLAB_SUBNET_ID not specified.\n";
91 std::cout <<
"We cannot continue\n";
94 if (c_subnet_id != NULL && c_subnet_mask == NULL) {
96 std::cout <<
"GRAPHLAB_SUBNET_ID specified, but GRAPHLAB_SUBNET_MASK not specified.\n";
97 std::cout <<
"We will try to guess a subnet mask\n";
103 subnet_mask = subnet_id;
104 subnet_mask = ntohl(subnet_mask);
105 subnet_mask = subnet_mask | (subnet_mask << 1);
106 subnet_mask = subnet_mask | (subnet_mask << 2);
107 subnet_mask = subnet_mask | (subnet_mask << 4);
108 subnet_mask = subnet_mask | (subnet_mask << 8);
109 subnet_mask = subnet_mask | (subnet_mask << 16);
110 subnet_mask = htonl(subnet_mask);
114 std::cout <<
"GRAPHLAB_SUBNET_ID/GRAPHLAB_SUBNET_MASK environment variables not defined.\n";
115 std::cout <<
"Using default values\n";
118 ip_to_str(subnet_id, str_subnet_id);
119 ip_to_str(subnet_mask, str_subnet_mask);
123 std::cout <<
"Subnet ID: " << str_subnet_id <<
"\n";
124 std::cout <<
"Subnet Mask: " << str_subnet_mask <<
"\n";
125 std::cout <<
"Will find first IPv4 non-loopback address matching the subnet" << std::endl;
129 struct ifaddrs * ifAddrStruct = NULL;
130 getifaddrs(&ifAddrStruct);
131 struct ifaddrs * firstifaddr = ifAddrStruct;
132 ASSERT_NE(ifAddrStruct, NULL);
133 bool success =
false;
134 while (ifAddrStruct != NULL) {
135 if (ifAddrStruct->ifa_addr != NULL &&
136 ifAddrStruct->ifa_addr->sa_family == AF_INET) {
137 char* tmpAddrPtr = NULL;
139 tmpAddrPtr = (
char*)&((
struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
140 ASSERT_NE(tmpAddrPtr, NULL);
141 if (tmpAddrPtr[0] != 127) {
142 memcpy(&ip, tmpAddrPtr, 4);
144 if ((ip & subnet_mask) == subnet_id) {
151 ifAddrStruct=ifAddrStruct->ifa_next;
153 freeifaddrs(firstifaddr);
156 if (c_subnet_id!= NULL) {
157 std::cout <<
"Unable to find a network matching the requested subnet\n";
160 std::cout <<
"Unable to find any valid IPv4 address. Defaulting to loopback\n";
167 int sock = socket(AF_INET, SOCK_STREAM, 0);
170 my_addr.sin_family = AF_INET;
171 my_addr.sin_port = 0;
172 my_addr.sin_addr.s_addr = INADDR_ANY;
173 memset(&(my_addr.sin_zero),
'\0', 8);
174 if (bind(sock, (sockaddr*)&my_addr,
sizeof(my_addr)) < 0){
175 logger(
LOG_FATAL,
"Failed to bind to a port 0! Unable to acquire a free TCP port!");
180 slen =
sizeof(sockaddr);
181 if (getsockname(sock, &addr, &slen) < 0) {
182 logger(
LOG_FATAL,
"Failed to get port information about bound socket");
184 size_t freeport = ntohs(((sockaddr_in*)(&addr))->sin_port);
185 std::pair<size_t, int> ret(freeport, sock);