00001 #include "otsdaq-core/NetworkUtilities/Socket.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004
00005 #include <iostream>
00006 #include <cassert>
00007 #include <sstream>
00008
00009 #include <unistd.h>
00010 #include <arpa/inet.h>
00011
00012 #include <netdb.h>
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <cstring>
00022
00023
00024 using namespace ots;
00025
00026
00027
00028
00029 Socket::Socket(const std::string &IPAddress, unsigned int port)
00030 : socketNumber_ (-1)
00031 , IPAddress_ (IPAddress)
00032 , requestedPort_(port)
00033
00034 {
00035 __COUT__ << "Socket constructor " << IPAddress << ":" << port << __E__;
00036
00037
00038 if(port >= (1<<16))
00039 {
00040 __SS__ << "FATAL: Invalid Port " << port << ". Max port number is " <<
00041 (1<<16)-1 << "." << std::endl;
00042
00043 __COUT_ERR__ << "\n" << ss.str();
00044 throw std::runtime_error(ss.str());
00045 }
00046
00047
00048
00049 socketAddress_.sin_family = AF_INET;
00050 socketAddress_.sin_port = htons(port);
00051
00052 __COUT__ << "IPAddress: " << IPAddress << " port: " << port << " htons: " << socketAddress_.sin_port << std::endl;
00053
00054 if(inet_aton(IPAddress.c_str(), &socketAddress_.sin_addr) == 0)
00055 {
00056 __SS__ << "FATAL: Invalid IP:Port combination. Please verify... " <<
00057 IPAddress << ":" << port << std::endl;
00058
00059 __COUT_ERR__ << "\n" << ss.str();
00060 throw std::runtime_error(ss.str());
00061 }
00062
00063 memset(&(socketAddress_.sin_zero), '\0', 8);
00064
00065 __COUT__ << "Constructed socket for port " << ntohs(socketAddress_.sin_port) <<
00066 " htons: " << socketAddress_.sin_port << std::endl;
00067
00068 }
00069
00070
00071
00072 Socket::Socket(void)
00073 {
00074 __SS__ << "ERROR: This method should never be called. This is the protected constructor. There is something wrong in your inheritance scheme!" << std::endl;
00075 __COUT_ERR__ << "\n" << ss.str();
00076
00077 throw std::runtime_error(ss.str());
00078 }
00079
00080
00081 Socket::~Socket(void)
00082 {
00083 __COUT__ << "CLOSING THE SOCKET #" << socketNumber_ << " IP: " << IPAddress_ << " port: " << getPort() << " htons: " << socketAddress_.sin_port << std::endl;
00084 if(socketNumber_ != -1)
00085 close(socketNumber_);
00086 }
00087
00088
00089 void Socket::initialize(unsigned int socketReceiveBufferSize)
00090 {
00091 __COUT__ << "Initializing port " << ntohs(socketAddress_.sin_port) <<
00092 " htons: " << socketAddress_.sin_port << std::endl;
00093 struct addrinfo hints;
00094 struct addrinfo* res;
00095 int status = 0;
00096
00097
00098 memset(&hints, 0, sizeof hints);
00099 hints.ai_family = AF_INET;
00100 hints.ai_socktype = SOCK_DGRAM;
00101 hints.ai_flags = AI_PASSIVE;
00102
00103 bool socketInitialized = false;
00104 int fromPort = FirstSocketPort;
00105 int toPort = LastSocketPort;
00106
00107 if(ntohs(socketAddress_.sin_port) != 0)
00108 fromPort = toPort = ntohs(socketAddress_.sin_port);
00109
00110 std::stringstream port;
00111
00112 for(int p=fromPort; p<=toPort && !socketInitialized; p++)
00113 {
00114 port.str("");
00115 port << p;
00116 __COUT__ << "]\tBinding port: " << port.str() << std::endl;
00117 socketAddress_.sin_port = htons(p);
00118
00119 if((status = getaddrinfo(NULL, port.str().c_str(), &hints, &res)) != 0)
00120 {
00121 __COUT__ << "]\tGetaddrinfo error status: " << status << std::endl;
00122 continue;
00123 }
00124
00125
00126 socketNumber_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
00127
00128 __COUT__ << "]\tSocket Number: " << socketNumber_ << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." << std::endl;
00129
00130 if(bind(socketNumber_, res->ai_addr, res->ai_addrlen) == -1)
00131 {
00132 std::cout << __COUT_HDR_FL__ << "Error********Error********Error********Error********Error********Error" << std::endl;
00133 std::cout << __COUT_HDR_FL__ << "FAILED BIND FOR PORT: " << port.str() << " ON IP: " << IPAddress_ << std::endl;
00134 std::cout << __COUT_HDR_FL__ << "Error********Error********Error********Error********Error********Error" << std::endl;
00135 socketNumber_ = 0;
00136 }
00137 else
00138 {
00139 std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
00140 std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
00141 std::cout << __COUT_HDR_FL__ << "SOCKET ON PORT: " << port.str() << " ON IP: " << IPAddress_ << " INITIALIZED OK!" << std::endl;
00142 std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
00143 std::cout << __COUT_HDR_FL__ << ":):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):):)" << std::endl;
00144 char yes = '1';
00145 setsockopt(socketNumber_,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int));
00146 socketInitialized = true;
00147 __COUT__ << "]\tSocket Number: " << socketNumber_ << " for port: " << ntohs(socketAddress_.sin_port) << " initialized." << std::endl;
00148 }
00149
00150 freeaddrinfo(res);
00151 }
00152
00153 if(!socketInitialized)
00154 {
00155 __SS__ << "FATAL: Socket could not initialize socket (IP=" << IPAddress_ <<
00156 ", Port=" << ntohs(socketAddress_.sin_port) << "). Perhaps it is already in use?" << std::endl;
00157 std::cout << ss.str();
00158 throw std::runtime_error(ss.str());
00159 }
00160
00161
00162 __COUT__ << "Setting socket receive buffer size = " << socketReceiveBufferSize <<
00163 " 0x" << std::hex << socketReceiveBufferSize << std::dec << __E__;
00164 if (setsockopt(socketNumber_, SOL_SOCKET, SO_RCVBUF,
00165 (char*)&socketReceiveBufferSize,
00166 sizeof(socketReceiveBufferSize)) < 0) {
00167 __COUT_ERR__ << "Failed to set socket receive size to " <<
00168 socketReceiveBufferSize << ". Attempting to revert to default." << std::endl;
00169
00170 socketReceiveBufferSize = defaultSocketReceiveSize_;
00171
00172
00173 __COUT__ << "Setting socket receive buffer size = " << socketReceiveBufferSize <<
00174 " 0x" << std::hex << socketReceiveBufferSize << std::dec << __E__;
00175 if (setsockopt(socketNumber_, SOL_SOCKET, SO_RCVBUF,
00176 (char*)&socketReceiveBufferSize,
00177 sizeof(socketReceiveBufferSize)) < 0)
00178 {
00179 __SS__ << "Failed to set socket receive size to " <<
00180 socketReceiveBufferSize << ". Attempting to revert to default." << std::endl;
00181 std::cout << ss.str();
00182 throw std::runtime_error(ss.str());
00183 }
00184
00185 }
00186 }
00187
00188 uint16_t Socket::getPort()
00189 {
00190 struct sockaddr_in sin;
00191 socklen_t len = sizeof(sin);
00192 getsockname(socketNumber_, (struct sockaddr *)&sin, &len);
00193 return ntohs(sin.sin_port);
00194 }
00195
00196
00197 const struct sockaddr_in& Socket::getSocketAddress(void)
00198 {
00199 return socketAddress_;
00200 }
00201