9 static const char rcsid[] __attribute__((used)) =
"$Id: Socket.cpp 1653 2016-02-28 19:54:59Z sella $";
20 #include <arpa/inet.h>
21 #include <sys/ioctl.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
25 #include <netinet/in.h>
29 using namespace sella::net;
35 struct sockaddr_storage *ss;
37 struct sockaddr_in *sa_in;
38 struct sockaddr_in6 *sa_in6;
39 struct sockaddr_un *sa_un;
42 Socket::Socket(
int s)
throw (SocketException) : usable(
false), mux(
false), read(
false), write(
false), except(
false) {
43 sockaddr_storage addr;
44 socklen_t addrlen =
sizeof(sockaddr_storage);
46 if (s < 0 || s > FD_SETSIZE) {
47 THROW(SocketException,
"Passed invalid socket (%d)", s);
50 if (getsockname(s, (sockaddr *) &addr, &addrlen) < 0) {
51 THROW2(SocketException,
"getsockname()");
54 if (addr.ss_family < 1 || addr.ss_family >= AF_MAX) {
55 THROW(SocketException,
"Family (%d) is invalid", addr.ss_family);
58 if (addr.ss_family != AF_INET && addr.ss_family != AF_INET6 && addr.ss_family != AF_PACKET && addr.ss_family != AF_UNIX) {
59 THROW(SocketException,
"Only addr.ss_family AF_INET, AF_INET6, AF_PACKET and AF_UNIX are implemented");
62 this->family = addr.ss_family;
66 Socket::Socket(
int family,
int type,
int protocol)
throw (SocketException) : s(-1), family(family), usable(
false), mux(
false), read(
false), write(
false), except(
false) {
67 if (family < 1 || family >= AF_MAX) {
68 THROW(SocketException,
"Family (%d) is invalid", family);
71 if (family != AF_INET && family != AF_INET6 && family != AF_PACKET && family != AF_UNIX) {
72 THROW(SocketException,
"Only family AF_INET, AF_INET6, AF_PACKET and AF_UNIX are implemented");
76 THROW(SocketException,
"Socket type (%d) is invalid", type);
80 THROW(SocketException,
"Protocol (%d) is invalid", protocol);
83 if ((this->s = ::socket(family, type, protocol)) < 0) {
84 THROW2(SocketException,
"socket()");
90 read = write = except =
false;
95 void Socket::bind(
const IPAddressPort &addressport)
throw (SocketException) {
96 bind(addressport.getIPAddress().str(), addressport.getPort().get());
99 void Socket::bind(
const IPAddress &address,
const Port &port)
throw (SocketException) {
100 bind(address.str(), port.get());
103 void Socket::bind(
const std::string &address,
const unsigned short port)
throw (SocketException) {
104 sockaddr_storage addr;
105 socklen_t addrlen =
sizeof(sockaddr_storage);
107 initAddr(family, address, port, addr, addrlen);
109 addr.ss_family = family;
111 if (::bind(s, (sockaddr *) &addr, addrlen) < 0) {
112 THROW2(SocketException,
"bind()");
118 void Socket::connect(
const IPAddressPort &addressport)
throw (SocketException) {
119 connect(addressport.getIPAddress().str(), addressport.getPort().get());
122 void Socket::connect(
const IPAddress &address,
const Port &port)
throw (SocketException) {
123 connect(address.str(), port.get());
126 void Socket::connect(
const std::string &address,
const unsigned short port)
throw (SocketException) {
127 sockaddr_storage addr;
128 socklen_t addrlen =
sizeof(sockaddr_storage);
130 initAddr(family, address, port, addr, addrlen);
132 if (::connect(s, (sockaddr *) &addr, addrlen) < 0) {
135 THROW2(SocketException,
"connect()");
141 void Socket::close(
void) throw (SocketException) {
145 if (::close(s) < 0) {
146 THROW2(SocketException,
"close()");
153 ssize_t Socket::send(
const void *data,
size_t len,
int flags)
throw (SocketException) {
158 if ((c = ::send(s, data, len, flags)) < 0) {
165 #if ((EAGAIN) != (EWOULDBLOCK))
169 if ((flags & MSG_DONTWAIT) || ((flg = fcntl(s, F_GETFL)) != -1 && (flg & O_NONBLOCK))) {
170 THROW_CODE(SocketException, EWOULDBLOCK,
"Nonblocking socket would have blocked");
173 THROW_CODE(SocketException, EWOULDBLOCK,
"Send timed out");
179 THROW2(SocketException,
"send()");
183 }
while ((r -= c) > 0);
190 ssize_t Socket::send(
const std::string &data,
int flags)
throw (SocketException) {
191 return send((
const void*) data.c_str(), data.size(), flags);
194 ssize_t Socket::send(
const std::vector<uint8_t> &data,
int flags)
throw (SocketException) {
195 return send((
const void*) data.data(), data.size(), flags);
198 ssize_t Socket::recv(
void *buf,
size_t len,
int flags)
throw (SocketException) {
202 if ((c = ::recv(s, buf, len, flags)) < 0) {
207 #if ((EAGAIN) != (EWOULDBLOCK))
211 read = except =
false;
213 if ((flags & MSG_DONTWAIT) || ((flg = fcntl(s, F_GETFL)) != -1 && (flg & O_NONBLOCK))) {
214 THROW_CODE(SocketException, EWOULDBLOCK,
"Nonblocking socket would have blocked");
217 THROW_CODE(SocketException, EWOULDBLOCK,
"Receive timed out");
223 THROW2(SocketException,
"recv()");
228 read = except =
false;
233 ssize_t Socket::recv(std::string &data,
size_t len,
int flags)
throw (SocketException) {
235 ssize_t size = recv(buf, len, flags);
237 std::string(buf, buf + size).swap(data);
242 ssize_t Socket::recv(std::vector<uint8_t> &data,
size_t len,
int flags)
throw (SocketException) {
244 ssize_t size = recv(buf, len, flags);
246 std::vector<uint8_t>(buf, buf + size).swap(data);
251 int Socket::getFD(
void)
const {
255 bool Socket::isRead(
void)
const {
259 bool Socket::isWrite(
void)
const {
263 bool Socket::isExcept(
void)
const {
267 bool Socket::hasData(
void)
const throw (SocketException) {
268 return (getQueuedBytes() > 0);
271 int Socket::getQueuedBytes(
void)
const throw (SocketException) {
274 if (ioctl(s, FIONREAD, &count) == -1) {
275 THROW2(SocketException,
"ioctl()");
281 IPAddressPort Socket::getLocalIPAddressPort(
void)
const throw (SocketException) {
282 sockaddr_storage addr;
283 socklen_t addrlen =
sizeof(sockaddr_storage);
285 if (getsockname(s, (sockaddr *) &addr, &addrlen) < 0) {
286 THROW2(SocketException,
"getsockname()");
292 IPAddress Socket::getLocalIPAddress(
void)
const throw (SocketException) {
293 sockaddr_storage addr;
294 socklen_t addrlen =
sizeof(sockaddr_storage);
296 if (getsockname(s, (sockaddr *) &addr, &addrlen) < 0) {
297 THROW2(SocketException,
"getsockname()");
303 Port Socket::getLocalPort(
void)
const throw (SocketException) {
304 sockaddr_storage addr;
305 socklen_t addrlen =
sizeof(sockaddr_storage);
307 if (getsockname(s, (sockaddr *) &addr, &addrlen) < 0) {
308 THROW2(SocketException,
"getsockname()");
314 IPAddressPort Socket::getRemoteIPAddressPort(
void)
const throw (SocketException) {
315 sockaddr_storage addr;
316 socklen_t addrlen =
sizeof(sockaddr_storage);
318 if (getpeername(s, (sockaddr *) &addr, &addrlen) < 0) {
319 THROW2(SocketException,
"getpeername()");
325 IPAddress Socket::getRemoteIPAddress(
void)
const throw (SocketException) {
326 sockaddr_storage addr;
327 socklen_t addrlen =
sizeof(sockaddr_storage);
329 if (getpeername(s, (sockaddr *) &addr, &addrlen) < 0) {
330 THROW2(SocketException,
"getpeername()");
336 Port Socket::getRemotePort(
void)
const throw (SocketException) {
337 sockaddr_storage addr;
338 socklen_t addrlen =
sizeof(sockaddr_storage);
340 if (getpeername(s, (sockaddr *) &addr, &addrlen) < 0) {
341 THROW2(SocketException,
"getpeername()");
347 int Socket::getFamily(
void)
const throw () {
351 bool Socket::isUsable(
void)
const throw () {
352 if (s < 0 || !(fcntl(s, F_GETFD) != -1 || errno != EBADF)) {
359 bool Socket::hasMux(
void)
const throw () {
363 bool Socket::isSecure(
void)
const throw () {
367 void Socket::setBlock(
bool on)
throw (SocketException) {
370 if ((flags = fcntl(s, F_GETFL)) < 0) {
371 THROW2(SocketException,
"fcntl()");
375 flags &= ~O_NONBLOCK;
380 if (fcntl(s, F_SETFL, flags) < 0) {
381 THROW2(SocketException,
"fcntl()");
385 bool Socket::isBlock(
void) throw (SocketException) {
388 if ((flags = fcntl(s, F_GETFL)) < 0) {
389 THROW2(SocketException,
"fcntl()");
392 return (flags & O_NONBLOCK);
395 void Socket::setIpOptions(
const void *optval, socklen_t len)
throw (SocketException) {
397 if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, (
void*) optval, len) < 0) {
398 THROW2(SocketException,
"setsockopt()");
401 THROW(SocketException,
"IP_OPTIONS not defined");
405 void Socket::setIpPktInfo(
bool on)
throw (SocketException) {
407 int optval = (on) ? 1 : 0;
409 if (setsockopt(s, IPPROTO_IP, IP_PKTINFO, (
void*) &optval,
sizeof(optval)) < 0) {
410 THROW2(SocketException,
"setsockopt()");
413 THROW(SocketException,
"IP_PKTINFO not defined");
417 void Socket::setIpRecvTOS(
bool on)
throw (SocketException) {
419 int optval = (on) ? 1 : 0;
421 if (setsockopt(s, IPPROTO_IP, IP_RECVTOS, (
void*) &optval,
sizeof(optval)) < 0) {
422 THROW2(SocketException,
"setsockopt()");
425 THROW(SocketException,
"IP_RECVTOS not defined");
429 void Socket::setIpRecvTTL(
bool on)
throw (SocketException) {
431 int optval = (on) ? 1 : 0;
433 if (setsockopt(s, IPPROTO_IP, IP_RECVTTL, (
void*) &optval,
sizeof(optval)) < 0) {
434 THROW2(SocketException,
"setsockopt()");
437 THROW(SocketException,
"IP_RECVTTL not defined");
441 void Socket::setIpRecvOpts(
bool on)
throw (SocketException) {
443 int optval = (on) ? 1 : 0;
445 if (setsockopt(s, IPPROTO_IP, IP_RECVOPTS, (
void*) &optval,
sizeof(optval)) < 0) {
446 THROW2(SocketException,
"setsockopt()");
449 THROW(SocketException,
"IP_RECVOPTS not defined");
453 void Socket::setIpRetOpts(
bool on)
throw (SocketException) {
455 int optval = (on) ? 1 : 0;
457 if (setsockopt(s, IPPROTO_IP, IP_RETOPTS, (
void*) &optval,
sizeof(optval)) < 0) {
458 THROW2(SocketException,
"setsockopt()");
461 THROW(SocketException,
"IP_RETOPTS not defined");
465 void Socket::setIpTOS(
unsigned char tos)
throw (SocketException) {
467 if (setsockopt(s, IPPROTO_IP, IP_TOS, (
void*) &tos,
sizeof(tos)) < 0) {
468 THROW2(SocketException,
"setsockopt()");
471 THROW(SocketException,
"IP_TOS not defined");
475 unsigned char Socket::getIpTOS(
void)
const throw (SocketException) {
476 unsigned char tos = 0;
479 socklen_t len =
sizeof(tos);
481 if (getsockopt(s, IPPROTO_IP, IP_TOS, (
void*) &tos, &len) < 0) {
482 THROW2(SocketException,
"getsockopt()");
485 THROW(SocketException,
"IP_TOS not defined");
491 void Socket::setIpTTL(
int ttl)
throw (SocketException) {
493 if (setsockopt(s, IPPROTO_IP, IP_TTL, (
void*) &ttl,
sizeof(ttl)) < 0) {
494 THROW2(SocketException,
"setsockopt()");
497 THROW(SocketException,
"IP_TTL not defined");
501 int Socket::getIpTTL(
void)
const throw (SocketException) {
504 socklen_t len =
sizeof(ttl);
506 if (getsockopt(s, IPPROTO_IP, IP_TTL, (
void*) &ttl, &len) < 0) {
507 THROW2(SocketException,
"getsockopt()");
510 THROW(SocketException,
"IP_TTL not defined");
516 void Socket::setIpHdrIncl(
bool on)
throw (SocketException) {
518 int optval = (on) ? 1 : 0;
520 if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, (
void*) &optval,
sizeof(optval)) < 0) {
521 THROW2(SocketException,
"setsockopt()");
524 THROW(SocketException,
"IP_HDRINCL not defined");
528 void Socket::setIpRecvErr(
bool on)
throw (SocketException) {
530 int optval = (on) ? 1 : 0;
532 if (setsockopt(s, IPPROTO_IP, IP_RECVERR, (
void*) &optval,
sizeof(optval)) < 0) {
533 THROW2(SocketException,
"setsockopt()");
536 THROW(SocketException,
"IP_RECVERR not defined");
540 void Socket::setIpMtuDiscover(
bool on)
throw (SocketException) {
541 #ifdef IP_MTU_DISCOVER
542 int optval = (on) ? 1 : 0;
544 if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, (
void*) &optval,
sizeof(optval)) < 0) {
545 THROW2(SocketException,
"setsockopt()");
548 THROW(SocketException,
"IP_MTU_DISCOVER not defined");
552 int Socket::getIpMtu(
void)
const throw (SocketException) {
556 socklen_t len =
sizeof(mtu);
558 if (getsockopt(s, IPPROTO_IP, IP_MTU, (
void*) &mtu, &len) < 0) {
559 THROW2(SocketException,
"getsockopt()");
562 THROW(SocketException,
"IP_MTU not defined");
568 void Socket::setIpRouterAlert(
bool on)
throw (SocketException) {
569 #ifdef IP_ROUTER_ALERT
570 int optval = (on) ? 1 : 0;
572 if (setsockopt(s, IPPROTO_IP, IP_ROUTER_ALERT, (
void*) &optval,
sizeof(optval)) < 0) {
573 THROW2(SocketException,
"setsockopt()");
576 THROW(SocketException,
"IP_ROUTER_ALERT not defined");
580 void Socket::setIpMulticastTTL(
int ttl)
throw (SocketException) {
581 #ifdef IP_MULTICAST_TTL
582 if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (
void*) &ttl,
sizeof(ttl)) < 0) {
583 THROW2(SocketException,
"setsockopt()");
586 THROW(SocketException,
"IP_MULTICAST_TTL not defined");
590 int Socket::getIpMulticastTTL(
void)
const throw (SocketException) {
594 socklen_t len =
sizeof(ttl);
596 if (getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (
void*) &ttl, &len) < 0) {
597 THROW2(SocketException,
"getsockopt()");
600 THROW(SocketException,
"IP_MULTICAST_TTL not defined");
606 void Socket::setIpMulticastLoop(
bool on)
throw (SocketException) {
607 #ifdef IP_MULTICAST_LOOP
608 int optval = (on) ? 1 : 0;
610 if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (
void*) &optval,
sizeof(optval)) < 0) {
611 THROW2(SocketException,
"setsockopt()");
614 THROW(SocketException,
"IP_MULTICAST_LOOP not defined");
618 void Socket::setIpAddMembership(
struct ip_mreqn& m)
throw (SocketException) {
619 #ifdef IP_ADD_MEMBERSHIP
620 if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (
void*) &m,
sizeof(
struct ip_mreqn)) < 0) {
621 THROW2(SocketException,
"setsockopt()");
624 THROW(SocketException,
"IP_ADD_MEMBERSHIP not defined");
628 void Socket::setIpDropMembership(
struct ip_mreqn& m)
throw (SocketException) {
629 #ifdef IP_DROP_MEMBERSHIP
630 if (setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, (
void*) &m,
sizeof(
struct ip_mreqn)) < 0) {
631 THROW2(SocketException,
"setsockopt()");
634 THROW(SocketException,
"IP_DROP_MEMBERSHIP not defined");
638 void Socket::setSoReuseAddr(
bool on)
throw (SocketException) {
640 int optval = (on) ? 1 : 0;
642 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (
void*) &optval,
sizeof(optval)) < 0) {
643 THROW2(SocketException,
"setsockopt()");
646 THROW(SocketException,
"SO_REUSEADDR not defined");
650 void Socket::setSoKeepAlive(
bool on)
throw (SocketException) {
652 int optval = (on) ? 1 : 0;
654 if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (
void*) &optval,
sizeof(optval)) < 0) {
655 THROW2(SocketException,
"setsockopt()");
658 THROW(SocketException,
"SO_KEEPALIVE not defined");
662 void Socket::setSoNoSigPipe(
bool on)
throw (SocketException) {
664 int optval = (on) ? 1 : 0;
666 if (setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (
void*) &optval,
sizeof(optval)) < 0) {
667 THROW2(SocketException,
"setsockopt()");
670 THROW(SocketException,
"SO_NOSIGPIPE not defined");
674 bool Socket::getSoAcceptConn(
void)
const throw (SocketException) {
677 socklen_t len =
sizeof(accept);
679 if (getsockopt(s, SOL_SOCKET, SO_ACCEPTCONN, (
void*) &accept, &len) < 0) {
680 THROW2(SocketException,
"getsockopt()");
683 THROW(SocketException,
"SO_ACCEPTCONN not defined");
686 return (accept) ?
true :
false;
689 void Socket::setSoBindToDevice(
const std::string &interface)
throw (SocketException) {
690 #ifdef SO_BINDTODEVICE
694 memset(&ifr, 0,
sizeof(ifr));
695 strncpy(ifr.ifr_name, interface.c_str(),
sizeof(ifr.ifr_name));
697 if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (
void*) &ifr,
sizeof(ifr)) < 0) {
698 THROW2(SocketException,
"setsockopt()");
701 size_t len = (interface.size() > IFNAMSIZ - 1) ? IFNAMSIZ - 1 : interface.size();
703 if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface.c_str(), len) < 0) {
704 THROW2(SocketException,
"setsockopt()");
708 THROW(SocketException,
"SO_BINDTODEVICE not defined");
712 void Socket::setSoBroadcast(
bool on)
throw (SocketException) {
714 int optval = (on) ? 1 : 0;
716 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (
void*) &optval,
sizeof(optval)) < 0) {
717 THROW2(SocketException,
"setsockopt()");
720 THROW(SocketException,
"SO_BROADCAST not defined");
724 void Socket::setSoDebug(
bool on)
throw (SocketException) {
726 int optval = (on) ? 1 : 0;
728 if (setsockopt(s, SOL_SOCKET, SO_DEBUG, (
void*) &optval,
sizeof(optval)) < 0) {
729 THROW2(SocketException,
"setsockopt()");
732 THROW(SocketException,
"SO_DEBUG not defined");
736 int Socket::getSoError(
void)
const throw (SocketException) {
739 socklen_t len =
sizeof(error);
741 if (getsockopt(s, SOL_SOCKET, SO_ERROR, (
void*) &error, &len) < 0) {
742 THROW2(SocketException,
"getsockopt()");
745 THROW(SocketException,
"SO_ERROR not defined");
751 void Socket::setSoDontRoute(
bool on)
throw (SocketException) {
753 int optval = (on) ? 1 : 0;
755 if (setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (
void*) &optval,
sizeof(optval)) < 0) {
756 THROW2(SocketException,
"setsockopt()");
759 THROW(SocketException,
"SO_DONTROUTE not defined");
763 void Socket::setSoLinger(
int onoff,
int linger)
throw (SocketException) {
769 if (setsockopt(s, SOL_SOCKET, SO_LINGER, (
void*) &l,
sizeof(
struct linger)) < 0) {
770 THROW2(SocketException,
"setsockopt()");
773 THROW(SocketException,
"SO_LINGER not defined");
777 void Socket::setSoPriority(
int pri)
throw (SocketException) {
779 if (setsockopt(s, SOL_SOCKET, SO_PRIORITY, (
void*) &pri,
sizeof(pri)) < 0) {
780 THROW2(SocketException,
"setsockopt()");
783 THROW(SocketException,
"SO_DONTROUTE not defined");
787 void Socket::setSoRcvTimeo(
struct timeval &tv)
throw (SocketException) {
789 if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (
void*) &tv,
sizeof(
struct timeval)) < 0) {
790 THROW2(SocketException,
"setsockopt()");
793 THROW(SocketException,
"SO_RCVTIMEO not defined");
797 void Socket::setSoSndTimeo(
struct timeval &tv)
throw (SocketException) {
799 if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (
void*) &tv,
sizeof(
struct timeval)) < 0) {
800 THROW2(SocketException,
"setsockopt()");
803 THROW(SocketException,
"SO_SNDTIMEO not defined");
807 void Socket::setSoRcvBuf(
int bytes)
throw (SocketException) {
809 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (
void*) &bytes,
sizeof(bytes)) < 0) {
810 THROW2(SocketException,
"setsockopt()");
813 THROW(SocketException,
"SO_RCVBUF not defined");
817 void Socket::setSoRcvBufForce(
int bytes)
throw (SocketException) {
818 #ifdef SO_RCVBUFFORCE
819 if (setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, (
void*) &bytes,
sizeof(bytes)) < 0) {
820 THROW2(SocketException,
"setsockopt()");
823 THROW(SocketException,
"SO_RCVBUFFORCE not defined");
827 int Socket::getSoRcvBuf(
void)
const throw (SocketException) {
830 socklen_t len =
sizeof(bytes);
832 if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, (
void*) &bytes, &len) < 0) {
833 THROW2(SocketException,
"getsockopt()");
836 THROW(SocketException,
"SO_RCVBUF not defined");
842 void Socket::setSoSndBuf(
int bytes)
throw (SocketException) {
844 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (
void*) &bytes,
sizeof(bytes)) < 0) {
845 THROW2(SocketException,
"setsockopt()");
848 THROW(SocketException,
"SO_SNDBUF not defined");
852 void Socket::setSoSndBufForce(
int bytes)
throw (SocketException) {
853 #ifdef SO_SNDBUFFORCE
854 if (setsockopt(s, SOL_SOCKET, SO_SNDBUFFORCE, (
void*) &bytes,
sizeof(bytes)) < 0) {
855 THROW2(SocketException,
"setsockopt()");
858 THROW(SocketException,
"SO_SNDBUFFORCE not defined");
862 int Socket::getSoSndBuf(
void)
const throw (SocketException) {
865 socklen_t len =
sizeof(bytes);
867 if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, (
void*) &bytes, &len) < 0) {
868 THROW2(SocketException,
"getsockopt()");
871 THROW(SocketException,
"SO_SNDBUF not defined");
877 void Socket::setSoTimestamp(
bool on)
throw (SocketException) {
879 int optval = (on) ? 1 : 0;
881 if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, (
void*) &optval, (socklen_t)
sizeof(optval)) < 0) {
882 THROW2(SocketException,
"setsockopt()");
885 THROW(SocketException,
"SO_TIMESTAMP not defined");
889 int Socket::getSoType(
void) throw (SocketException) {
892 socklen_t len =
sizeof(type);
894 if (getsockopt(s, SOL_SOCKET, SO_TYPE, (
void*) &type, &len) < 0) {
895 THROW2(SocketException,
"getsockopt()");
898 THROW(SocketException,
"SO_TYPE not defined");
905 void Socket::setIpv6V6Only(
bool on)
throw (SocketException) {
907 int optval = (on) ? 1 : 0;
909 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (
void*) &optval,
sizeof(optval)) < 0) {
910 THROW2(SocketException,
"setsockopt()");
913 THROW(SocketException,
"IPV6_V6ONLY not defined");
917 bool Socket::getIpv6V6Only(
void)
const throw (SocketException) {
920 socklen_t len =
sizeof(optval);
922 if (getsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (
void*) &optval, &len) < 0) {
923 THROW2(SocketException,
"getsockopt()");
926 THROW(SocketException,
"IPV6_V6ONLY not defined");
929 return (optval) ?
true :
false;
933 void Socket::mmapRingBuffer(
unsigned char **ring,
struct tpacket_req &req)
throw (SocketException) {
934 if ((*ring = (
unsigned char*) mmap(0, req.tp_block_size * req.tp_block_nr, PROT_READ | PROT_WRITE, MAP_SHARED, s, 0)) == NULL) {
935 THROW2(SocketException,
"mmap()");
939 void Socket::munmapRingBuffer(
unsigned char **ring,
struct tpacket_req &req)
throw (SocketException) {
940 if (munmap(*ring, req.tp_block_size) > 0) {
941 THROW2(SocketException,
"munmap()");
947 void Socket::setPacketRxRing(
struct tpacket_req &req,
int version)
throw (SocketException) {
948 #ifdef PACKET_VERSION
949 if (setsockopt(s, SOL_PACKET, PACKET_VERSION, (
void*) &version,
sizeof(version)) < 0) {
950 THROW2(SocketException,
"setsockopt()");
953 THROW(SocketException,
"PACKET_VERSION not defined");
956 #ifdef PACKET_RX_RING
957 if (setsockopt(s, SOL_PACKET, PACKET_RX_RING, (
void*) &req,
sizeof(req)) < 0) {
958 THROW2(SocketException,
"setsockopt()");
961 THROW(SocketException,
"PACKET_RX_RING not defined");
965 void Socket::setPacketTxRing(
struct tpacket_req &req,
int version)
throw (SocketException) {
966 #ifdef PACKET_VERSION
967 if (setsockopt(s, SOL_PACKET, PACKET_VERSION, (
void*) &version,
sizeof(version)) < 0) {
968 THROW2(SocketException,
"setsockopt()");
971 THROW(SocketException,
"PACKET_VERSION not defined");
974 #ifdef PACKET_TX_RING
975 if (setsockopt(s, SOL_PACKET, PACKET_TX_RING, (
void*) &req,
sizeof(req)) < 0) {
976 THROW2(SocketException,
"setsockopt()");
979 THROW(SocketException,
"PACKET_TX_RING not defined");
983 void Socket::setPacketLoss(
bool drop)
throw (SocketException) {
984 int optval = (drop) ? 1 : 0;
987 if (setsockopt(s, SOL_PACKET, PACKET_LOSS, (
void*) &optval,
sizeof(optval)) < 0) {
988 THROW2(SocketException,
"setsockopt()");
991 THROW(SocketException,
"PACKET_LOSS not defined");
995 int Socket::getPacketHdrLen(
int version)
throw (SocketException) {
997 socklen_t len =
sizeof(version);
1000 if ((ret = getsockopt(s, SOL_PACKET, PACKET_HDRLEN, (
void*) &version, &len)) < 0) {
1001 THROW2(SocketException,
"getsockopt()");
1004 THROW(SocketException,
"PACKET_HDRLEN not defined");
1010 void Socket::initAddr(
int family,
const std::string &address,
unsigned short port, sockaddr_storage &addr, socklen_t addrlen)
throw (SocketException) {
1012 u.ss = (
struct sockaddr_storage*) &addr;
1014 memset(&addr, 0, addrlen);
1015 u.ss->ss_family = family;
1017 if (family != AF_INET && family != AF_INET6) {
1018 THROW(SocketException,
"Only family AF_INET and AF_INET6 and AF_PACKET are implemented");
1021 if (address.empty()) {
1022 if (family == AF_INET) {
1023 u.sa_in->sin_addr.s_addr = htonl(INADDR_ANY);
1025 u.sa_in6->sin6_addr = in6addr_any;
1029 struct addrinfo hints, *result, *rp;
1031 memset(&hints, 0,
sizeof(
struct addrinfo));
1032 hints.ai_family = family;
1033 hints.ai_socktype = SOCK_DGRAM;
1034 hints.ai_flags = AI_PASSIVE;
1035 hints.ai_protocol = 0;
1036 hints.ai_canonname = NULL;
1037 hints.ai_addr = NULL;
1038 hints.ai_next = NULL;
1040 if ((s = getaddrinfo(address.c_str(), NULL, &hints, &result)) != 0) {
1041 THROW(SocketException,
"getaddrinfo() failed: %s", gai_strerror(s));
1044 for (rp = result; rp != NULL; rp = rp->ai_next) {
1045 if (family == rp->ai_family) {
1046 if (rp->ai_family == AF_INET) {
1047 memcpy(u.sa_in, rp->ai_addr, rp->ai_addrlen);
1048 }
else if (rp->ai_family == AF_INET6) {
1049 memcpy(u.sa_in6, rp->ai_addr, rp->ai_addrlen);
1055 if (rp->ai_next == NULL) {
1056 THROW(SocketException,
"Failed to locate an IPv4 or IPv6 address for %s", address.c_str());
1063 if (family == AF_INET) {
1064 u.sa_in->sin_port = htons(port);
1066 u.sa_in6->sin6_port = htons(port);
1070 unsigned short Socket::resolveService(
const std::string &service,
const std::string &protocol)
throw (SocketException) {
1071 struct servent serv, *result = NULL;
1075 if (getservbyname_r(service.c_str(), protocol.c_str(), &serv, buf,
sizeof(buf), &result) != 0) {
1076 THROW2(SocketException,
"getservbyname()");
1079 if (result != NULL) {
1080 return ntohs(result->s_port);
1081 }
else if (!isdigit(service.c_str()[0])) {
1082 THROW(SocketException,
"unresolveable service");
1085 ret = strtol(service.c_str(), (
char **) NULL, 10);
1086 if (ret < 1 || ret > 65535) {
1087 THROW2(SocketException,
"port out of range");