8 #include "artdaq/DAQdata/Globals.hh"
9 #define TRACE_NAME (app_name + "_TCPConnect").c_str()
11 #include <arpa/inet.h>
13 #include <netinet/in.h>
14 #include <netinet/in.h>
18 #include <sys/socket.h>
19 #include <sys/socket.h>
20 #include <sys/types.h>
24 #include <linux/if_link.h>
36 struct hostent *hostent_sp;
40 if (regex_match(host_in, mm, std::regex(
"([^:]+):(\\d+)")))
44 else if (regex_match(host_in, mm, std::regex(
":{0,1}(\\d+)")))
46 host = std::string(
"127.0.0.1");
48 else if (regex_match(host_in, mm, std::regex(
"([^:]+):{0,1}")))
50 host = mm[1].str().c_str();
54 host = std::string(
"127.0.0.1");
56 TLOG(TLVL_INFO) <<
"Resolving host " << host;
58 bzero((
char *)&addr,
sizeof(addr));
60 if (regex_match(host.c_str(), mm, std::regex(
"\\d+(\\.\\d+){3}")))
61 inet_aton(host.c_str(), &addr);
64 hostent_sp = gethostbyname(host.c_str());
67 perror(
"gethostbyname");
70 addr = *(
struct in_addr *)(hostent_sp->h_addr_list[0]);
79 TLOG(TLVL_INFO) <<
"Finding address for interface " << interface_name;
81 bzero((
char *)&addr,
sizeof(addr));
83 struct ifaddrs *ifaddr, *ifa;
85 if (getifaddrs(&ifaddr) == -1)
94 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
96 if (ifa->ifa_addr == NULL)
101 if (ifa->ifa_addr->sa_family == AF_INET)
103 auto if_addr = (
struct sockaddr_in *)ifa->ifa_addr;
105 TLOG(15) <<
"IF: " << ifa->ifa_name <<
" Desired: " << interface_name <<
" IP: " << if_addr->sin_addr.s_addr;
107 if (std::string(ifa->ifa_name) == interface_name)
109 TLOG(TLVL_INFO) <<
"Interface " << ifa->ifa_name <<
" matches " << interface_name <<
" IP: " << if_addr->sin_addr.s_addr;
110 memcpy(&addr, &if_addr->sin_addr,
sizeof(addr));
117 TLOG(TLVL_WARNING) <<
"No matches for if " << interface_name <<
", using 0.0.0.0";
118 inet_aton(
"0.0.0.0", &addr);
131 bzero((
char *)&addr,
sizeof(addr));
133 struct ifaddrs *ifaddr, *ifa;
135 enum ip_preference :
int
143 struct in_addr addr_192, addr_172, addr_10, addr_131, nm_16, nm_12, nm_8;
144 inet_aton(
"192.168.0.0", &addr_192);
145 inet_aton(
"172.16.0.0", &addr_172);
146 inet_aton(
"10.0.0.0", &addr_10);
147 inet_aton(
"131.225.0.0", &addr_131);
148 inet_aton(
"255.255.0.0", &nm_16);
149 inet_aton(
"255.240.0.0", &nm_12);
150 inet_aton(
"255.0.0.0", &nm_8);
152 std::map<ip_preference, in_addr> preference_map;
154 if (getifaddrs(&ifaddr) == -1)
156 perror(
"getifaddrs");
163 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
165 if (ifa->ifa_addr == NULL)
170 if (ifa->ifa_addr->sa_family == AF_INET)
172 auto if_addr = (
struct sockaddr_in *)ifa->ifa_addr;
174 TLOG(15) <<
"IF: " << ifa->ifa_name <<
" IP: " << if_addr->sin_addr.s_addr;
176 if (preference_map.count(IP_192) == 0 && (if_addr->sin_addr.s_addr & nm_16.s_addr) == addr_192.s_addr)
178 preference_map[IP_192];
179 memcpy(&preference_map[IP_192], &if_addr->sin_addr,
sizeof(addr));
181 else if (preference_map.count(IP_172) == 0 && (if_addr->sin_addr.s_addr & nm_12.s_addr) == addr_172.s_addr)
183 preference_map[IP_172];
184 memcpy(&preference_map[IP_172], &if_addr->sin_addr,
sizeof(addr));
186 else if (preference_map.count(IP_10) == 0 && (if_addr->sin_addr.s_addr & nm_8.s_addr) == addr_10.s_addr)
188 preference_map[IP_10];
189 memcpy(&preference_map[IP_10], &if_addr->sin_addr,
sizeof(addr));
191 else if (preference_map.count(IP_131) == 0 && (if_addr->sin_addr.s_addr & nm_16.s_addr) == addr_131.s_addr)
193 preference_map[IP_131];
194 memcpy(&preference_map[IP_131], &if_addr->sin_addr,
sizeof(addr));
199 if (preference_map.size() == 0)
201 TLOG(TLVL_WARNING) <<
"AutodetectPrivateInterface: No matches, using 0.0.0.0";
202 inet_aton(
"0.0.0.0", &addr);
207 TLOG(TLVL_INFO) <<
"AutodetectPrivateInterface: Using " << inet_ntoa(addr);
208 memcpy(&addr, &preference_map.begin()->second,
sizeof(addr));
220 struct hostent *hostent_sp;
225 if (regex_match(host_in, mm, std::regex(
"([^:]+):(\\d+)")))
229 else if (regex_match(host_in, mm, std::regex(
":{0,1}(\\d+)")))
231 host = std::string(
"127.0.0.1");
233 else if (regex_match(host_in, mm, std::regex(
"([^:]+):{0,1}")))
235 host = mm[1].str().c_str();
239 host = std::string(
"127.0.0.1");
241 TLOG(TLVL_INFO) <<
"Resolving ip " << host;
243 bzero((
char *)&addr,
sizeof(addr));
245 if (regex_match(host.c_str(), mm, std::regex(
"\\d+(\\.\\d+){3}")))
247 in_addr desired_host;
248 inet_aton(host.c_str(), &desired_host);
249 struct ifaddrs *ifaddr, *ifa;
251 if (getifaddrs(&ifaddr) == -1)
253 perror(
"getifaddrs");
260 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
262 if (ifa->ifa_addr == NULL)
267 if (ifa->ifa_addr->sa_family == AF_INET)
269 auto if_addr = (
struct sockaddr_in *)ifa->ifa_addr;
270 auto sa = (
struct sockaddr_in *)ifa->ifa_netmask;
272 TLOG(15) <<
"IF: " << ifa->ifa_name <<
" Desired: " << desired_host.s_addr <<
" netmask: " << sa->sin_addr.s_addr <<
" this interface: " << if_addr->sin_addr.s_addr;
274 if ((if_addr->sin_addr.s_addr & sa->sin_addr.s_addr) == (desired_host.s_addr & sa->sin_addr.s_addr))
276 TLOG(TLVL_INFO) <<
"Using interface " << ifa->ifa_name;
277 memcpy(&addr, &if_addr->sin_addr,
sizeof(addr));
284 if (host != std::string(
"0.0.0.0"))
285 TLOG(TLVL_WARNING) <<
"No matches for ip " << host <<
", using 0.0.0.0";
286 inet_aton(
"0.0.0.0", &addr);
294 hostent_sp = gethostbyname(host.c_str());
297 perror(
"gethostbyname");
300 addr = *(
struct in_addr *)(hostent_sp->h_addr_list[0]);
306 int ResolveHost(
char const *host_in,
int dflt_port, sockaddr_in &sin)
310 struct hostent *hostent_sp;
314 if (regex_match(host_in, mm, std::regex(
"([^:]+):(\\d+)")))
317 port = strtoul(mm[2].str().c_str(), NULL, 0);
319 else if (regex_match(host_in, mm, std::regex(
":{0,1}(\\d+)")))
321 host = std::string(
"127.0.0.1");
322 port = strtoul(mm[1].str().c_str(), NULL, 0);
324 else if (regex_match(host_in, mm, std::regex(
"([^:]+):{0,1}")))
326 host = mm[1].str().c_str();
331 host = std::string(
"127.0.0.1");
334 TLOG(TLVL_INFO) <<
"Resolving host " << host <<
", on port " << port;
336 if (host ==
"localhost") host =
"127.0.0.1";
338 bzero((
char *)&sin,
sizeof(sin));
339 sin.sin_family = AF_INET;
340 sin.sin_port = htons(port);
342 if (regex_match(host.c_str(), mm, std::regex(
"\\d+(\\.\\d+){3}")))
343 inet_aton(host.c_str(), &sin.sin_addr);
346 hostent_sp = gethostbyname(host.c_str());
349 perror(
"gethostbyname");
352 sin.sin_addr = *(
struct in_addr *)(hostent_sp->h_addr_list[0]);
358 int TCPConnect(
char const *host_in,
int dflt_port,
long flags,
int sndbufsiz)
361 struct sockaddr_in sin;
363 s_fd = socket(PF_INET, SOCK_STREAM , 0);
367 perror(
"socket error");
378 sts = connect(s_fd, (
struct sockaddr *)&sin,
sizeof(sin));
388 sts = fcntl(s_fd, F_SETFL, flags);
389 TLOG(TLVL_TRACE) <<
"TCPConnect fcntl(fd=" << s_fd <<
",flags=0x" << std::hex << flags << std::dec <<
") =" << sts;
395 socklen_t lenlen =
sizeof(len);
397 sts = getsockopt(s_fd, SOL_SOCKET, SO_SNDBUF, &len, &lenlen);
398 TLOG(TLVL_DEBUG) <<
"TCPConnect SNDBUF initial: " << len <<
" sts/errno=" << sts <<
"/" << errno <<
" lenlen=" << lenlen;
400 sts = setsockopt(s_fd, SOL_SOCKET, SO_SNDBUF, &len, lenlen);
402 TLOG(TLVL_ERROR) <<
"Error with setsockopt SNDBUF " << errno;
404 sts = getsockopt(s_fd, SOL_SOCKET, SO_SNDBUF, &len, &lenlen);
405 if (len < (sndbufsiz * 2))
406 TLOG(TLVL_WARNING) <<
"SNDBUF " << len <<
" not expected (" << sndbufsiz <<
" sts/errno=" << sts <<
"/" << errno <<
")";
408 TLOG(TLVL_DEBUG) <<
"SNDBUF " << len <<
" sts/errno=" << sts <<
"/" << errno;
int ResolveHost(char const *host_in, in_addr &addr)
Convert a string hostname to a in_addr suitable for socket communication.
int TCPConnect(char const *host_in, int dflt_port, long flags=0, int sndbufsiz=0)
Connect to a host on a given port.
int GetInterfaceForNetwork(char const *host_in, in_addr &addr)
Convert an IP address to the network address of the interface sharing the subnet mask.
int GetIPOfInterface(std::string interface_name, in_addr &addr)
Get the IP address associated with a given interface name.
int AutodetectPrivateInterface(in_addr &addr)
Pick a private IP address on this host.