8 #define TRACE_NAME "TCPConnect"
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
23 #include <linux/if_link.h>
28 #include "artdaq/DAQdata/Globals.hh"
35 struct hostent* hostent_sp;
39 if (regex_match(host_in, mm, std::regex(
"([^:]+):(\\d+)")))
43 else if (regex_match(host_in, mm, std::regex(
":{0,1}(\\d+)")))
45 host = std::string(
"127.0.0.1");
47 else if (regex_match(host_in, mm, std::regex(
"([^:]+):{0,1}")))
49 host = mm[1].str().c_str();
53 host = std::string(
"127.0.0.1");
55 TLOG(TLVL_INFO) <<
"Resolving host " << host;
57 bzero((
char *)&addr,
sizeof(addr));
59 if (regex_match(host.c_str(), mm, std::regex(
"\\d+(\\.\\d+){3}")))
60 inet_aton(host.c_str(), &addr);
63 hostent_sp = gethostbyname(host.c_str());
66 perror(
"gethostbyname");
69 addr = *(
struct in_addr *)(hostent_sp->h_addr_list[0]);
78 struct hostent* hostent_sp;
83 if (regex_match(host_in, mm, std::regex(
"([^:]+):(\\d+)")))
87 else if (regex_match(host_in, mm, std::regex(
":{0,1}(\\d+)")))
89 host = std::string(
"127.0.0.1");
91 else if (regex_match(host_in, mm, std::regex(
"([^:]+):{0,1}")))
93 host = mm[1].str().c_str();
97 host = std::string(
"127.0.0.1");
99 TLOG(TLVL_INFO) <<
"Resolving ip " << host;
101 bzero((
char *)&addr,
sizeof(addr));
103 if (regex_match(host.c_str(), mm, std::regex(
"\\d+(\\.\\d+){3}")))
105 in_addr desired_host;
106 inet_aton(host.c_str(), &desired_host);
107 struct ifaddrs *ifaddr, *ifa;
109 if (getifaddrs(&ifaddr) == -1)
111 perror(
"getifaddrs");
118 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
120 if (ifa->ifa_addr == NULL)
125 if (ifa->ifa_addr->sa_family == AF_INET)
127 auto if_addr = (
struct sockaddr_in*) ifa->ifa_addr;
128 auto sa = (
struct sockaddr_in *) ifa->ifa_netmask;
130 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;
132 if ((if_addr->sin_addr.s_addr & sa->sin_addr.s_addr) == (desired_host.s_addr & sa->sin_addr.s_addr))
134 TLOG(TLVL_INFO) <<
"Using interface " << ifa->ifa_name;
135 memcpy(&addr, &if_addr->sin_addr,
sizeof(addr));
142 TLOG(TLVL_WARNING) <<
"No matches for ip " << host <<
", using 0.0.0.0";
143 inet_aton(
"0.0.0.0", &addr);
151 hostent_sp = gethostbyname(host.c_str());
154 perror(
"gethostbyname");
157 addr = *(
struct in_addr *)(hostent_sp->h_addr_list[0]);
163 int ResolveHost(
char const* host_in,
int dflt_port, sockaddr_in& sin)
167 struct hostent* hostent_sp;
171 if (regex_match(host_in, mm, std::regex(
"([^:]+):(\\d+)")))
174 port = strtoul(mm[2].str().c_str(), NULL, 0);
176 else if (regex_match(host_in, mm, std::regex(
":{0,1}(\\d+)")))
178 host = std::string(
"127.0.0.1");
179 port = strtoul(mm[1].str().c_str(), NULL, 0);
181 else if (regex_match(host_in, mm, std::regex(
"([^:]+):{0,1}")))
183 host = mm[1].str().c_str();
188 host = std::string(
"127.0.0.1");
191 TLOG(TLVL_INFO) <<
"Resolving host " << host <<
", on port " << std::to_string(port);
193 if (host ==
"localhost") host =
"127.0.0.1";
195 bzero((
char *)&sin,
sizeof(sin));
196 sin.sin_family = AF_INET;
197 sin.sin_port = htons(port);
199 if (regex_match(host.c_str(), mm, std::regex(
"\\d+(\\.\\d+){3}")))
200 inet_aton(host.c_str(), &sin.sin_addr);
203 hostent_sp = gethostbyname(host.c_str());
206 perror(
"gethostbyname");
209 sin.sin_addr = *(
struct in_addr *)(hostent_sp->h_addr_list[0]);
221 struct sockaddr_in sin;
224 s_fd = socket(PF_INET, SOCK_STREAM, 0);
228 perror(
"socket error");
239 sts = connect(s_fd, (
struct sockaddr *)&sin,
sizeof(sin));
249 sts = fcntl(s_fd, F_SETFL, flags);
250 TLOG(TLVL_TRACE) <<
"TCPConnect fcntl(fd=" << s_fd <<
",flags=0x" << std::hex << flags << std::dec <<
") =" << sts;
256 socklen_t lenlen =
sizeof(len);
258 sts = getsockopt(s_fd, SOL_SOCKET, SO_SNDBUF, &len, &lenlen);
259 TLOG(TLVL_DEBUG) <<
"TCPConnect SNDBUF initial: " << len <<
" sts/errno=" << sts <<
"/" << errno <<
" lenlen=" << lenlen;
261 sts = setsockopt(s_fd, SOL_SOCKET, SO_SNDBUF, &len, lenlen);
263 TLOG(TLVL_ERROR) <<
"Error with setsockopt SNDBUF " << errno;
265 sts = getsockopt(s_fd, SOL_SOCKET, SO_SNDBUF, &len, &lenlen);
266 if (len < (sndbufsiz * 2))
267 TLOG(TLVL_WARNING) <<
"SNDBUF " << len <<
" not expected (" << sndbufsiz <<
" sts/errno=" << sts <<
"/" << errno;
269 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.