31 #define AI_ADDRCONFIG 0
34 #include <arpa/inet.h>
35 #include <sys/select.h>
36 #include <netinet/tcp.h>
38 #include <sys/socket.h>
52 #define bzero(s,n) (memset((s), '\0', (n)), (void) 0)
56 #define EINPROGRESS WSAEINPROGRESS
57 #define ECONNRESET WSAECONNRESET
58 #define EAFNOSUPPORT WSAEAFNOSUPPORT
59 #define ENOBUFS WSAENOBUFS
60 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
61 #define ELOOP WSAELOOP
70 int __compat_setsockopt(
int __fd,
int __level,
int __optname, __const
void *__optval, socklen_t __optlen)
72 return ::setsockopt(__fd, __level, __optname, (
char*)__optval, __optlen);
77 static bool initialized =
false;
78 if (initialized)
return 0;
80 return WSAStartup(MAKEWORD(2,2),&wsa);
83 #define __close closesocket
84 #define __errno WSAGetLastError()
86 #define __compat_setsockopt ::setsockopt
87 #define __init_sockets void
88 #define __close ::close
100 : _state(SOCKET_DOWN), _fd(-1), _family(PF_UNSPEC)
106 : _state(SOCKET_UNMANAGED), _fd(fd), _family(PF_UNSPEC)
113 #ifdef __DEVELOPMENT_ASSERTIONS__
143 throw socket_exception(
"close error");
155 int ret = ::shutdown(this->fd(), how);
159 if (_state == SOCKET_UNMANAGED)
160 _state = SOCKET_DESTROYED;
162 _state = SOCKET_DOWN;
174 unsigned long block_mode = (val) ? 1 : 0;
175 ioctlsocket((fd == -1) ? _fd : fd, FIONBIO, &block_mode);
178 opts = fcntl((fd == -1) ? _fd : fd, F_GETFL);
184 opts &= ~(O_NONBLOCK);
188 if (fcntl((fd == -1) ? _fd : fd, F_SETFL, opts) < 0) {
197 int optval = (val ? 1 : 0);
198 if (
__compat_setsockopt((fd == -1) ? _fd : fd, SOL_SOCKET, SO_KEEPALIVE, &optval,
sizeof(optval)) < 0) {
206 struct linger linger;
208 linger.l_onoff = (val ? 1 : 0);
210 if (
__compat_setsockopt((fd == -1) ? _fd : fd, SOL_SOCKET, SO_LINGER, &linger,
sizeof(linger)) < 0) {
217 int on = (val ? 1: 0);
218 if (
__compat_setsockopt((fd == -1) ? _fd : fd, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof(on)) < 0)
226 int set = (val ? 1 : 0);
227 if (
__compat_setsockopt((fd == -1) ? _fd : fd, IPPROTO_TCP, TCP_NODELAY, &set,
sizeof(set)) < 0) {
239 struct sockaddr_storage bound_addr;
240 socklen_t bound_len =
sizeof(bound_addr);
241 ::memset(&bound_addr, 0, bound_len);
244 int ret = ::getsockname(fd, (
struct sockaddr*)&bound_addr, &bound_len);
249 return bound_addr.ss_family;
255 if ((fd = ::socket(family, type, protocol)) < 0) {
265 _family = addr.family();
266 if ((_fd = ::socket(_family, type, protocol)) < 0) {
271 if ((_fd = ::socket(DEFAULT_SOCKET_FAMILY, type, protocol)) > -1) {
272 _family =
static_cast<sa_family_t
>(DEFAULT_SOCKET_FAMILY);
275 else if ((_fd = ::socket(DEFAULT_SOCKET_FAMILY_ALTERNATIVE, type, protocol)) > -1) {
276 _family =
static_cast<sa_family_t
>(DEFAULT_SOCKET_FAMILY_ALTERNATIVE);
279 DEFAULT_SOCKET_FAMILY = DEFAULT_SOCKET_FAMILY_ALTERNATIVE;
290 _family =
static_cast<sa_family_t
>(domain);
291 if ((_fd = ::socket(domain, type, protocol)) < 0) {
298 int ret = ::bind(fd, addr, len);
306 ::getnameinfo(addr, len, (
char*)&addr_str, 256, (
char*)&serv_str, 256, NI_NUMERICHOST | NI_NUMERICSERV);
307 std::stringstream ss;
308 vaddress vaddr(addr_str, serv_str, addr->sa_family);
309 ss <<
"with address " << vaddr.
toString();
311 check_bind_error(bind_err, ss.str());
334 throw socket_exception(
"socket is already up");
342 throw socket_exception(
"socket is not up");
349 ssize_t ret = ::send(this->fd(), data, len, flags);
374 ssize_t ret = ::recv(this->fd(), data, len, flags);
397 set_blocking_mode(val);
419 int ret = ::listen(_fd, connections);
426 struct sockaddr_storage cliaddr;
427 socklen_t len =
sizeof(cliaddr);
428 ::memset(&cliaddr, 0, len);
430 int new_fd = ::accept(this->fd(), (
struct sockaddr *) &cliaddr, &len);
439 if (::getnameinfo((
struct sockaddr *) &cliaddr, len, address,
sizeof address, service,
sizeof service, NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
470 struct sockaddr_storage clientAddress;
471 socklen_t clientAddressLength =
sizeof(clientAddress);
472 ::memset(&clientAddress, 0, clientAddressLength);
475 ssize_t ret = ::recvfrom(this->fd(), buf, buflen, flags, (
struct sockaddr *) &clientAddress, &clientAddressLength);
483 if (::getnameinfo((
struct sockaddr *) &clientAddress, clientAddressLength, address,
sizeof address, service,
sizeof service, NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
484 addr =
ibrcommon::vaddress(std::string(address), std::string(service), clientAddress.ss_family);
493 struct addrinfo hints, *res;
494 memset(&hints, 0,
sizeof hints);
496 hints.ai_family = _family;
497 hints.ai_socktype = SOCK_DGRAM;
498 hints.ai_flags = AI_ADDRCONFIG;
500 const char *address = NULL;
501 const char *service = NULL;
504 address = addr.address().c_str();
510 service = addr.service().c_str();
513 if ((ret = ::getaddrinfo(address, service, &hints, &res)) != 0)
519 len = ::sendto(this->fd(), buf, buflen, flags, res->ai_addr, res->ai_addrlen);
549 throw socket_exception(
"socket is already up");
552 throw socket_exception(
"socket type not supported");
555 struct sockaddr_un saun;
567 saun.sun_family = AF_UNIX;
568 ::strcpy(saun.sun_path, _filename.
getPath().c_str());
580 len =
sizeof(saun.sun_family) + strlen(saun.sun_path);
582 if (::connect(
_fd, (
struct sockaddr *)&saun,
static_cast<socklen_t
>(len)) < 0) {
584 throw socket_exception(
"Could not connect to the named socket.");
594 throw socket_exception(
"socket is not up");
600 : _filename(file), _listen(listen)
614 throw socket_exception(
"socket is already up");
624 this->bind(_filename);
626 }
catch (
const socket_exception&) {
639 throw socket_exception(
"socket is not up");
653 unlink(file.getPath().c_str());
655 struct sockaddr_un address;
656 size_t address_length;
658 address.sun_family = AF_UNIX;
659 strcpy(address.sun_path, file.getPath().c_str());
660 address_length =
sizeof(address.sun_family) + strlen(address.sun_path);
663 basesocket::bind(_fd, (
struct sockaddr *) &address, static_cast<socklen_t>(address_length));
668 : _address(port), _listen(listen)
673 : _address(address), _listen(listen)
687 throw socket_exception(
"socket is already up");
696 this->
bind(_address);
698 }
catch (
const socket_exception&) {
711 throw socket_exception(
"socket is not up");
718 struct addrinfo hints, *res;
719 memset(&hints, 0,
sizeof hints);
721 hints.ai_family = _family;
722 hints.ai_socktype = SOCK_STREAM;
725 const char *address = NULL;
726 const char *service = NULL;
729 hints.ai_flags |= AI_PASSIVE;
731 }
else if (addr.isLocal()) {
734 hints.ai_flags |= AI_PASSIVE;
736 address = addr.address().c_str();
741 service = addr.service().c_str();
744 if (0 != ::getaddrinfo(address, service, &hints, &res))
745 throw socket_exception(
"failed to getaddrinfo with address: " + addr.toString());
769 timerclear(&_timeout);
773 : _address(destination)
775 if (timeout == NULL) {
776 timerclear(&_timeout);
778 ::memcpy(&_timeout, timeout,
sizeof _timeout);
792 throw socket_exception(
"socket is already up");
794 struct addrinfo hints;
795 struct addrinfo *walk;
796 memset(&hints, 0,
sizeof(
struct addrinfo));
797 hints.ai_family = PF_UNSPEC;
798 hints.ai_socktype = SOCK_STREAM;
801 struct addrinfo *res = NULL;
804 const char *address = NULL;
805 const char *service = NULL;
808 address = _address.
address().c_str();
810 throw socket_exception(
"need at least an address to connect to");
814 service = _address.
service().c_str();
817 if ((ret = ::getaddrinfo(address, service, &hints, &res)) != 0)
819 throw socket_exception(
"getaddrinfo(): " + std::string(gai_strerror(ret)));
824 throw socket_exception(
"Could not connect to the server.");
832 for (walk = res; walk != NULL; walk = walk->ai_next) {
837 fd = ::socket(walk->ai_family, walk->ai_socktype, walk->ai_protocol);
843 if ((walk->ai_next == NULL) && (probesocket.
size() == 0))
845 throw socket_exception(
"Could not create a socket.");
854 if (::connect(fd, walk->ai_addr, walk->ai_addrlen) != 0) {
860 if ((walk->ai_next == NULL) && (probesocket.
size() == 0))
878 timeval timeout_value;
879 ::memcpy(&timeout_value, &_timeout,
sizeof timeout_value);
881 bool fastest_found =
false;
883 while (!fastest_found) {
887 if (timerisset(&_timeout)) {
889 if (!timerisset(&timeout_value)) {
895 probesocket.
select(NULL, &probeset, NULL, &timeout_value);
898 probesocket.
select(NULL, &probeset, NULL, NULL);
902 for (socketset::iterator iter = probeset.begin(); iter != probeset.end(); ++iter) {
905 socklen_t len =
sizeof(err);
907 ::getsockopt(current->
fd(), SOL_SOCKET, SO_ERROR, (
char*)&err, &len);
909 ::getsockopt(current->
fd(), SOL_SOCKET, SO_ERROR, &err, &len);
915 fastest_found =
true;
930 probesocket.
remove(current);
935 if (probesocket.
size() == 0) {
941 if (fastest_found)
break;
945 if (fastest_found ==
false) {
946 throw socket_exception(
"connection setup timed out");
954 }
catch (
const std::exception&) {
967 throw socket_exception(
"socket is not up");
996 throw socket_exception(
"socket is already up");
1011 }
catch (
const socket_exception&) {
1024 throw socket_exception(
"socket is not up");
1031 struct addrinfo hints, *res;
1032 memset(&hints, 0,
sizeof hints);
1034 hints.ai_family = _family;
1035 hints.ai_socktype = SOCK_DGRAM;
1038 const char *address = NULL;
1039 const char *service = NULL;
1042 hints.ai_flags |= AI_PASSIVE;
1044 }
else if (addr.isLocal()) {
1047 hints.ai_flags |= AI_PASSIVE;
1049 address = addr.address().c_str();
1054 service = addr.service().c_str();
1057 if (0 != ::getaddrinfo(address, service, &hints, &res))
1058 throw socket_exception(
"failed to getaddrinfo with address: " + addr.toString());
1085 #ifdef HAVE_FEATURES_H
1089 throw socket_exception(
"setsockopt(IP_MULTICAST_LOOP)");
1092 unsigned char ttl = 7;
1095 throw socket_exception(
"setsockopt(IP_MULTICAST_TTL)");
1107 #ifdef HAVE_FEATURES_H
1111 throw socket_exception(
"setsockopt(IPV6_MULTICAST_LOOP)");
1129 }
catch (
const socket_exception&) {
1139 #ifdef HAVE_FEATURES_H
1143 throw socket_exception(
"setsockopt(IP_MULTICAST_LOOP)");
1150 #ifdef HAVE_FEATURES_H
1154 throw socket_exception(
"setsockopt(IPV6_MULTICAST_LOOP)");
1166 #ifndef MCAST_JOIN_GROUP
1167 if (
group.family() == AF_INET6) {
1168 mcast_op(IPV6_JOIN_GROUP,
group, iface);
1170 mcast_op(IP_ADD_MEMBERSHIP,
group, iface);
1173 mcast_op(MCAST_JOIN_GROUP,
group, iface);
1179 #ifndef MCAST_LEAVE_GROUP
1180 if (
group.family() == AF_INET6) {
1181 mcast_op(IPV6_LEAVE_GROUP,
group, iface);
1183 mcast_op(IP_DROP_MEMBERSHIP,
group, iface);
1186 mcast_op(MCAST_LEAVE_GROUP,
group, iface);
1190 #ifndef MCAST_JOIN_GROUP
1193 struct addrinfo hints, *res;
1194 memset(&hints, 0,
sizeof hints);
1196 hints.ai_family = AF_INET;
1197 hints.ai_socktype = SOCK_DGRAM;
1200 struct sockaddr_storage iface_addr;
1201 ::memset(&iface_addr, 0,
sizeof(iface_addr));
1203 const std::list<vaddress> iface_addrs = iface.
getAddresses();
1204 for (std::list<vaddress>::const_iterator iter = iface_addrs.begin(); iter != iface_addrs.end(); ++iter) {
1207 if ((ret = ::getaddrinfo(addr.
address().c_str(), NULL, &hints, &res)) == 0) {
1209 ::memcpy(inaddr, &((
struct sockaddr_in*)res->ai_addr)->sin_addr,
sizeof(
struct sockaddr_in));
1220 void multicastsocket::mcast_op(
int optname,
const vaddress &
group,
const vinterface &iface)
throw (socket_exception)
1222 struct sockaddr_storage mcast_addr;
1223 ::memset(&mcast_addr, 0,
sizeof(mcast_addr));
1228 struct addrinfo hints, *res;
1229 memset(&hints, 0,
sizeof hints);
1231 hints.ai_family = PF_UNSPEC;
1232 hints.ai_socktype = SOCK_DGRAM;
1235 if ((ret = ::getaddrinfo(
group.address().c_str(), NULL, &hints, &res)) != 0) {
1236 throw socket_exception(
"getaddrinfo(): " + std::string(gai_strerror(ret)));
1239 switch (res->ai_family) {
1245 level = IPPROTO_IPV6;
1252 throw socket_exception(
"address family not supported");
1255 #ifndef MCAST_JOIN_GROUP
1256 if (res->ai_family == AF_INET) {
1258 ::memset(&req, 0,
sizeof(req));
1261 req.imr_multiaddr = ((
struct sockaddr_in*)res->ai_addr)->sin_addr;
1271 throw socket_raw_error(
__errno,
"setsockopt()");
1274 struct ipv6_mreq req;
1275 ::memset(&req, 0,
sizeof(req));
1278 req.ipv6mr_multiaddr = ((
struct sockaddr_in6*)res->ai_addr)->sin6_addr;
1284 req.ipv6mr_interface = iface.getIndex();
1288 throw socket_raw_error(
__errno,
"setsockopt()");
1292 struct group_req req;
1293 ::memset(&req, 0,
sizeof(req));
1296 ::memcpy(&req.gr_group, res->ai_addr, res->ai_addrlen);
1302 req.gr_interface = iface.getIndex();
1306 throw socket_raw_error(
__errno,
"setsockopt()");
1319 throw socket_exception(
"Permission to create a socket of the specified type and/or protocol is denied.");
1322 throw socket_exception(
"The implementation does not support the specified address family.");
1325 throw socket_exception(
"Unknown protocol, or protocol family not available.");
1331 throw socket_exception(
"The system limit on the total number of open files has been reached.");
1335 throw socket_exception(
"Insufficient memory is available. The socket cannot be created until sufficient resources are freed.");
1337 case EPROTONOSUPPORT:
1338 throw socket_exception(
"The protocol type or the specified protocol is not supported within this domain.");
1356 throw socket_exception(
"The socket inode would reside on a read-only filesystem.");
1359 throw socket_exception(
"Given address points outside the user's accessible address space.");
1371 throw socket_exception(
"A component of the path prefix is not a directory.");
1374 throw socket_exception(
"Search permission is denied on a component of the path prefix.");
1377 throw socket_exception(
"Too many symbolic links were encountered in resolving the given address.");