00001
00002
00003
00004
00005
00006
00007
00008 #define TRACE_NAME "TCPConnect"
00009
00010 #include <stdio.h>
00011 #include <sys/types.h>
00012 #include <sys/socket.h>
00013 #include <netinet/in.h>
00014 #include <stdlib.h>
00015 #include <unistd.h>
00016 #include <string.h>
00017 #include <sys/socket.h>
00018 #include <netinet/in.h>
00019 #include <arpa/inet.h>
00020 #include <netdb.h>
00021
00022 #include <string>
00023 #include <regex>
00024
00025 #include "artdaq/DAQdata/Globals.hh"
00026 #include "artdaq/DAQdata/TCPConnect.hh"
00027
00028
00029 int ResolveHost(char const* host_in, in_addr& addr)
00030 {
00031 std::string host;
00032 struct hostent* hostent_sp;
00033 std::cmatch mm;
00034
00035
00036 if (regex_match(host_in, mm, std::regex("([^:]+):(\\d+)")))
00037 {
00038 host = mm[1].str();
00039 }
00040 else if (regex_match(host_in, mm, std::regex(":{0,1}(\\d+)")))
00041 {
00042 host = std::string("127.0.0.1");
00043 }
00044 else if (regex_match(host_in, mm, std::regex("([^:]+):{0,1}")))
00045 {
00046 host = mm[1].str().c_str();
00047 }
00048 else
00049 {
00050 host = std::string("127.0.0.1");
00051 }
00052 TLOG(TLVL_INFO) << "Resolving host " << host;
00053
00054 bzero((char *)&addr, sizeof(addr));
00055
00056 if (regex_match(host.c_str(), mm, std::regex("\\d+(\\.\\d+){3}")))
00057 inet_aton(host.c_str(), &addr);
00058 else
00059 {
00060 hostent_sp = gethostbyname(host.c_str());
00061 if (!hostent_sp)
00062 {
00063 perror("gethostbyname");
00064 return (-1);
00065 }
00066 addr = *(struct in_addr *)(hostent_sp->h_addr_list[0]);
00067 }
00068 return 0;
00069 }
00070
00071
00072 int ResolveHost(char const* host_in, int dflt_port, sockaddr_in& sin)
00073 {
00074 int port;
00075 std::string host;
00076 struct hostent* hostent_sp;
00077 std::cmatch mm;
00078
00079
00080 if (regex_match(host_in, mm, std::regex("([^:]+):(\\d+)")))
00081 {
00082 host = mm[1].str();
00083 port = strtoul(mm[2].str().c_str(), NULL, 0);
00084 }
00085 else if (regex_match(host_in, mm, std::regex(":{0,1}(\\d+)")))
00086 {
00087 host = std::string("127.0.0.1");
00088 port = strtoul(mm[1].str().c_str(), NULL, 0);
00089 }
00090 else if (regex_match(host_in, mm, std::regex("([^:]+):{0,1}")))
00091 {
00092 host = mm[1].str().c_str();
00093 port = dflt_port;
00094 }
00095 else
00096 {
00097 host = std::string("127.0.0.1");
00098 port = dflt_port;
00099 }
00100 TLOG(TLVL_INFO) << "Resolving host " << host << ", on port " << std::to_string(port);
00101
00102 if (host == "localhost") host = "127.0.0.1";
00103
00104 bzero((char *)&sin, sizeof(sin));
00105 sin.sin_family = AF_INET;
00106 sin.sin_port = htons(port);
00107
00108 if (regex_match(host.c_str(), mm, std::regex("\\d+(\\.\\d+){3}")))
00109 inet_aton(host.c_str(), &sin.sin_addr);
00110 else
00111 {
00112 hostent_sp = gethostbyname(host.c_str());
00113 if (!hostent_sp)
00114 {
00115 perror("gethostbyname");
00116 return (-1);
00117 }
00118 sin.sin_addr = *(struct in_addr *)(hostent_sp->h_addr_list[0]);
00119 }
00120 return 0;
00121 }
00122
00123
00124 int TCPConnect(char const* host_in
00125 , int dflt_port
00126 , long flags
00127 , int sndbufsiz)
00128 {
00129 int s_fd, sts;
00130 struct sockaddr_in sin;
00131
00132
00133 s_fd = socket(PF_INET, SOCK_STREAM, 0);
00134
00135 if (s_fd == -1)
00136 {
00137 perror("socket error");
00138 return (-1);
00139 }
00140
00141 sts = ResolveHost(host_in, dflt_port, sin);
00142 if (sts == -1)
00143 {
00144 close(s_fd);
00145 return -1;
00146 }
00147
00148 sts = connect(s_fd, (struct sockaddr *)&sin, sizeof(sin));
00149 if (sts == -1)
00150 {
00151
00152 close(s_fd);
00153 return (-1);
00154 }
00155
00156 if (flags)
00157 {
00158 sts = fcntl(s_fd, F_SETFL, flags);
00159 TLOG(TLVL_TRACE) << "TCPConnect fcntl(fd=" << s_fd << ",flags=0x" << std::hex << flags << std::dec << ") =" << sts;
00160 }
00161
00162 if (sndbufsiz > 0)
00163 {
00164 int len;
00165 socklen_t lenlen = sizeof(len);
00166 len = 0;
00167 sts = getsockopt(s_fd, SOL_SOCKET, SO_SNDBUF, &len, &lenlen);
00168 TLOG(TLVL_DEBUG) << "TCPConnect SNDBUF initial: "<< len <<" sts/errno="<< sts <<"/"<< errno <<" lenlen="<< lenlen ;
00169 len = sndbufsiz;
00170 sts = setsockopt(s_fd, SOL_SOCKET, SO_SNDBUF, &len, lenlen);
00171 if (sts == -1)
00172 TLOG(TLVL_ERROR) << "Error with setsockopt SNDBUF "<< errno;
00173 len = 0;
00174 sts = getsockopt(s_fd, SOL_SOCKET, SO_SNDBUF, &len, &lenlen);
00175 if (len < (sndbufsiz * 2))
00176 TLOG(TLVL_WARNING) << "SNDBUF "<< len <<" not expected ("<< sndbufsiz <<" sts/errno="<< sts <<"/"<< errno ;
00177 else
00178 TLOG(TLVL_DEBUG) << "SNDBUF "<< len <<" sts/errno="<< sts <<"/"<< errno ;
00179 }
00180 return (s_fd);
00181 }