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