00001
00002
00003
00004
00005
00006
00007
00008
00009 static const char rcsid[] __attribute__((used)) = "$Id: IPAddressPort.cpp 1197 2014-10-14 22:26:11Z sella $";
00010
00011 #include "IPAddressPort.h"
00012 #include "../util/String.h"
00013
00014 #include <string.h>
00015
00016 #define HASH_ALGO_INT1
00017
00018 using namespace sella::net;
00019 using namespace sella::util;
00020
00021 IPAddressPort::IPAddressPort(const IPAddress &address, const Port &port) throw () :
00022 hcache(0)
00023 {
00024 init(address, port);
00025 }
00026
00027 IPAddressPort::IPAddressPort(const IPAddress &address, const TCPPort &port) throw () :
00028 hcache(0)
00029 {
00030 init(address, (Port) port);
00031 }
00032
00033 IPAddressPort::IPAddressPort(const IPAddress &address, const UDPPort &port) throw () :
00034 hcache(0)
00035 {
00036 init(address, (Port) port);
00037 }
00038
00039 IPAddressPort::IPAddressPort(const IPAddress &address, uint16_t port) throw (PortException) :
00040 hcache(0)
00041 {
00042 const Port p(port);
00043
00044 init(address, p);
00045 }
00046
00047 IPAddressPort::IPAddressPort(const std::string &address, uint16_t port) throw (AddressException, PortException) :
00048 hcache(0)
00049 {
00050 std::vector<std::string> matches;
00051
00052 if (String::regex_imatch(address, "^\\s*(\\[?([0-9\\.]+)\\]?|\\[([0-9A-Z:]+)\\]):([0-9]+)\\s*$", matches)) {
00053 const IPAddress a((matches.at(3).empty()) ? matches.at(2) : matches.at(3));
00054
00055 if (port > 0) {
00056 const Port p(port);
00057
00058 init(a, p);
00059 } else {
00060 const Port p(matches.at(4));
00061
00062 init(a, p);
00063 }
00064 } else if (String::regex_imatch(address, "^\\s*\\[?([0-9\\.]+|[0-9A-Z:]+)\\]?\\s*$", matches)) {
00065 const IPAddress a(matches.at(1));
00066 const Port p(port);
00067
00068 init(a, p);
00069 } else {
00070 const IPAddress a(address);
00071 const Port p(port);
00072
00073 init(a, p);
00074 }
00075 }
00076
00077 IPAddressPort::IPAddressPort(const struct sockaddr_storage *ss) throw (AddressException, PortException) :
00078 hcache(0)
00079 {
00080 const IPAddress a(ss);
00081 const Port p(ss);
00082
00083 init(a, p);
00084 }
00085
00086 IPAddressPort::IPAddressPort(const struct sockaddr *sa) throw (AddressException, PortException) :
00087 hcache(0)
00088 {
00089 const IPAddress a(sa);
00090 const Port p(sa);
00091
00092 init(a, p);
00093 }
00094
00095 IPAddressPort::IPAddressPort(const IPAddressPort &other) throw () :
00096 address(other.address),
00097 port(other.port),
00098 u(other.u),
00099 scache(other.scache),
00100 hcache(other.hcache)
00101 { }
00102
00103 IPAddressPort::IPAddressPort(const IPAddressPort &&other) throw () :
00104 address(std::move(other.address)),
00105 port(std::move(other.port)),
00106 u(other.u),
00107 scache(std::move(other.scache)),
00108 hcache(other.hcache)
00109 { }
00110
00111 IPAddressPort::~IPAddressPort() throw () { }
00112
00113 IPAddressPort& IPAddressPort::operator = (const IPAddressPort &other) throw () {
00114 if (this != &other) {
00115 this->address = other.address;
00116 this->port = other.port;
00117 this->u = other.u;
00118 this->scache = other.scache;
00119 this->hcache = other.hcache;
00120 }
00121
00122 return *this;
00123 }
00124
00125 IPAddressPort& IPAddressPort::operator = (const IPAddressPort &&other) throw () {
00126 if (this != &other) {
00127 this->address = std::move(other.address);
00128 this->port = std::move(other.port);
00129 this->u = other.u;
00130 this->scache = std::move(other.scache);
00131 this->hcache = other.hcache;
00132 }
00133
00134 return *this;
00135 }
00136
00137 bool IPAddressPort::operator == (const IPAddressPort &other) const throw () {
00138 return (this->port == other.port) ? ((this->address == other.address) ? true : false) : false;
00139 }
00140
00141 bool IPAddressPort::operator != (const IPAddressPort &other) const throw () {
00142 return !(*this == other);
00143 }
00144
00145 bool IPAddressPort::operator >= (const IPAddressPort &other) const throw () {
00146 return (this->address < other.address) ? false : ((this->address > other.address) ? true : (this->port >= other.port) ? true : false);
00147 }
00148
00149 bool IPAddressPort::operator <= (const IPAddressPort &other) const throw () {
00150 return (this->address > other.address) ? false : ((this->address < other.address) ? true : (this->port <= other.port) ? true : false);
00151 }
00152
00153 bool IPAddressPort::operator > (const IPAddressPort &other) const throw () {
00154 return (this->address > other.address) ? true : ((this->address < other.address) ? false : (this->port > other.port) ? true : false);
00155 }
00156
00157 bool IPAddressPort::operator < (const IPAddressPort &other) const throw () {
00158 return (this->address < other.address) ? true : ((this->address > other.address) ? false : (this->port < other.port) ? true : false);
00159 }
00160
00161 int IPAddressPort::getFamily(void) const throw () {
00162 return address.getFamily();
00163 }
00164
00165 const IPAddress& IPAddressPort::getIPAddress(void) const throw () {
00166 return this->address;
00167 }
00168
00169 const Port& IPAddressPort::getPort(void) const throw () {
00170 return this->port;
00171 }
00172
00173 const struct sockaddr_storage& IPAddressPort::getSockaddrStorage(void) const throw () {
00174 return u.ss;
00175 }
00176
00177 const struct sockaddr& IPAddressPort::getSockaddr(void) const throw () {
00178 return u.sa;
00179 }
00180
00181 const struct sockaddr_in& IPAddressPort::getSockaddrIn(void) const throw () {
00182 return u.sa_in;
00183 }
00184
00185 const struct sockaddr_in6& IPAddressPort::getSockaddrIn6(void) const throw () {
00186 return u.sa_in6;
00187 }
00188
00189 bool IPAddressPort::hasIPAddress(void) const throw () {
00190 return (!address.empty());
00191 }
00192
00193 bool IPAddressPort::hasPort(void) const throw () {
00194 return (!port.empty());
00195 }
00196
00197 const std::string& IPAddressPort::str(void) const throw (AddressException) {
00198 if (scache.empty()) {
00199 if (this->address.getFamily() == AF_INET) {
00200 scache.append(this->address.str()).append(":").append(this->port.str());
00201 } else {
00202 scache.append("[").append(this->address.str()).append("]:").append(this->port.str());
00203 }
00204 }
00205
00206 return scache;
00207 }
00208
00209 const char* IPAddressPort::c_str(void) const throw (AddressException) {
00210 return str().c_str();
00211 }
00212
00213 uint32_t IPAddressPort::getU32(void) const throw () {
00214 return (address.getU32() ^ port.getU32());
00215 }
00216
00217 uint32_t IPAddressPort::getHash(void) const throw () {
00218 if (hcache != 0) {
00219 return hcache;
00220 }
00221
00222 #if defined HASH_ALGO_INT1
00223 uint32_t k = getU32();
00224
00225 hcache = ((k & 0xF0F0F0F0) >> 4) | ((k & 0x0F0F0F0F) << 4);
00226 #elif defined HASH_ALGO_INT2
00227 uint32_t k = getU32();
00228
00229 hcache = (k<<16)^(k>>16)^k;
00230 #elif defined HASH_ALGO_INT3
00231 hcache = getU32();
00232 #else
00233 #error No hash algo selected.
00234 #endif
00235
00236 return hcache;
00237 }
00238
00239 bool IPAddressPort::empty(void) const throw () {
00240 return (port.empty() && address.empty());
00241 }
00242
00243 const IPAddressPort::shared IPAddressPort::shared_ptr(const IPAddress &address, const Port &port) throw () {
00244 return std::make_shared<IPAddressPort>(address, port);
00245 }
00246
00247 const IPAddressPort::shared IPAddressPort::shared_ptr(const IPAddress &address, const TCPPort &port) throw () {
00248 return std::make_shared<IPAddressPort>(address, port);
00249 }
00250
00251 const IPAddressPort::shared IPAddressPort::shared_ptr(const IPAddress &address, const UDPPort &port) throw () {
00252 return std::make_shared<IPAddressPort>(address, port);
00253 }
00254
00255 const IPAddressPort::shared IPAddressPort::shared_ptr(const IPAddress &address, uint16_t port) throw (PortException) {
00256 return std::make_shared<IPAddressPort>(address, port);
00257 }
00258
00259 const IPAddressPort::shared IPAddressPort::shared_ptr(const std::string &address, uint16_t port) throw (AddressException, PortException) {
00260 return std::make_shared<IPAddressPort>(address, port);
00261 }
00262
00263 const IPAddressPort::shared IPAddressPort::shared_ptr(const struct sockaddr_storage *ss) throw (AddressException, PortException) {
00264 return std::make_shared<IPAddressPort>(ss);
00265 }
00266
00267 const IPAddressPort::shared IPAddressPort::shared_ptr(const struct sockaddr *sa) throw (AddressException, PortException) {
00268 return std::make_shared<IPAddressPort>(sa);
00269 }
00270
00271 void IPAddressPort::init(const IPAddress &address, const Port &port) throw () {
00272 this->address = address;
00273 this->port = port;
00274
00275 memset(&u, 0, sizeof(union __sockaddr_union));
00276
00277 u.sa.sa_family = address.getFamily();
00278 if (u.sa.sa_family == AF_INET) {
00279 memcpy(&(u.sa_in.sin_addr), &(address.getIPv4AddressStructure()), sizeof(struct in_addr));
00280 } else {
00281 memcpy(&(u.sa_in6.sin6_addr), &(address.getIPv6AddressStructure()), sizeof(struct in6_addr));
00282 }
00283 u.sa_in.sin_port = htons(port.get());
00284 }
00285
00286
00287
00288