00001
00002
00003
00004
00005
00006
00007
00008
00009 static const char rcsid[] __attribute__((used)) = "$Id: Socket.cpp 1197 2014-10-14 22:26:11Z sella $";
00010
00011 #include "Socket.h"
00012
00013 #include <stdio.h>
00014 #include <netdb.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include <unistd.h>
00018 #include <fcntl.h>
00019 #include <net/if.h>
00020 #include <arpa/inet.h>
00021 #include <sys/ioctl.h>
00022 #include <sys/types.h>
00023 #include <sys/socket.h>
00024 #include <sys/un.h>
00025 #include <netinet/in.h>
00026 #include <errno.h>
00027 #include <sys/mman.h>
00028
00029 using namespace sella::net;
00030
00031
00032 extern int errno;
00033
00034 union __sockaddr_union {
00035 struct sockaddr_storage *ss;
00036 struct sockaddr *sa;
00037 struct sockaddr_in *sa_in;
00038 struct sockaddr_in6 *sa_in6;
00039 struct sockaddr_un *sa_un;
00040 };
00041
00042 Socket::Socket(int s) throw (SocketException) : usable(false), mux(false), read(false), write(false), except(false) {
00043 sockaddr_storage addr;
00044 socklen_t addrlen = sizeof(sockaddr_storage);
00045
00046 if (s < 0 || s > FD_SETSIZE) {
00047 THROW(SocketException, "Passed invalid socket (%d)", s);
00048 }
00049
00050 if (getsockname(s, (sockaddr *) &addr, &addrlen) < 0) {
00051 THROW2(SocketException, "getsockname()");
00052 }
00053
00054 if (addr.ss_family < 1 || addr.ss_family >= AF_MAX) {
00055 THROW(SocketException, "Family (%d) is invalid", addr.ss_family);
00056 }
00057
00058 if (addr.ss_family != AF_INET && addr.ss_family != AF_INET6 && addr.ss_family != AF_PACKET && addr.ss_family != AF_UNIX) {
00059 THROW(SocketException, "Only addr.ss_family AF_INET, AF_INET6, AF_PACKET and AF_UNIX are implemented");
00060 }
00061
00062 this->family = addr.ss_family;
00063 this->s = s;
00064 }
00065
00066 Socket::Socket(int family, int type, int protocol) throw (SocketException) : s(-1), family(family), usable(false), mux(false), read(false), write(false), except(false) {
00067 if (family < 1 || family >= AF_MAX) {
00068 THROW(SocketException, "Family (%d) is invalid", family);
00069 }
00070
00071 if (family != AF_INET && family != AF_INET6 && family != AF_PACKET && family != AF_UNIX) {
00072 THROW(SocketException, "Only family AF_INET, AF_INET6, AF_PACKET and AF_UNIX are implemented");
00073 }
00074
00075 if (type < 0) {
00076 THROW(SocketException, "Socket type (%d) is invalid", type);
00077 }
00078
00079 if (protocol < 0) {
00080 THROW(SocketException, "Protocol (%d) is invalid", protocol);
00081 }
00082
00083 if ((this->s = ::socket(family, type, protocol)) < 0) {
00084 THROW2(SocketException, "socket()");
00085 }
00086 }
00087
00088 Socket::~Socket() {
00089 read = write = except = false;
00090 close();
00091 }
00092
00093 void Socket::bind(const IPAddressPort &addressport) throw (SocketException) {
00094 bind(addressport.getIPAddress().str(), addressport.getPort().get());
00095 }
00096
00097 void Socket::bind(const IPAddress &address, const Port &port) throw (SocketException) {
00098 bind(address.str(), port.get());
00099 }
00100
00101 void Socket::bind(const std::string &address, const unsigned short port) throw (SocketException) {
00102 sockaddr_storage addr;
00103 socklen_t addrlen = sizeof(sockaddr_storage);
00104
00105 initAddr(family, address, port, addr, addrlen);
00106
00107 addr.ss_family = family;
00108
00109 if (::bind(s, (sockaddr *) &addr, addrlen) < 0) {
00110 THROW2(SocketException, "bind()");
00111 }
00112
00113 usable = true;
00114 }
00115
00116 void Socket::connect(const IPAddressPort &addressport) throw (SocketException) {
00117 connect(addressport.getIPAddress().str(), addressport.getPort().get());
00118 }
00119
00120 void Socket::connect(const IPAddress &address, const Port &port) throw (SocketException) {
00121 connect(address.str(), port.get());
00122 }
00123
00124 void Socket::connect(const std::string &address, const unsigned short port) throw (SocketException) {
00125 sockaddr_storage addr;
00126 socklen_t addrlen = sizeof(sockaddr_storage);
00127
00128 initAddr(family, address, port, addr, addrlen);
00129
00130 if (::connect(s, (sockaddr *) &addr, addrlen) < 0) {
00131 usable = false;
00132
00133 THROW2(SocketException, "connect()");
00134 }
00135
00136 usable = true;
00137 }
00138
00139 void Socket::close(void) throw (SocketException) {
00140 usable = false;
00141
00142 if (s >= 0) {
00143 if (::close(s) < 0) {
00144 THROW2(SocketException, "close()");
00145 }
00146
00147 s = -1;
00148 }
00149 }
00150
00151 ssize_t Socket::send(const void *data, size_t len, int flags) throw (SocketException) {
00152 ssize_t c, r = len;
00153 int flg;
00154
00155 do {
00156 if ((c = ::send(s, data, len, flags)) < 0) {
00157 switch (errno) {
00158 case EINTR:
00159 case EMSGSIZE:
00160 case ENOBUFS:
00161 break;
00162
00163 #if ((EAGAIN) != (EWOULDBLOCK))
00164 case EAGAIN:
00165 #endif
00166 case EWOULDBLOCK:
00167 if ((flags & MSG_DONTWAIT) || ((flg = fcntl(s, F_GETFL)) != -1 && (flg & O_NONBLOCK))) {
00168 THROW_CODE(SocketException, EWOULDBLOCK, "Nonblocking socket would have blocked");
00169 }
00170
00171 THROW_CODE(SocketException, EWOULDBLOCK, "Send timed out");
00172
00173 default:
00174 usable = false;
00175 }
00176
00177 THROW2(SocketException, "send()");
00178 } else if (c == 0) {
00179 usable = false;
00180 }
00181 } while ((r -= c) > 0);
00182
00183 write = false;
00184
00185 return len;
00186 }
00187
00188 ssize_t Socket::send(const std::string &data, int flags) throw (SocketException) {
00189 return send((const void*) data.c_str(), data.size(), flags);
00190 }
00191
00192 ssize_t Socket::send(const std::vector<uint8_t> &data, int flags) throw (SocketException) {
00193 return send((const void*) data.data(), data.size(), flags);
00194 }
00195
00196 ssize_t Socket::recv(void *buf, size_t len, int flags) throw (SocketException) {
00197 ssize_t c;
00198 int flg;
00199
00200 if ((c = ::recv(s, buf, len, flags)) < 0) {
00201 switch (errno) {
00202 case EINTR:
00203 break;
00204
00205 #if ((EAGAIN) != (EWOULDBLOCK))
00206 case EAGAIN:
00207 #endif
00208 case EWOULDBLOCK:
00209 read = except = false;
00210
00211 if ((flags & MSG_DONTWAIT) || ((flg = fcntl(s, F_GETFL)) != -1 && (flg & O_NONBLOCK))) {
00212 THROW_CODE(SocketException, EWOULDBLOCK, "Nonblocking socket would have blocked");
00213 }
00214
00215 THROW_CODE(SocketException, EWOULDBLOCK, "Receive timed out");
00216
00217 default:
00218 usable = false;
00219 }
00220
00221 THROW2(SocketException, "recv()");
00222 } else if (c == 0) {
00223 usable = false;
00224 }
00225
00226 read = except = false;
00227
00228 return c;
00229 }
00230
00231 ssize_t Socket::recv(std::string &data, size_t len, int flags) throw (SocketException) {
00232 uint8_t buf[len];
00233 ssize_t size = recv(buf, len, flags);
00234
00235 std::string(buf, buf + len).swap(data);
00236
00237 return size;
00238 }
00239
00240 ssize_t Socket::recv(std::vector<uint8_t> &data, size_t len, int flags) throw (SocketException) {
00241 uint8_t buf[len];
00242 ssize_t size = recv(buf, len, flags);
00243
00244 std::vector<uint8_t>(buf, buf + len).swap(data);
00245
00246 return size;
00247 }
00248
00249 int Socket::getFD(void) const {
00250 return s;
00251 }
00252
00253 bool Socket::isRead(void) const {
00254 return read;
00255 }
00256
00257 bool Socket::isWrite(void) const {
00258 return write;
00259 }
00260
00261 bool Socket::isExcept(void) const {
00262 return except;
00263 }
00264
00265 bool Socket::hasData(void) const throw (SocketException) {
00266 return (getQueuedBytes() > 0);
00267 }
00268
00269 int Socket::getQueuedBytes(void) const throw (SocketException) {
00270 int count;
00271
00272 if (ioctl(s, FIONREAD, &count) == -1) {
00273 THROW2(SocketException, "ioctl()");
00274 }
00275
00276 return count;
00277 }
00278
00279 IPAddressPort Socket::getLocalIPAddressPort(void) const throw (SocketException) {
00280 sockaddr_storage addr;
00281 socklen_t addrlen = sizeof(sockaddr_storage);
00282
00283 if (getsockname(s, (sockaddr *) &addr, &addrlen) < 0) {
00284 THROW2(SocketException, "getsockname()");
00285 }
00286
00287 return IPAddressPort(&addr);
00288 }
00289
00290 IPAddress Socket::getLocalIPAddress(void) const throw (SocketException) {
00291 sockaddr_storage addr;
00292 socklen_t addrlen = sizeof(sockaddr_storage);
00293
00294 if (getsockname(s, (sockaddr *) &addr, &addrlen) < 0) {
00295 THROW2(SocketException, "getsockname()");
00296 }
00297
00298 return IPAddress(&addr);
00299 }
00300
00301 Port Socket::getLocalPort(void) const throw (SocketException) {
00302 sockaddr_storage addr;
00303 socklen_t addrlen = sizeof(sockaddr_storage);
00304
00305 if (getsockname(s, (sockaddr *) &addr, &addrlen) < 0) {
00306 THROW2(SocketException, "getsockname()");
00307 }
00308
00309 return Port(&addr);
00310 }
00311
00312 IPAddressPort Socket::getRemoteIPAddressPort(void) const throw (SocketException) {
00313 sockaddr_storage addr;
00314 socklen_t addrlen = sizeof(sockaddr_storage);
00315
00316 if (getpeername(s, (sockaddr *) &addr, &addrlen) < 0) {
00317 THROW2(SocketException, "getpeername()");
00318 }
00319
00320 return IPAddressPort(&addr);
00321 }
00322
00323 IPAddress Socket::getRemoteIPAddress(void) const throw (SocketException) {
00324 sockaddr_storage addr;
00325 socklen_t addrlen = sizeof(sockaddr_storage);
00326
00327 if (getpeername(s, (sockaddr *) &addr, &addrlen) < 0) {
00328 THROW2(SocketException, "getpeername()");
00329 }
00330
00331 return IPAddress(&addr);
00332 }
00333
00334 Port Socket::getRemotePort(void) const throw (SocketException) {
00335 sockaddr_storage addr;
00336 socklen_t addrlen = sizeof(sockaddr_storage);
00337
00338 if (getpeername(s, (sockaddr *) &addr, &addrlen) < 0) {
00339 THROW2(SocketException, "getpeername()");
00340 }
00341
00342 return Port(&addr);
00343 }
00344
00345 int Socket::getFamily(void) const throw () {
00346 return family;
00347 }
00348
00349 bool Socket::isUsable(void) const throw () {
00350 if (s < 0 || !(fcntl(s, F_GETFD) != -1 || errno != EBADF)) {
00351 return false;
00352 }
00353
00354 return usable;
00355 }
00356
00357 bool Socket::hasMux(void) const throw () {
00358 return mux;
00359 }
00360
00361 void Socket::setBlock(bool on) throw (SocketException) {
00362 int flags;
00363
00364 if ((flags = fcntl(s, F_GETFL)) < 0) {
00365 THROW2(SocketException, "fcntl()");
00366 }
00367
00368 if (on) {
00369 flags &= ~O_NONBLOCK;
00370 } else {
00371 flags |= O_NONBLOCK;
00372 }
00373
00374 if (fcntl(s, F_SETFL, flags) < 0) {
00375 THROW2(SocketException, "fcntl()");
00376 }
00377 }
00378
00379 bool Socket::isBlock(void) throw (SocketException) {
00380 int flags;
00381
00382 if ((flags = fcntl(s, F_GETFL)) < 0) {
00383 THROW2(SocketException, "fcntl()");
00384 }
00385
00386 return (flags & O_NONBLOCK);
00387 }
00388
00389 void Socket::setIpOptions(const void *optval, socklen_t len) throw (SocketException) {
00390 #ifdef IP_OPTIONS
00391 if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, (void*) optval, len) < 0) {
00392 THROW2(SocketException, "setsockopt()");
00393 }
00394 #else
00395 THROW(SocketException, "IP_OPTIONS not defined");
00396 #endif
00397 }
00398
00399 void Socket::setIpPktInfo(bool on) throw (SocketException) {
00400 #ifdef IP_PKTINFO
00401 int optval = (on) ? 1 : 0;
00402
00403 if (setsockopt(s, IPPROTO_IP, IP_PKTINFO, (void*) &optval, sizeof(optval)) < 0) {
00404 THROW2(SocketException, "setsockopt()");
00405 }
00406 #else
00407 THROW(SocketException, "IP_PKTINFO not defined");
00408 #endif
00409 }
00410
00411 void Socket::setIpRecvTOS(bool on) throw (SocketException) {
00412 #ifdef IP_RECVTOS
00413 int optval = (on) ? 1 : 0;
00414
00415 if (setsockopt(s, IPPROTO_IP, IP_RECVTOS, (void*) &optval, sizeof(optval)) < 0) {
00416 THROW2(SocketException, "setsockopt()");
00417 }
00418 #else
00419 THROW(SocketException, "IP_RECVTOS not defined");
00420 #endif
00421 }
00422
00423 void Socket::setIpRecvTTL(bool on) throw (SocketException) {
00424 #ifdef IP_RECVTTL
00425 int optval = (on) ? 1 : 0;
00426
00427 if (setsockopt(s, IPPROTO_IP, IP_RECVTTL, (void*) &optval, sizeof(optval)) < 0) {
00428 THROW2(SocketException, "setsockopt()");
00429 }
00430 #else
00431 THROW(SocketException, "IP_RECVTTL not defined");
00432 #endif
00433 }
00434
00435 void Socket::setIpRecvOpts(bool on) throw (SocketException) {
00436 #ifdef IP_RECVOPTS
00437 int optval = (on) ? 1 : 0;
00438
00439 if (setsockopt(s, IPPROTO_IP, IP_RECVOPTS, (void*) &optval, sizeof(optval)) < 0) {
00440 THROW2(SocketException, "setsockopt()");
00441 }
00442 #else
00443 THROW(SocketException, "IP_RECVOPTS not defined");
00444 #endif
00445 }
00446
00447 void Socket::setIpRetOpts(bool on) throw (SocketException) {
00448 #ifdef IP_RETOPTS
00449 int optval = (on) ? 1 : 0;
00450
00451 if (setsockopt(s, IPPROTO_IP, IP_RETOPTS, (void*) &optval, sizeof(optval)) < 0) {
00452 THROW2(SocketException, "setsockopt()");
00453 }
00454 #else
00455 THROW(SocketException, "IP_RETOPTS not defined");
00456 #endif
00457 }
00458
00459 void Socket::setIpTOS(unsigned char tos) throw (SocketException) {
00460 #ifdef IP_TOS
00461 if (setsockopt(s, IPPROTO_IP, IP_TOS, (void*) &tos, sizeof(tos)) < 0) {
00462 THROW2(SocketException, "setsockopt()");
00463 }
00464 #else
00465 THROW(SocketException, "IP_TOS not defined");
00466 #endif
00467 }
00468
00469 unsigned char Socket::getIpTOS(void) const throw (SocketException) {
00470 unsigned char tos = 0;
00471
00472 #ifdef IP_TOS
00473 socklen_t len = sizeof(tos);
00474
00475 if (getsockopt(s, IPPROTO_IP, IP_TOS, (void*) &tos, &len) < 0) {
00476 THROW2(SocketException, "getsockopt()");
00477 }
00478 #else
00479 THROW(SocketException, "IP_TOS not defined");
00480 #endif
00481
00482 return tos;
00483 }
00484
00485 void Socket::setIpTTL(int ttl) throw (SocketException) {
00486 #ifdef IP_TTL
00487 if (setsockopt(s, IPPROTO_IP, IP_TTL, (void*) &ttl, sizeof(ttl)) < 0) {
00488 THROW2(SocketException, "setsockopt()");
00489 }
00490 #else
00491 THROW(SocketException, "IP_TTL not defined");
00492 #endif
00493 }
00494
00495 int Socket::getIpTTL(void) const throw (SocketException) {
00496 int ttl = 0;
00497 #ifdef IP_TTL
00498 socklen_t len = sizeof(ttl);
00499
00500 if (getsockopt(s, IPPROTO_IP, IP_TTL, (void*) &ttl, &len) < 0) {
00501 THROW2(SocketException, "getsockopt()");
00502 }
00503 #else
00504 THROW(SocketException, "IP_TTL not defined");
00505 #endif
00506
00507 return ttl;
00508 }
00509
00510 void Socket::setIpHdrIncl(bool on) throw (SocketException) {
00511 #ifdef IP_HDRINCL
00512 int optval = (on) ? 1 : 0;
00513
00514 if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, (void*) &optval, sizeof(optval)) < 0) {
00515 THROW2(SocketException, "setsockopt()");
00516 }
00517 #else
00518 THROW(SocketException, "IP_HDRINCL not defined");
00519 #endif
00520 }
00521
00522 void Socket::setIpRecvErr(bool on) throw (SocketException) {
00523 #ifdef IP_RECVERR
00524 int optval = (on) ? 1 : 0;
00525
00526 if (setsockopt(s, IPPROTO_IP, IP_RECVERR, (void*) &optval, sizeof(optval)) < 0) {
00527 THROW2(SocketException, "setsockopt()");
00528 }
00529 #else
00530 THROW(SocketException, "IP_RECVERR not defined");
00531 #endif
00532 }
00533
00534 void Socket::setIpMtuDiscover(bool on) throw (SocketException) {
00535 #ifdef IP_MTU_DISCOVER
00536 int optval = (on) ? 1 : 0;
00537
00538 if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, (void*) &optval, sizeof(optval)) < 0) {
00539 THROW2(SocketException, "setsockopt()");
00540 }
00541 #else
00542 THROW(SocketException, "IP_MTU_DISCOVER not defined");
00543 #endif
00544 }
00545
00546 int Socket::getIpMtu(void) const throw (SocketException) {
00547 int mtu = 0;
00548
00549 #ifdef IP_MTU
00550 socklen_t len = sizeof(mtu);
00551
00552 if (getsockopt(s, IPPROTO_IP, IP_MTU, (void*) &mtu, &len) < 0) {
00553 THROW2(SocketException, "getsockopt()");
00554 }
00555 #else
00556 THROW(SocketException, "IP_MTU not defined");
00557 #endif
00558
00559 return mtu;
00560 }
00561
00562 void Socket::setIpRouterAlert(bool on) throw (SocketException) {
00563 #ifdef IP_ROUTER_ALERT
00564 int optval = (on) ? 1 : 0;
00565
00566 if (setsockopt(s, IPPROTO_IP, IP_ROUTER_ALERT, (void*) &optval, sizeof(optval)) < 0) {
00567 THROW2(SocketException, "setsockopt()");
00568 }
00569 #else
00570 THROW(SocketException, "IP_ROUTER_ALERT not defined");
00571 #endif
00572 }
00573
00574 void Socket::setIpMulticastTTL(int ttl) throw (SocketException) {
00575 #ifdef IP_MULTICAST_TTL
00576 if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void*) &ttl, sizeof(ttl)) < 0) {
00577 THROW2(SocketException, "setsockopt()");
00578 }
00579 #else
00580 THROW(SocketException, "IP_MULTICAST_TTL not defined");
00581 #endif
00582 }
00583
00584 int Socket::getIpMulticastTTL(void) const throw (SocketException) {
00585 int ttl = 0;
00586
00587 #ifdef MULTICAST_TTL
00588 socklen_t len = sizeof(ttl);
00589
00590 if (getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void*) &ttl, &len) < 0) {
00591 THROW2(SocketException, "getsockopt()");
00592 }
00593 #else
00594 THROW(SocketException, "IP_MULTICAST_TTL not defined");
00595 #endif
00596
00597 return ttl;
00598 }
00599
00600 void Socket::setIpMulticastLoop(bool on) throw (SocketException) {
00601 #ifdef IP_MULTICAST_LOOP
00602 int optval = (on) ? 1 : 0;
00603
00604 if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (void*) &optval, sizeof(optval)) < 0) {
00605 THROW2(SocketException, "setsockopt()");
00606 }
00607 #else
00608 THROW(SocketException, "IP_MULTICAST_LOOP not defined");
00609 #endif
00610 }
00611
00612 void Socket::setIpAddMembership(struct ip_mreqn& m) throw (SocketException) {
00613 #ifdef IP_ADD_MEMBERSHIP
00614 if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*) &m, sizeof(struct ip_mreqn)) < 0) {
00615 THROW2(SocketException, "setsockopt()");
00616 }
00617 #else
00618 THROW(SocketException, "IP_ADD_MEMBERSHIP not defined");
00619 #endif
00620 }
00621
00622 void Socket::setIpDropMembership(struct ip_mreqn& m) throw (SocketException) {
00623 #ifdef IP_DROP_MEMBERSHIP
00624 if (setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void*) &m, sizeof(struct ip_mreqn)) < 0) {
00625 THROW2(SocketException, "setsockopt()");
00626 }
00627 #else
00628 THROW(SocketException, "IP_DROP_MEMBERSHIP not defined");
00629 #endif
00630 }
00631
00632 void Socket::setSoReuseAddr(bool on) throw (SocketException) {
00633 #ifdef SO_REUSEADDR
00634 int optval = (on) ? 1 : 0;
00635
00636 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*) &optval, sizeof(optval)) < 0) {
00637 THROW2(SocketException, "setsockopt()");
00638 }
00639 #else
00640 THROW(SocketException, "SO_REUSEADDR not defined");
00641 #endif
00642 }
00643
00644 void Socket::setSoKeepAlive(bool on) throw (SocketException) {
00645 #ifdef SO_KEEPALIVE
00646 int optval = (on) ? 1 : 0;
00647
00648 if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void*) &optval, sizeof(optval)) < 0) {
00649 THROW2(SocketException, "setsockopt()");
00650 }
00651 #else
00652 THROW(SocketException, "SO_KEEPALIVE not defined");
00653 #endif
00654 }
00655
00656 void Socket::setSoNoSigPipe(bool on) throw (SocketException) {
00657 #ifdef SO_NOSIGPIPE
00658 int optval = (on) ? 1 : 0;
00659
00660 if (setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void*) &optval, sizeof(optval)) < 0) {
00661 THROW2(SocketException, "setsockopt()");
00662 }
00663 #else
00664 THROW(SocketException, "SO_NOSIGPIPE not defined");
00665 #endif
00666 }
00667
00668 bool Socket::getSoAcceptConn(void) const throw (SocketException) {
00669 int accept = 0;
00670 #ifdef SO_ACCEPTCONN
00671 socklen_t len = sizeof(accept);
00672
00673 if (getsockopt(s, SOL_SOCKET, SO_ACCEPTCONN, (void*) &accept, &len) < 0) {
00674 THROW2(SocketException, "getsockopt()");
00675 }
00676 #else
00677 THROW(SocketException, "SO_ACCEPTCONN not defined");
00678 #endif
00679
00680 return (accept) ? true : false;
00681 }
00682
00683 void Socket::setSoBindToDevice(const std::string &interface) throw (SocketException) {
00684 #ifdef SO_BINDTODEVICE
00685 #if 0
00686 struct ifreq ifr;
00687
00688 memset(&ifr, 0, sizeof(ifr));
00689 strncpy(ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name));
00690
00691 if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (void*) &ifr, sizeof(ifr)) < 0) {
00692 THROW2(SocketException, "setsockopt()");
00693 }
00694 #else
00695 size_t len = (interface.size() > IFNAMSIZ - 1) ? IFNAMSIZ - 1 : interface.size();
00696
00697 if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface.c_str(), len) < 0) {
00698 THROW2(SocketException, "setsockopt()");
00699 }
00700 #endif
00701 #else
00702 THROW(SocketException, "SO_BINDTODEVICE not defined");
00703 #endif
00704 }
00705
00706 void Socket::setSoBroadcast(bool on) throw (SocketException) {
00707 #ifdef SO_BROADCAST
00708 int optval = (on) ? 1 : 0;
00709
00710 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (void*) &optval, sizeof(optval)) < 0) {
00711 THROW2(SocketException, "setsockopt()");
00712 }
00713 #else
00714 THROW(SocketException, "SO_BROADCAST not defined");
00715 #endif
00716 }
00717
00718 void Socket::setSoDebug(bool on) throw (SocketException) {
00719 #ifdef SO_DEBUG
00720 int optval = (on) ? 1 : 0;
00721
00722 if (setsockopt(s, SOL_SOCKET, SO_DEBUG, (void*) &optval, sizeof(optval)) < 0) {
00723 THROW2(SocketException, "setsockopt()");
00724 }
00725 #else
00726 THROW(SocketException, "SO_DEBUG not defined");
00727 #endif
00728 }
00729
00730 int Socket::getSoError(void) const throw (SocketException) {
00731 int error = 0;
00732 #ifdef SO_ERROR
00733 socklen_t len = sizeof(error);
00734
00735 if (getsockopt(s, SOL_SOCKET, SO_ERROR, (void*) &error, &len) < 0) {
00736 THROW2(SocketException, "getsockopt()");
00737 }
00738 #else
00739 THROW(SocketException, "SO_ERROR not defined");
00740 #endif
00741
00742 return error;
00743 }
00744
00745 void Socket::setSoDontRoute(bool on) throw (SocketException) {
00746 #ifdef SO_DONTROUTE
00747 int optval = (on) ? 1 : 0;
00748
00749 if (setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (void*) &optval, sizeof(optval)) < 0) {
00750 THROW2(SocketException, "setsockopt()");
00751 }
00752 #else
00753 THROW(SocketException, "SO_DONTROUTE not defined");
00754 #endif
00755 }
00756
00757 void Socket::setSoLinger(int onoff, int linger) throw (SocketException) {
00758 #ifdef SO_LINGER
00759 struct linger l;
00760 l.l_onoff = onoff;
00761 l.l_linger = linger;
00762
00763 if (setsockopt(s, SOL_SOCKET, SO_LINGER, (void*) &l, sizeof(struct linger)) < 0) {
00764 THROW2(SocketException, "setsockopt()");
00765 }
00766 #else
00767 THROW(SocketException, "SO_LINGER not defined");
00768 #endif
00769 }
00770
00771 void Socket::setSoPriority(int pri) throw (SocketException) {
00772 #ifdef SO_PRIORITY
00773 if (setsockopt(s, SOL_SOCKET, SO_PRIORITY, (void*) &pri, sizeof(pri)) < 0) {
00774 THROW2(SocketException, "setsockopt()");
00775 }
00776 #else
00777 THROW(SocketException, "SO_DONTROUTE not defined");
00778 #endif
00779 }
00780
00781 void Socket::setSoRcvTimeo(struct timeval &tv) throw (SocketException) {
00782 #ifdef SO_RCVTIMEO
00783 if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (void*) &tv, sizeof(struct timeval)) < 0) {
00784 THROW2(SocketException, "setsockopt()");
00785 }
00786 #else
00787 THROW(SocketException, "SO_RCVTIMEO not defined");
00788 #endif
00789 }
00790
00791 void Socket::setSoSndTimeo(struct timeval &tv) throw (SocketException) {
00792 #ifdef SO_SNDTIMEO
00793 if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (void*) &tv, sizeof(struct timeval)) < 0) {
00794 THROW2(SocketException, "setsockopt()");
00795 }
00796 #else
00797 THROW(SocketException, "SO_SNDTIMEO not defined");
00798 #endif
00799 }
00800
00801 void Socket::setSoRcvBuf(int bytes) throw (SocketException) {
00802 #ifdef SO_RCVBUF
00803 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void*) &bytes, sizeof(bytes)) < 0) {
00804 THROW2(SocketException, "setsockopt()");
00805 }
00806 #else
00807 THROW(SocketException, "SO_RCVBUF not defined");
00808 #endif
00809 }
00810
00811 void Socket::setSoRcvBufForce(int bytes) throw (SocketException) {
00812 #ifdef SO_RCVBUFFORCE
00813 if (setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, (void*) &bytes, sizeof(bytes)) < 0) {
00814 THROW2(SocketException, "setsockopt()");
00815 }
00816 #else
00817 THROW(SocketException, "SO_RCVBUFFORCE not defined");
00818 #endif
00819 }
00820
00821 int Socket::getSoRcvBuf(void) const throw (SocketException) {
00822 int bytes = 0;
00823 #ifdef SO_RCVBUF
00824 socklen_t len = sizeof(bytes);
00825
00826 if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, (void*) &bytes, &len) < 0) {
00827 THROW2(SocketException, "getsockopt()");
00828 }
00829 #else
00830 THROW(SocketException, "SO_RCVBUF not defined");
00831 #endif
00832
00833 return bytes;
00834 }
00835
00836 void Socket::setSoSndBuf(int bytes) throw (SocketException) {
00837 #ifdef SO_SNDBUF
00838 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*) &bytes, sizeof(bytes)) < 0) {
00839 THROW2(SocketException, "setsockopt()");
00840 }
00841 #else
00842 THROW(SocketException, "SO_SNDBUF not defined");
00843 #endif
00844 }
00845
00846 void Socket::setSoSndBufForce(int bytes) throw (SocketException) {
00847 #ifdef SO_SNDBUFFORCE
00848 if (setsockopt(s, SOL_SOCKET, SO_SNDBUFFORCE, (void*) &bytes, sizeof(bytes)) < 0) {
00849 THROW2(SocketException, "setsockopt()");
00850 }
00851 #else
00852 THROW(SocketException, "SO_SNDBUFFORCE not defined");
00853 #endif
00854 }
00855
00856 int Socket::getSoSndBuf(void) const throw (SocketException) {
00857 int bytes = 0;
00858 #ifdef SO_SNDBUF
00859 socklen_t len = sizeof(bytes);
00860
00861 if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*) &bytes, &len) < 0) {
00862 THROW2(SocketException, "getsockopt()");
00863 }
00864 #else
00865 THROW(SocketException, "SO_SNDBUF not defined");
00866 #endif
00867
00868 return bytes;
00869 }
00870
00871 void Socket::setSoTimestamp(bool on) throw (SocketException) {
00872 #ifdef SO_TIMESTAMP
00873 int optval = (on) ? 1 : 0;
00874
00875 if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, (void*)optval, sizeof(optval)) < 0) {
00876 THROW2(SocketException, "setsockopt()");
00877 }
00878 #else
00879 THROW(SocketException, "SO_TIMESTAMP not defined");
00880 #endif
00881 }
00882
00883 int Socket::getSoType(void) throw (SocketException) {
00884 int type = 0;
00885 #ifdef SO_TYPE
00886 socklen_t len = sizeof(type);
00887
00888 if (getsockopt(s, SOL_SOCKET, SO_TYPE, (void*) &type, &len) < 0) {
00889 THROW2(SocketException, "getsockopt()");
00890 }
00891 #else
00892 THROW(SocketException, "SO_TYPE not defined");
00893 #endif
00894
00895 return type;
00896 }
00897
00898
00899 void Socket::setIpv6V6Only(bool on) throw (SocketException) {
00900 #ifdef IPV6_V6ONLY
00901 int optval = (on) ? 1 : 0;
00902
00903 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &optval, sizeof(optval)) < 0) {
00904 THROW2(SocketException, "setsockopt()");
00905 }
00906 #else
00907 THROW(SocketException, "IPV6_V6ONLY not defined");
00908 #endif
00909 }
00910
00911 bool Socket::getIpv6V6Only(void) const throw (SocketException) {
00912 int optval = 0;
00913 #ifdef IPV6_V6ONLY
00914 socklen_t len = sizeof(optval);
00915
00916 if (getsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &optval, &len) < 0) {
00917 THROW2(SocketException, "getsockopt()");
00918 }
00919 #else
00920 THROW(SocketException, "IPV6_V6ONLY not defined");
00921 #endif
00922
00923 return (optval) ? true : false;
00924 }
00925
00926
00927 void Socket::mmapRingBuffer(unsigned char **ring, struct tpacket_req &req) throw (SocketException) {
00928 if ((*ring = (unsigned char*) mmap(0, req.tp_block_size * req.tp_block_nr, PROT_READ | PROT_WRITE, MAP_SHARED, s, 0)) == NULL) {
00929 THROW2(SocketException, "mmap()");
00930 }
00931 }
00932
00933 void Socket::munmapRingBuffer(unsigned char **ring, struct tpacket_req &req) throw (SocketException) {
00934 if (munmap(*ring, req.tp_block_size) > 0) {
00935 THROW2(SocketException, "munmap()");
00936 }
00937
00938 ring = NULL;
00939 }
00940
00941 void Socket::setPacketRxRing(struct tpacket_req &req, int version) throw (SocketException) {
00942 #ifdef PACKET_VERSION
00943 if (setsockopt(s, SOL_PACKET, PACKET_VERSION, (void*) &version, sizeof(version)) < 0) {
00944 THROW2(SocketException, "setsockopt()");
00945 }
00946 #else
00947 THROW(SocketException, "PACKET_VERSION not defined");
00948 #endif
00949
00950 #ifdef PACKET_RX_RING
00951 if (setsockopt(s, SOL_PACKET, PACKET_RX_RING, (void*) &req, sizeof(req)) < 0) {
00952 THROW2(SocketException, "setsockopt()");
00953 }
00954 #else
00955 THROW(SocketException, "PACKET_RX_RING not defined");
00956 #endif
00957 }
00958
00959 void Socket::setPacketTxRing(struct tpacket_req &req, int version) throw (SocketException) {
00960 #ifdef PACKET_VERSION
00961 if (setsockopt(s, SOL_PACKET, PACKET_VERSION, (void*) &version, sizeof(version)) < 0) {
00962 THROW2(SocketException, "setsockopt()");
00963 }
00964 #else
00965 THROW(SocketException, "PACKET_VERSION not defined");
00966 #endif
00967
00968 #ifdef PACKET_TX_RING
00969 if (setsockopt(s, SOL_PACKET, PACKET_TX_RING, (void*) &req, sizeof(req)) < 0) {
00970 THROW2(SocketException, "setsockopt()");
00971 }
00972 #else
00973 THROW(SocketException, "PACKET_TX_RING not defined");
00974 #endif
00975 }
00976
00977 void Socket::setPacketLoss(bool drop) throw (SocketException) {
00978 int optval = (drop) ? 1 : 0;
00979
00980 #ifdef PACKET_LOSS
00981 if (setsockopt(s, SOL_PACKET, PACKET_LOSS, (void*) optval, sizeof(optval)) < 0) {
00982 THROW2(SocketException, "setsockopt()");
00983 }
00984 #else
00985 THROW(SocketException, "PACKET_TX_RING not defined");
00986 #endif
00987 }
00988
00989 int Socket::getPacketHdrLen(int version) throw (SocketException) {
00990 int ret;
00991 socklen_t len = sizeof(version);
00992
00993 #ifdef PACKET_LOSS
00994 if ((ret = getsockopt(s, SOL_PACKET, PACKET_HDRLEN, (void*) &version, &len)) < 0) {
00995 THROW2(SocketException, "getsockopt()");
00996 }
00997 #else
00998 THROW(SocketException, "PACKET_HDRLEN not defined");
00999 #endif
01000
01001 return ret;
01002 }
01003
01004 void Socket::initAddr(int family, const std::string &address, unsigned short port, sockaddr_storage &addr, socklen_t addrlen) throw (SocketException) {
01005 union __sockaddr_union u;
01006 u.ss = (struct sockaddr_storage*) &addr;
01007
01008 memset(&addr, 0, addrlen);
01009 u.ss->ss_family = family;
01010
01011 if (family != AF_INET && family != AF_INET6) {
01012 THROW(SocketException, "Only family AF_INET and AF_INET6 and AF_PACKET are implemented");
01013 }
01014
01015 if (address.empty()) {
01016 if (family == AF_INET) {
01017 u.sa_in->sin_addr.s_addr = htonl(INADDR_ANY);
01018 } else {
01019 u.sa_in6->sin6_addr = in6addr_any;
01020 }
01021 } else {
01022 int s;
01023 struct addrinfo hints, *result, *rp;
01024
01025 memset(&hints, 0, sizeof(struct addrinfo));
01026 hints.ai_family = family;
01027 hints.ai_socktype = SOCK_DGRAM;
01028 hints.ai_flags = AI_PASSIVE;
01029 hints.ai_protocol = 0;
01030 hints.ai_canonname = NULL;
01031 hints.ai_addr = NULL;
01032 hints.ai_next = NULL;
01033
01034 if ((s = getaddrinfo(address.c_str(), NULL, &hints, &result)) != 0) {
01035 THROW(SocketException, "getaddrinfo() failed: %s", gai_strerror(s));
01036 }
01037
01038 for (rp = result; rp != NULL; rp = rp->ai_next) {
01039 if (family == rp->ai_family) {
01040 if (rp->ai_family == AF_INET) {
01041 memcpy(u.sa_in, rp->ai_addr, rp->ai_addrlen);
01042 } else if (rp->ai_family == AF_INET6) {
01043 memcpy(u.sa_in6, rp->ai_addr, rp->ai_addrlen);
01044 }
01045
01046 break;
01047 }
01048
01049 if (rp->ai_next == NULL) {
01050 THROW(SocketException, "Failed to locate an IPv4 or IPv6 address for %s", address.c_str());
01051 }
01052 }
01053 }
01054
01055 IPAddress x(u.ss);
01056
01057 if (family == AF_INET) {
01058 u.sa_in->sin_port = htons(port);
01059 } else {
01060 u.sa_in6->sin6_port = htons(port);
01061 }
01062 }
01063
01064 unsigned short Socket::resolveService(const std::string &service, const std::string &protocol) throw (SocketException) {
01065 struct servent serv, *result = NULL;
01066 char buf[1024];
01067 long int ret;
01068
01069 if (getservbyname_r(service.c_str(), protocol.c_str(), &serv, buf, sizeof(buf), &result) != 0) {
01070 THROW2(SocketException, "getservbyname()");
01071 }
01072
01073 if (result != NULL) {
01074 return ntohs(result->s_port);
01075 } else if (!isdigit(service.c_str()[0])) {
01076 THROW(SocketException, "unresolveable service");
01077 }
01078
01079 ret = strtol(service.c_str(), (char **) NULL, 10);
01080 if (ret < 1 || ret > 65535) {
01081 THROW2(SocketException, "port out of range");
01082 }
01083
01084 return ret;
01085 }
01086
01087
01088
01089