27 #include <arpa/inet.h>
28 #include <sys/select.h>
31 #include <netinet/tcp.h>
33 #include <sys/socket.h>
43 #define bzero(s,n) (memset((s), '\0', (n)), (void) 0)
52 : _state(SOCKET_DOWN), _fd(-1), _family(PF_UNSPEC)
57 : _state(SOCKET_UNMANAGED), _fd(fd), _family(PF_UNSPEC)
63 #ifdef __DEVELOPMENT_ASSERTIONS__
93 throw socket_exception(
"close error");
105 int ret = ::shutdown(this->fd(), how);
109 if (_state == SOCKET_UNMANAGED)
110 _state = SOCKET_DESTROYED;
112 _state = SOCKET_DOWN;
123 opts = fcntl((fd == -1) ? _fd : fd, F_GETFL);
129 opts &= ~(O_NONBLOCK);
133 if (fcntl((fd == -1) ? _fd : fd, F_SETFL, opts) < 0) {
141 int optval = (val ? 1 : 0);
142 if (::setsockopt((fd == -1) ? _fd : fd, SOL_SOCKET, SO_KEEPALIVE, &optval,
sizeof(optval)) < 0) {
150 struct linger linger;
152 linger.l_onoff = (val ? 1 : 0);
154 if (::setsockopt((fd == -1) ? _fd : fd, SOL_SOCKET, SO_LINGER, &linger,
sizeof(linger)) < 0) {
161 int on = (val ? 1: 0);
162 if (::setsockopt((fd == -1) ? _fd : fd, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof(on)) < 0)
170 int set = (val ? 1 : 0);
171 if (::setsockopt((fd == -1) ? _fd : fd, IPPROTO_TCP, TCP_NODELAY, (
char *)&
set,
sizeof(
set)) < 0) {
183 struct sockaddr_storage bound_addr;
184 socklen_t bound_len =
sizeof(bound_addr);
185 ::memset(&bound_addr, 0, bound_len);
188 int ret = ::getsockname(fd, (
struct sockaddr*)&bound_addr, &bound_len);
193 return bound_addr.ss_family;
199 if ((fd = ::socket(family, type, protocol)) < 0) {
209 _family = addr.family();
210 if ((_fd = ::socket(_family, type, protocol)) < 0) {
215 if ((_fd = ::socket(DEFAULT_SOCKET_FAMILY, type, protocol)) > -1) {
216 _family =
static_cast<sa_family_t
>(DEFAULT_SOCKET_FAMILY);
219 else if ((_fd = ::socket(DEFAULT_SOCKET_FAMILY_ALTERNATIVE, type, protocol)) > -1) {
220 _family =
static_cast<sa_family_t
>(DEFAULT_SOCKET_FAMILY_ALTERNATIVE);
223 DEFAULT_SOCKET_FAMILY = DEFAULT_SOCKET_FAMILY_ALTERNATIVE;
234 _family =
static_cast<sa_family_t
>(domain);
235 if ((_fd = ::socket(domain, type, protocol)) < 0) {
242 int ret = ::bind(fd, addr, len);
246 int bind_err = errno;
250 ::getnameinfo(addr, len, (
char*)&addr_str, 256, (
char*)&serv_str, 256, NI_NUMERICHOST | NI_NUMERICSERV);
251 std::stringstream ss;
252 vaddress vaddr(addr_str, serv_str, addr->sa_family);
253 ss <<
"with address " << vaddr.
toString();
255 check_bind_error(bind_err, ss.str());
278 throw socket_exception(
"socket is already up");
286 throw socket_exception(
"socket is not up");
293 ssize_t ret = ::send(this->fd(), data, len, flags);
318 ssize_t ret = ::recv(this->fd(), data, len, flags);
341 set_blocking_mode(val);
363 int ret = ::listen(_fd, connections);
370 struct sockaddr_storage cliaddr;
371 socklen_t len =
sizeof(cliaddr);
372 ::memset(&cliaddr, 0, len);
374 int new_fd = ::accept(this->fd(), (
struct sockaddr *) &cliaddr, &len);
383 if (::getnameinfo((
struct sockaddr *) &cliaddr, len, address,
sizeof address, service,
sizeof service, NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
414 struct sockaddr_storage clientAddress;
415 socklen_t clientAddressLength =
sizeof(clientAddress);
416 ::memset(&clientAddress, 0, clientAddressLength);
419 ssize_t ret = ::recvfrom(this->fd(), buf, buflen, flags, (
struct sockaddr *) &clientAddress, &clientAddressLength);
427 if (::getnameinfo((
struct sockaddr *) &clientAddress, clientAddressLength, address,
sizeof address, service,
sizeof service, NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
428 addr =
ibrcommon::vaddress(std::string(address), std::string(service), clientAddress.ss_family);
437 struct addrinfo hints, *res;
438 memset(&hints, 0,
sizeof hints);
440 hints.ai_family = _family;
441 hints.ai_socktype = SOCK_DGRAM;
442 hints.ai_flags = AI_ADDRCONFIG;
444 const char *address = NULL;
445 const char *service = NULL;
448 address = addr.address().c_str();
454 service = addr.service().c_str();
457 if ((ret = ::getaddrinfo(address, service, &hints, &res)) != 0)
463 len = ::sendto(this->fd(), buf, buflen, flags, res->ai_addr, res->ai_addrlen);
493 throw socket_exception(
"socket is already up");
496 struct sockaddr_un saun;
508 saun.sun_family = AF_UNIX;
509 ::strcpy(saun.sun_path, _filename.
getPath().c_str());
521 len =
sizeof(saun.sun_family) + strlen(saun.sun_path);
523 if (::connect(
_fd, (
struct sockaddr *)&saun,
static_cast<socklen_t
>(len)) < 0) {
525 throw socket_exception(
"Could not connect to the named socket.");
534 throw socket_exception(
"socket is not up");
540 : _filename(file), _listen(listen)
554 throw socket_exception(
"socket is already up");
564 this->bind(_filename);
566 }
catch (
const socket_exception&) {
579 throw socket_exception(
"socket is not up");
592 unlink(file.getPath().c_str());
594 struct sockaddr_un address;
595 size_t address_length;
597 address.sun_family = AF_UNIX;
598 strcpy(address.sun_path, file.getPath().c_str());
599 address_length =
sizeof(address.sun_family) + strlen(address.sun_path);
602 basesocket::bind(_fd, (
struct sockaddr *) &address, static_cast<socklen_t>(address_length));
606 : _address(port), _listen(listen)
611 : _address(address), _listen(listen)
625 throw socket_exception(
"socket is already up");
634 this->
bind(_address);
636 }
catch (
const socket_exception&) {
649 throw socket_exception(
"socket is not up");
656 struct addrinfo hints, *res;
657 memset(&hints, 0,
sizeof hints);
659 hints.ai_family = _family;
660 hints.ai_socktype = SOCK_STREAM;
663 const char *address = NULL;
664 const char *service = NULL;
667 hints.ai_flags |= AI_PASSIVE;
669 }
else if (addr.isLocal()) {
672 hints.ai_flags |= AI_PASSIVE;
674 address = addr.address().c_str();
679 service = addr.service().c_str();
682 if (0 != ::getaddrinfo(address, service, &hints, &res))
683 throw socket_exception(
"failed to getaddrinfo with address: " + addr.toString());
707 timerclear(&_timeout);
711 : _address(destination)
713 if (timeout == NULL) {
714 timerclear(&_timeout);
716 ::memcpy(&_timeout, timeout,
sizeof _timeout);
730 throw socket_exception(
"socket is already up");
732 struct addrinfo hints;
733 struct addrinfo *walk;
734 memset(&hints, 0,
sizeof(
struct addrinfo));
735 hints.ai_family = PF_UNSPEC;
736 hints.ai_socktype = SOCK_STREAM;
739 struct addrinfo *res = NULL;
742 const char *address = NULL;
743 const char *service = NULL;
746 address = _address.
address().c_str();
748 throw socket_exception(
"need at least an address to connect to");
752 service = _address.
service().c_str();
755 if ((ret = ::getaddrinfo(address, service, &hints, &res)) != 0)
757 throw socket_exception(
"getaddrinfo(): " + std::string(gai_strerror(ret)));
762 throw socket_exception(
"Could not connect to the server.");
770 for (walk = res; walk != NULL; walk = walk->ai_next) {
775 fd = ::socket(walk->ai_family, walk->ai_socktype, walk->ai_protocol);
781 if ((walk->ai_next == NULL) && (probesocket.
size() == 0))
783 throw socket_exception(
"Could not create a socket.");
792 if (::connect(fd, walk->ai_addr, walk->ai_addrlen) != 0) {
793 if (errno != EINPROGRESS) {
798 if ((walk->ai_next == NULL) && (probesocket.
size() == 0))
816 timeval timeout_value;
817 ::memcpy(&timeout_value, &_timeout,
sizeof timeout_value);
819 bool fastest_found =
false;
821 while (!fastest_found) {
825 if (timerisset(&_timeout)) {
827 if (!timerisset(&timeout_value)) {
833 probesocket.
select(NULL, &probeset, NULL, &timeout_value);
836 probesocket.
select(NULL, &probeset, NULL, NULL);
840 for (socketset::iterator iter = probeset.begin(); iter != probeset.end(); ++iter) {
843 socklen_t len =
sizeof(err);
844 ::getsockopt(current->
fd(), SOL_SOCKET, SO_ERROR, &err, &len);
849 fastest_found =
true;
864 probesocket.
remove(current);
869 if (probesocket.
size() == 0) {
875 if (fastest_found)
break;
879 if (fastest_found ==
false) {
880 throw socket_exception(
"connection setup timed out");
888 }
catch (
const std::exception&) {
901 throw socket_exception(
"socket is not up");
930 throw socket_exception(
"socket is already up");
945 }
catch (
const socket_exception&) {
958 throw socket_exception(
"socket is not up");
965 struct addrinfo hints, *res;
966 memset(&hints, 0,
sizeof hints);
968 hints.ai_family = _family;
969 hints.ai_socktype = SOCK_DGRAM;
972 const char *address = NULL;
973 const char *service = NULL;
976 hints.ai_flags |= AI_PASSIVE;
978 }
else if (addr.isLocal()) {
981 hints.ai_flags |= AI_PASSIVE;
983 address = addr.address().c_str();
988 service = addr.service().c_str();
991 if (0 != ::getaddrinfo(address, service, &hints, &res))
992 throw socket_exception(
"failed to getaddrinfo with address: " + addr.toString());
1019 #ifdef HAVE_FEATURES_H
1021 if ( ::setsockopt(
_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (
const char *)&val,
sizeof(val)) < 0 )
1023 throw socket_exception(
"setsockopt(IP_MULTICAST_LOOP)");
1026 unsigned char ttl = 255;
1027 if ( ::setsockopt(
_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
sizeof(ttl)) < 0 )
1029 throw socket_exception(
"setsockopt(IP_MULTICAST_TTL)");
1041 #ifdef HAVE_FEATURES_H
1043 if ( ::setsockopt(
_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (
const char *)&val,
sizeof(val)) < 0 )
1045 throw socket_exception(
"setsockopt(IPV6_MULTICAST_LOOP)");
1063 }
catch (
const socket_exception&) {
1073 #ifdef HAVE_FEATURES_H
1075 if ( ::setsockopt(
_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (
const char *)&val,
sizeof(val)) < 0 )
1077 throw socket_exception(
"setsockopt(IP_MULTICAST_LOOP)");
1084 #ifdef HAVE_FEATURES_H
1086 if ( ::setsockopt(
_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (
const char *)&val,
sizeof(val)) < 0 )
1088 throw socket_exception(
"setsockopt(IPV6_MULTICAST_LOOP)");
1100 #ifndef MCAST_JOIN_GROUP
1101 if (
group.family() == AF_INET6) {
1102 mcast_op(IPV6_JOIN_GROUP,
group, iface);
1104 mcast_op(IP_ADD_MEMBERSHIP,
group, iface);
1107 mcast_op(MCAST_JOIN_GROUP,
group, iface);
1113 #ifndef MCAST_LEAVE_GROUP
1114 if (
group.family() == AF_INET6) {
1115 mcast_op(IPV6_LEAVE_GROUP,
group, iface);
1117 mcast_op(IP_DROP_MEMBERSHIP,
group, iface);
1120 mcast_op(MCAST_LEAVE_GROUP,
group, iface);
1124 #ifndef MCAST_JOIN_GROUP
1127 struct addrinfo hints, *res;
1128 memset(&hints, 0,
sizeof hints);
1130 hints.ai_family = AF_INET;
1131 hints.ai_socktype = SOCK_DGRAM;
1134 struct sockaddr_storage iface_addr;
1135 ::memset(&iface_addr, 0,
sizeof(iface_addr));
1137 const std::list<vaddress> iface_addrs = iface.
getAddresses();
1138 for (std::list<vaddress>::const_iterator iter = iface_addrs.begin(); iter != iface_addrs.end(); ++iter) {
1141 if ((ret = ::getaddrinfo(addr.
address().c_str(), NULL, &hints, &res)) == 0) {
1143 ::memcpy(inaddr, &((
struct sockaddr_in*)res->ai_addr)->sin_addr,
sizeof(
struct sockaddr_in));
1154 void multicastsocket::mcast_op(
int optname,
const vaddress &
group,
const vinterface &iface)
throw (socket_exception)
1156 struct sockaddr_storage mcast_addr;
1157 ::memset(&mcast_addr, 0,
sizeof(mcast_addr));
1162 struct addrinfo hints, *res;
1163 memset(&hints, 0,
sizeof hints);
1165 hints.ai_family = PF_UNSPEC;
1166 hints.ai_socktype = SOCK_DGRAM;
1169 if ((ret = ::getaddrinfo(
group.address().c_str(), NULL, &hints, &res)) != 0) {
1170 throw socket_exception(
"getaddrinfo(): " + std::string(gai_strerror(ret)));
1173 switch (res->ai_family) {
1179 level = IPPROTO_IPV6;
1186 throw socket_exception(
"address family not supported");
1189 #ifndef MCAST_JOIN_GROUP
1190 if (res->ai_family == AF_INET) {
1192 ::memset(&req, 0,
sizeof(req));
1195 req.imr_multiaddr = ((
struct sockaddr_in*)res->ai_addr)->sin_addr;
1203 if ( ::setsockopt(this->fd(), level, optname, &req,
sizeof(req)) == -1 )
1205 throw socket_raw_error(errno,
"setsockopt()");
1208 struct ipv6_mreq req;
1209 ::memset(&req, 0,
sizeof(req));
1212 req.ipv6mr_multiaddr = ((
struct sockaddr_in6*)res->ai_addr)->sin6_addr;
1218 req.ipv6mr_interface = iface.getIndex();
1220 if ( ::setsockopt(this->fd(), level, optname, &req,
sizeof(req)) == -1 )
1222 throw socket_raw_error(errno,
"setsockopt()");
1226 struct group_req req;
1227 ::memset(&req, 0,
sizeof(req));
1230 ::memcpy(&req.gr_group, res->ai_addr, res->ai_addrlen);
1236 req.gr_interface = iface.getIndex();
1238 if ( ::setsockopt(this->fd(), level, optname, &req,
sizeof(req)) == -1 )
1240 throw socket_raw_error(errno,
"setsockopt()");
1253 throw socket_exception(
"Permission to create a socket of the specified type and/or protocol is denied.");
1256 throw socket_exception(
"The implementation does not support the specified address family.");
1259 throw socket_exception(
"Unknown protocol, or protocol family not available.");
1265 throw socket_exception(
"The system limit on the total number of open files has been reached.");
1269 throw socket_exception(
"Insufficient memory is available. The socket cannot be created until sufficient resources are freed.");
1271 case EPROTONOSUPPORT:
1272 throw socket_exception(
"The protocol type or the specified protocol is not supported within this domain.");
1289 throw socket_exception(
"Die addr_len war falsch oder der Socket gehrte nicht zur AF_UNIX Familie.");
1292 throw socket_exception(
"Die Socket \"Inode\" sollte auf einem schreibgeschtzten Dateisystem residieren.");
1295 throw socket_exception(
"my_addr weist auf eine Adresse auerhalb des erreichbaren Adressraumes zu.");
1307 throw socket_exception(
"Eine Komponente des Pfad-Prfixes ist kein Verzeichnis.");
1310 throw socket_exception(
"Keine berechtigung um eine Komponente des Pfad-prefixes zu durchsuchen.");
1313 throw socket_exception(
"my_addr enthlt eine Kreis-Referenz (zum Beispiel durch einen symbolischen Link)");