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 using namespace std;
00027
00028
00029 int ResolveHost(char const* host_in, in_addr& addr)
00030 {
00031 std::string host;
00032 struct hostent* hostent_sp;
00033 cmatch mm;
00034
00035
00036 if (regex_match(host_in, mm, regex("([^:]+):(\\d+)")))
00037 {
00038 host = mm[1].str();
00039 }
00040 else if (regex_match(host_in, mm, regex(":{0,1}(\\d+)")))
00041 {
00042 host = std::string("127.0.0.1");
00043 }
00044 else if (regex_match(host_in, mm, 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_INFO("TCPConnect") << "Resolving host " << host << TLOG_ENDL;
00053
00054 bzero((char *)&addr, sizeof(addr));
00055
00056 if (regex_match(host.c_str(), mm, 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 cmatch mm;
00078
00079
00080 if (regex_match(host_in, mm, 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, 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, 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_INFO("TCPConnect") << "Resolving host " << host << ", on port " << std::to_string(port) << TLOG_ENDL;
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, 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 }