19 #include <ucommon-config.h> 29 #include <sys/ioctl.h> 30 #include <arpa/inet.h> 32 #define HAVE_GETADDRINFO 1 39 #if defined(HAVE_POLL_H) 41 #elif defined(HAVE_SYS_POLL_H) 45 #if defined(HAVE_SYS_FILIO_H) 46 #include <sys/filio.h> 49 #if defined(HAVE_POLL) && defined(POLLRDNORM) 53 #if defined(__linux__) && !defined(IP_MTU) 58 #define MSG_DONTWAIT 0 62 #define MSG_NOSIGNAL 0 76 struct ipv6_mreq ipv6;
81 #ifndef HAVE_GETADDRINFO 94 #define NI_NUMERICHOST 0x0001 95 #define NI_NUMERICSERV 0x0002 96 #define NI_NAMEREQD 0x0004 97 #define NI_NOFQDN 0x0008 98 #define NI_DGRAM 0x0010 100 #define AI_PASSIVE 0x0100 101 #define AI_CANONNAME 0x0200 102 #define AI_NUMERICHOST 0x0400 103 #define AI_NUMERICSERV 0x0800 119 #if defined(IPV6_V6ONLY) && defined(IPPROTO_IPV6) 120 if(family == AF_INET6)
121 setsockopt (so, IPPROTO_IPV6, IPV6_V6ONLY, (
char *) &
v6only,
sizeof (
v6only));
125 #ifndef HAVE_GETADDRINFO 142 static int getnameinfo(
const struct sockaddr *
addr, socklen_t len,
char *host,
size_t hostlen,
char *service,
size_t servlen,
int flags)
147 assert(
addr != NULL);
148 assert(host != NULL || hostlen == 0);
149 assert(service != NULL || servlen == 0);
153 switch(
addr->sa_family) {
157 snprintf(host, hostlen,
"%s", ((
struct sockaddr_un *)
addr)->sun_path);
159 snprintf(service, servlen,
"%s", ((
struct sockaddr_un *)
addr)->sun_path);
164 port = ((
struct sockaddr_in6 *)
addr)->sin6_port;
168 port = ((
struct sockaddr_in *)
addr)->sin_port;
175 if(inet_ntop(
addr->sa_family,
addr, host, hostlen) == NULL)
181 if(hp != NULL && hp->h_name != NULL) {
183 cp = strchr(hp->h_name,
'.');
187 snprintf(host, hostlen,
"%s", hp->h_name);
194 if(inet_ntop(
addr->sa_family,
addr, host, hostlen) != NULL)
201 snprintf(service, servlen,
"%d", ntohs(
port));
204 sp = getservbyport(
port, (flags &
NI_DGRAM) ?
"udp" : NULL);
206 snprintf(service, servlen,
"%s", sp->s_name);
208 snprintf(service, servlen,
"%d", ntohs(
port));
218 const char *servtype =
"tcp";
223 struct addrinfo *aip = NULL, *prior = NULL;
226 struct sockaddr_in *ipv4;
228 struct sockaddr_in6 *ipv6;
231 memset(&hints, 0,
sizeof(hints));
235 memcpy(&hints, hintsp,
sizeof(hints));
245 memset(aip, 0,
sizeof(
struct addrinfo));
249 struct sockaddr_un *unp;
250 if(strlen(hostname) >=
sizeof(unp->sun_path))
252 unp = (
struct sockaddr_un *)malloc(
sizeof(
struct sockaddr_un));
253 memset(unp, 0,
sizeof(
struct sockaddr_un));
254 unp->sun_family = AF_UNIX;
255 String::set(unp->sun_path,
sizeof(unp->sun_path), hostname);
257 len =
sizeof(unp->sun_len) + strlen(unp->sun_path) +
258 sizeof(unp->sun_family) + 1;
261 len = strlen(unp->sun_path) +
sizeof(unp->sun_family) + 1;
264 unlink(unp->sun_path);
265 aip->
ai_addr = (
struct sockaddr *)unp;
272 if(servname && *servname) {
273 if(servname[0] >=
'0' && servname[0] <=
'9') {
274 port = htons(atoi(servname));
280 sp = getservbyname(servname, servtype);
290 if((!hostname || !*hostname)) {
292 memset(aip, 0,
sizeof(
struct addrinfo));
301 ipv6 = (
struct sockaddr_in6 *)malloc(
sizeof(
struct sockaddr_in6));
302 memset(ipv6, 0,
sizeof(
struct sockaddr_in6));
304 inet_pton(AF_INET6,
"::1", &ipv6->sin6_addr);
305 ipv6->sin6_family = AF_INET6;
306 ipv6->sin6_port =
port;
307 aip->
ai_addr = (
struct sockaddr *)ipv6;
308 aip->
ai_addrlen =
sizeof(
struct sockaddr_in6);
314 ipv4 = (
struct sockaddr_in*)malloc(
sizeof(
struct sockaddr_in));
315 memset(ipv4, 0,
sizeof(
struct sockaddr_in));
316 ipv4->sin_family = AF_INET;
317 ipv4->sin_port =
port;
319 inet_pton(AF_INET,
"127.0.0.1", &ipv4->sin_addr);
320 aip->
ai_addr = (
struct sockaddr *)ipv4;
331 #ifdef HAVE_GETHOSTBYNAME2 332 hp = gethostbyname2(hostname, family);
334 hp = gethostbyname(hostname);
341 for(np = hp->h_addr_list; *np != NULL; np++) {
343 memset(aip, 0,
sizeof(
struct addrinfo));
360 ipv6 = (
struct sockaddr_in6 *)malloc(
sizeof(
struct sockaddr_in6));
361 memset(ipv6, 0,
sizeof(
struct sockaddr_in6));
362 memcpy(&ipv6->sin6_addr, *np,
sizeof(&ipv6->sin6_addr));
363 ipv6->sin6_family = AF_INET6;
364 ipv6->sin6_port =
port;
365 aip->
ai_addr = (
struct sockaddr *)ipv6;
366 aip->
ai_addrlen =
sizeof(
struct sockaddr_in6);
371 ipv4 = (
struct sockaddr_in*)malloc(
sizeof(
struct sockaddr_in));
372 memset(ipv4, 0,
sizeof(
struct sockaddr_in));
373 ipv4->sin_family = AF_INET;
374 ipv4->sin_port =
port;
375 memcpy(&ipv4->sin_addr, *np,
sizeof(&ipv4->sin_addr));
376 aip->
ai_addr = (
struct sockaddr *)ipv4;
388 #if defined(AF_UNIX) && !defined(_MSWINDOWS_) 390 static socklen_t unixaddr(
struct sockaddr_un *
addr,
const char *path)
392 assert(
addr != NULL);
393 assert(path != NULL && *path != 0);
396 unsigned slen = strlen(path);
398 if(slen >
sizeof(
addr->sun_path))
399 slen =
sizeof(
addr->sun_path);
402 addr->sun_family = AF_UNIX;
403 memcpy(
addr->sun_path, path, slen);
406 len =
sizeof(
addr->sun_len) + strlen(
addr->sun_path) +
407 sizeof(
addr->sun_family) + 1;
410 len = strlen(
addr->sun_path) +
sizeof(
addr->sun_family) + 1;
423 const char *hc = host;
429 if(strchr(host,
':'))
436 while((*hc >=
'0' && *hc <=
'9') || *hc ==
'.')
450 assert(bits != NULL);
451 assert(mask != NULL);
454 *(bits++) &= *(mask++);
459 assert(bits != NULL);
460 assert(mask != NULL);
463 *(bits++) |= ~(*(mask++));
468 assert(bits != NULL);
473 mask = (
bit_t)(1 << 7);
474 while(mask && blen) {
485 assert(bits != NULL);
491 mask = (
bit_t)(1<<7);
505 static bool _started =
false;
507 static void _socketcleanup(
void)
515 static bool initialized =
false;
516 unsigned short version;
523 version = MAKEWORD(2,2);
525 if(WSAStartup(version, &status))
527 atexit(_socketcleanup);
554 memset(&Netmask, 0,
sizeof(Netmask));
561 assert(cp != NULL && *cp != 0);
570 assert(cp != NULL && *cp != 0);
580 assert(cp != NULL && *cp != 0);
581 assert(
id != NULL && *
id != 0);
593 memcpy(&Netmask, &
copy.Netmask,
sizeof(Netmask));
602 return bitcount((
bit_t *)&Netmask.ipv4,
sizeof(
struct in_addr));
605 return bitcount((
bit_t *)&Netmask.ipv6,
sizeof(
struct in6_addr));
617 const cidr *member = NULL;
622 if(p->is_member(s)) {
623 if(p->getMask() > top) {
638 const cidr *member = NULL;
643 if(p->is_member(s)) {
644 if(p->getMask() < top) {
667 memcpy(&host.
ipv4, &
addr->ipv4.sin_addr,
sizeof(host.
ipv4));
674 memcpy(&host.ipv6, &
addr->ipv6.sin6_addr,
sizeof(host.ipv6));
676 if(!memcmp(&host.ipv6, &
Network.ipv6,
sizeof(host.ipv6)))
691 memcpy(&bcast.
ipv4, &Network.ipv4,
sizeof(Network.ipv4));
696 memcpy(&bcast.ipv6, &Network.ipv6,
sizeof(Network.ipv6));
701 memset(&bcast, 0,
sizeof(bcast));
708 assert(cp != NULL && *cp != 0);
710 unsigned count = 0, rcount = 0, dcount = 0;
711 const char *sp = strchr(cp,
'/');
722 if(!strncmp(cp,
"ff00:", 5))
724 if(!strncmp(cp,
"ff80:", 5))
726 if(!strncmp(cp,
"2002:", 5))
729 sp = strrchr(cp,
':');
730 while(*(++sp) ==
'0')
735 while(*cp &&
count < 128) {
753 if(!strchr(++sp,
'.'))
755 mask = inet_addr(sp);
758 memset(dots, 0,
sizeof(dots));
760 while(*gp && dcount < 3) {
762 dots[++dcount] = atoi(gp);
781 assert(cp != NULL && *cp != 0);
790 struct sockaddr_in6 *paddr;
802 memset(&Netmask.ipv4, 0,
sizeof(Netmask.ipv4));
805 ep = (
char *)strchr(
cbuf,
'/');
810 while(NULL != (cp = strchr(cp,
'.'))) {
819 addr4 = inet_addr(cp);
828 memset(&Netmask.ipv6, 0,
sizeof(Netmask));
831 ep = (
char *)strchr(cp,
'/');
835 struct sockaddr saddr;
836 slen =
sizeof(saddr);
837 paddr = (
struct sockaddr_in6 *)&saddr;
838 WSAStringToAddress((LPSTR)
cbuf, AF_INET6, NULL, &saddr, &slen);
839 Network.ipv6 = paddr->sin6_addr;
852 assert(a != NULL && *a != 0);
863 assert(host != NULL && *host != 0);
874 assert(host != NULL && *host != 0);
875 assert(svc != NULL && *svc != 0);
884 memset(&hint, 0,
sizeof(hint));
892 addr.sin_family = AF_INET;
901 addr.sin6_family = AF_INET6;
932 set(host, service,
type);
958 assert(hp != NULL && *hp != 0);
964 char *cp = strchr(hostbuf,
'/');
965 char *host = hostbuf;
967 memset(&hint, 0,
sizeof(hint));
981 cp = strchr(++host,
']');
993 else if(((cp = strrchr(host,
':')) != NULL) && (strchr(host,
':') == cp)) {
1001 if(strchr(host,
':')) {
1015 #if defined(AF_INET6) && defined(AI_V4MAPPED) 1019 #ifdef AI_NUMERICSERV 1020 if(svc && atoi(svc) > 0)
1035 while(node && node_o) {
1048 assert(host != NULL && *host != 0);
1055 snprintf(buf,
sizeof(buf),
"%u",
port);
1064 assert(a != NULL && *a != 0);
1066 char *
addr = strdup(a);
1067 char *host = strchr(
addr,
'@');
1074 memset(&hint, 0,
sizeof(hint));
1087 ep = strchr(host,
':');
1098 ep = strchr(host,
']');
1111 #if defined(AF_INET6) && defined(AI_V4MAPPED) 1125 return list->ai_addr;
1133 return list->ai_addr;
1138 struct sockaddr *ap;
1146 return ap->sa_family;
1151 struct sockaddr *ap;
1172 struct sockaddr *ap;
1179 if(ap && ap->sa_family ==
family)
1188 const struct sockaddr *ap;
1195 if(ap && ap->sa_family ==
family)
1210 assert(
addr != NULL);
1211 struct addrinfo *node = list, *prior = NULL;
1257 assert(
addr != NULL);
1259 struct addrinfo *node = list, hints;
1261 while(node && node->
ai_addr) {
1267 char buf[256], svc[16];
1269 snprintf(svc,
sizeof(svc),
"%d",
port(
addr));
1270 memset(&hints, 0,
sizeof(hints));
1271 hints.ai_family =
addr->sa_family;
1291 insert(
addr->ai_addr);
1303 reinterpret_cast<sockaddr_in* >(
address)->sin_port = htons(
port);
1306 reinterpret_cast<sockaddr_in6*>(
address)->sin6_port = htons(
port);
1318 return reinterpret_cast<const sockaddr_in*>(
address)->sin_addr.s_addr == INADDR_ANY;
1321 &reinterpret_cast<const sockaddr_in6*>(
address)->sin6_addr,
1323 sizeof(in6addr_any)) == 0;
1339 &reinterpret_cast<const sockaddr_in6*>(
address)->sin6_addr,
1341 sizeof(in6addr_loopback)) == 0;
1353 insert(reinterpret_cast<const sockaddr*>(&sa));
1362 insert(reinterpret_cast<const sockaddr*>(&sa));
1367 int family = sa->sa_family;
1374 switch (sa->sa_family) {
1376 reinterpret_cast<sockaddr_in*>(sa)->sin_addr.s_addr = htonl(
INADDR_LOOPBACK);
1380 &reinterpret_cast<sockaddr_in6*>(sa)->sin6_addr,
1382 sizeof(in6addr_loopback));
1398 setLoopback((
struct sockaddr*)&sa);
1404 if(
addr == NULL ||
addr->sa_family != AF_INET)
1407 return (
struct sockaddr_in*)
addr;
1411 struct sockaddr_in6 *Socket::address::ipv6(
struct sockaddr *
addr)
1413 if(
addr == NULL ||
addr->sa_family != AF_INET6)
1416 return (
struct sockaddr_in6*)
addr;
1422 struct sockaddr *node;
1431 node = (
struct sockaddr *)malloc(slen);
1433 memcpy(node,
addr, slen);
1439 assert(
addr != NULL);
1452 add(host, svc, socktype);
1457 assert(host != NULL && *host != 0);
1458 assert(svc != NULL && *svc != 0);
1471 while(last->ai_next)
1472 last = last->ai_next;
1473 last->ai_next =
join;
1478 assert(
addr != NULL);
1492 if(!
addr || !dst || !dst_sz)
1495 memset(dst, 0, dst_sz);
1496 const char* ret = dst;
1497 const int af =
addr->sa_family;
1498 const char *res = NULL;
1499 #if defined(AF_INET6) 1500 ipv6_brackets = (af == AF_INET6) ? ipv6_brackets ||
port :
false;
1509 struct sockaddr_in in;
1510 memset(&in, 0,
sizeof(in));
1511 in.sin_family = AF_INET;
1512 memcpy(&in.sin_addr, &reinterpret_cast<const struct sockaddr_in*>(
addr)->sin_addr,
sizeof(
struct in_addr));
1520 struct sockaddr_in6 in6;
1521 memset(&in6, 0,
sizeof(in6));
1522 in6.sin6_family = AF_INET6;
1523 memcpy(&in6.sin6_addr, &reinterpret_cast<const struct sockaddr_in6*>(
addr)->sin6_addr,
sizeof(
struct in_addr6));
1530 #elif defined(HAVE_INET_NTOP) 1532 res = ::inet_ntop(AF_INET, &reinterpret_cast<const sockaddr_in*>(
addr)->sin_addr, dst, dst_sz);
1536 res = ::inet_ntop(AF_INET6, &reinterpret_cast<const sockaddr_in6*>(
addr)->sin6_addr, dst, dst_sz);
1542 String::set(dst, dst_sz, inet_ntoa(((
const struct sockaddr_in *)(
addr))->sin_addr));
1551 size_t addr_len = strlen(res);
1552 dst = dst + addr_len;
1555 #if defined(AF_INET6) 1556 if(ipv6_brackets && dst_sz) {
1562 if(
port && dst_sz) {
1565 snprintf(dst, dst_sz,
"%u", getPort(
addr));
1573 HANDLE pidH = GetCurrentProcess();
1577 if(DuplicateHandle(pidH, reinterpret_cast<HANDLE>(s.
so), pidH, &dupH, 0, FALSE, DUPLICATE_SAME_ACCESS))
1578 so = reinterpret_cast<SOCKET>(dupH);
1607 assert(
addr != NULL);
1610 so = ::socket(
addr->ai_family,
addr->ai_socktype,
addr->ai_protocol);
1613 if(!::connect(
so,
addr->ai_addr, (socklen_t)
addr->ai_addrlen))
1632 assert(iface != NULL && *iface != 0);
1633 assert(
port != NULL && *
port != 0);
1664 assert(iface != NULL && *iface != 0);
1665 assert(
port != NULL && *
port != 0);
1675 memset(&hint, 0,
sizeof(hint));
1681 #if defined(AF_INET6) && defined(AI_V4MAPPED) 1686 #if defined(AF_UNIX) && !defined(_MSWINDOWS_) 1687 if(iface && strchr(iface,
'/')) {
1689 socklen_t
len = unixaddr((
struct sockaddr_un *)&uaddr, iface);
1695 if(::bind(
so, (
struct sockaddr *)&uaddr,
len)) {
1703 if(iface && !strcmp(iface,
"*"))
1715 setsockopt(
so, SOL_SOCKET, SO_REUSEADDR, (
caddr_t)&reuse,
sizeof(reuse));
1782 switch(WSAGetLastError())
1784 case WSANOTINITIALISED:
1786 case WSASYSNOTREADY:
1792 case WSA_OPERATION_ABORTED:
1793 case WSA_IO_INCOMPLETE:
1794 case WSASYSCALLFAILURE:
1795 case WSA_E_CANCELLED:
1797 case WSA_IO_PENDING:
1798 case WSAEINPROGRESS:
1804 case WSAENETUNREACH:
1807 case WSAETOOMANYREFS:
1808 case WSA_NOT_ENOUGH_MEMORY:
1814 case WSA_INVALID_HANDLE:
1818 case WSAEWOULDBLOCK:
1821 case WSAENOPROTOOPT:
1827 case WSAECONNABORTED:
1828 return ECONNABORTED;
1839 case WSAECONNREFUSED:
1840 return ECONNREFUSED;
1843 case WSAEHOSTUNREACH:
1844 return EHOSTUNREACH;
1855 Socket::operator bool()
const 1878 assert(data != NULL);
1892 assert(data != NULL);
1901 assert(data != NULL);
1920 assert(data != NULL);
1938 assert(data != NULL);
1961 assert(data != NULL);
2006 assert(data != NULL);
2011 size_t nleft =
max - 1;
2018 while(nleft && !nl) {
2028 return (ssize_t)(
max - nleft - 1);
2030 for(c = 0; c < nstat; ++c) {
2031 if(data[c] ==
'\n') {
2032 if(c > 0 && data[c - 1] ==
'\r')
2040 nstat = ::recv(
so, (
caddr_t)data, c, 0);
2046 data[nstat - 1] =
'\n';
2057 return ssize_t(
max - nleft - 1);
2064 struct sockaddr_in inaddr;
2067 struct sockaddr *
addr = (
struct sockaddr *)&us.saddr;
2069 socklen_t
len =
sizeof(us.saddr);
2079 family = us.inaddr.sin_family;
2082 if(!setsockopt(
so, IPPROTO_IP, IP_MULTICAST_LOOP, (
char *)&opt,
sizeof(opt)))
2085 #if defined(AF_INET6) && defined(IPROTO_IPV6) 2087 if(!setsockopt(
so, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (
char *)&opt,
sizeof(opt)))
2101 struct sockaddr_in inaddr;
2104 struct sockaddr *
addr = (
struct sockaddr *)&us.saddr;
2106 socklen_t
len =
sizeof(us.saddr);
2112 family = us.inaddr.sin_family;
2115 if(!setsockopt(
so, IPPROTO_IP, IP_TTL, (
char *)&t,
sizeof(t)))
2118 #if defined(AF_INET6) && defined(IPPROTO_IPV6) 2120 if(!setsockopt(
so, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (
char *)&t,
sizeof(t)))
2135 if(!setsockopt(
so, SOL_SOCKET, SO_PRIORITY, (
char *)&pri, (socklen_t)
sizeof(pri)))
2152 if(!setsockopt(
so, SOL_IP, IP_TOS,(
char *)&ts, (socklen_t)
sizeof(ts)))
2168 int opt = (enable ? 1 : 0);
2169 if(!::setsockopt(
so, SOL_SOCKET, SO_BROADCAST,
2170 (
char *)&opt, (socklen_t)
sizeof(opt)))
2183 #if defined(TCP_NODELAY) 2185 if(!::setsockopt(
so, IPPROTO_TCP, TCP_NODELAY,
2186 (
char *)&opt, (socklen_t)
sizeof(opt)))
2201 #if defined(SO_KEEPALIVE) || defined(_MSWINDOWS_) 2202 int opt = (enable ? ~0 : 0);
2203 if(!::setsockopt(
so, SOL_SOCKET, SO_KEEPALIVE, (
char *)&opt, (socklen_t)
sizeof(opt)))
2229 ::getsockname(
so, (
struct sockaddr *)&
addr, &
len);
2231 switch(
addr.address.sa_family)
2234 memset(&
addr.ipv4.sin_addr, 0,
sizeof(
addr.ipv4.sin_addr));
2238 memset(&
addr.ipv6.sin6_addr, 0,
sizeof(
addr.ipv6.sin6_addr));
2244 switch(
addr.address.sa_family) {
2245 #if defined(AF_INET6) && defined(IPPROTO_IPV6) 2247 rtn = ::setsockopt(
so, IPPROTO_IPV6, IPV6_MULTICAST_IF, (
char *)&
addr.ipv6.sin6_addr,
sizeof(
addr.ipv6.sin6_addr));
2249 rtn = ::setsockopt(
so, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (
char *)&
ttl,
sizeof(
ttl));
2258 #ifdef IP_MULTICAST_IF 2259 rtn = ::setsockopt(
so, IPPROTO_IP, IP_MULTICAST_IF, (
char *)&
addr.ipv4.sin_addr,
sizeof(
addr.ipv4.sin_addr));
2261 rtn = ::setsockopt(
so, IPPROTO_IP, IP_MULTICAST_TTL, (
char *)&
ttl,
sizeof(
ttl));
2313 #if defined(_MSWINDOWS_) 2314 unsigned long flag = (enable ? 0 : 1);
2315 if(!ioctlsocket(
so, FIONBIO, &flag))
2319 long flags = fcntl(
so, F_GETFL);
2324 if(!fcntl(
so, F_SETFL, flags))
2337 struct sockaddr_in inaddr;
2340 struct sockaddr *
addr = (
struct sockaddr *)&us.saddr;
2341 socklen_t
len =
sizeof(us.saddr);
2343 #if defined(_MSWINDOWS_) 2345 int family = us.inaddr.sin_family;
2346 memset(
addr, 0,
sizeof(us.saddr));
2347 us.inaddr.sin_family =
family;
2349 memset(
addr, 0,
sizeof(us.saddr));
2352 if((
size_t)
len >
sizeof(us.saddr))
2353 len =
sizeof(us.saddr);
2366 assert(node != NULL);
2378 ::getsockname(
so, (
struct sockaddr *)&
addr, &
len);
2379 while(!rtn && node && node->
ai_addr) {
2385 switch(
addr.address.sa_family) {
2386 #if defined(AF_INET6) && defined(IPV6_ADD_MEMBERSHIP) && defined(IPPROTO_IPV6) 2388 mcast.ipv6.ipv6mr_interface = ifindex;
2389 memcpy(&mcast.ipv6.ipv6mr_multiaddr, &target->ipv6.sin6_addr,
sizeof(target->ipv6.sin6_addr));
2390 rtn = ::setsockopt(
so, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (
char *)&mcast,
sizeof(mcast.ipv6));
2393 #if defined(IP_ADD_MEMBERSHIP) 2395 mcast.ipv4.imr_interface.s_addr = INADDR_ANY;
2396 memcpy(&mcast.ipv4.imr_multiaddr, &target->
ipv4.sin_addr,
sizeof(target->
ipv4.sin_addr));
2397 rtn = ::setsockopt(
so, IPPROTO_IP, IP_ADD_MEMBERSHIP, (
char *)&mcast,
sizeof(mcast.ipv4));
2414 assert(node != NULL);
2426 ::getsockname(
so, (
struct sockaddr *)&
addr, &
len);
2427 while(!rtn && node && node->
ai_addr) {
2435 switch(
addr.address.sa_family) {
2436 #if defined(AF_INET6) && defined(IPV6_DROP_MEMBERSHIP) && defined(IPPROTO_IPV6) 2438 mcast.ipv6.ipv6mr_interface = ifindex;
2439 memcpy(&mcast.ipv6.ipv6mr_multiaddr, &target->ipv6.sin6_addr,
sizeof(target->ipv6.sin6_addr));
2440 rtn = ::setsockopt(
so, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (
char *)&mcast,
sizeof(mcast.ipv6));
2443 #if defined(IP_DROP_MEMBERSHIP) 2445 mcast.ipv4.imr_interface.s_addr = INADDR_ANY;
2446 memcpy(&mcast.ipv4.imr_multiaddr, &target->
ipv4.sin_addr,
sizeof(target->
ipv4.sin_addr));
2447 rtn = ::setsockopt(
so, IPPROTO_IP, IP_DROP_MEMBERSHIP, (
char *)&mcast,
sizeof(mcast.ipv4));
2464 assert(node != NULL);
2468 int cprotocol, ctype;
2486 cprotocol = sprotocol;
2515 assert(node != NULL);
2537 if(!rtn || errno == EINPROGRESS)
2553 socklen_t slen =
sizeof(opt);
2555 if(getsockopt(
so, SOL_SOCKET, SO_ERROR, (
caddr_t)&opt, &slen))
2566 if(!setsockopt(
so, SOL_SOCKET, SO_SNDLOWAT, (
caddr_t)&size,
sizeof(size)))
2582 if(!setsockopt(
so, SOL_SOCKET, SO_SNDBUF, (
caddr_t)&size,
sizeof(size)))
2596 if(!setsockopt(
so, SOL_SOCKET, SO_RCVBUF, (
caddr_t)&size,
sizeof(size)))
2638 ioctlsocket(
so, FIONREAD, &opt);
2639 return (
unsigned)opt;
2649 if(::ioctl(
so, FIONREAD, &opt))
2651 return (
unsigned)opt;
2660 return ::accept(
so, (
struct sockaddr *)
addr, &
len);
2662 return ::accept(
so, NULL, NULL);
2679 pfd.events = POLLIN;
2687 status = ::poll(&pfd, 1, -1);
2689 status = ::poll(&pfd, 1,
timeout);
2690 if(status == -1 && errno == EINTR)
2695 if(pfd.revents & POLLIN)
2700 struct timeval *tvp = &tv;
2701 unsigned long to = (
unsigned long)
timeout;
2710 tv.tv_usec = (to % 1000) * 1000;
2711 tv.tv_sec = (to / 1000);
2716 status = ::select((
int)(
so + 1), &grp, NULL, NULL, tvp);
2719 if(FD_ISSET(
so, &grp))
2733 pfd.events = POLLOUT;
2741 status = ::poll(&pfd, 1, -1);
2743 status = ::poll(&pfd, 1,
timeout);
2744 if(status == -1 && errno == EINTR)
2749 if(pfd.revents & POLLOUT)
2754 struct timeval *tvp = &tv;
2755 unsigned long to = (
unsigned long)
timeout;
2764 tv.tv_usec = (to % 1000) * 1000;
2765 tv.tv_sec = to / 1000;
2770 status = ::select((
int)(
so + 1), NULL, &grp, NULL, tvp);
2773 if(FD_ISSET(
so, &grp))
2785 assert(iface != NULL && *iface != 0);
2786 assert(svc != NULL && *svc != 0);
2787 assert(backlog > 0);
2802 if(::listen(
so, backlog)) {
2813 return ::accept(
so, (
struct sockaddr *)
addr, &
len);
2815 return ::accept(
so, NULL, NULL);
2829 assert(hint != NULL);
2833 struct sockaddr_in in;
2835 struct sockaddr *sa = (
struct sockaddr *)&us.st;
2836 socklen_t slen =
sizeof(us.st);
2838 memset(hint, 0,
sizeof(
struct addrinfo));
2839 memset(sa, 0,
sizeof(us.st));
2840 if(::getsockname(
so, sa, &slen))
2851 socklen_t slen =
sizeof(sotype);
2852 if(getsockopt(
so, SOL_SOCKET, SO_TYPE, (
caddr_t)&sotype, &slen))
2860 socklen_t
len =
sizeof(ccids);
2861 bool supported =
false;
2867 for(
unsigned pos = 0; pos <
sizeof(ccids); ++pos) {
2868 if(
ccid == ccids[pos]) {
2886 socklen_t alen =
sizeof(size);
2893 setsockopt(
so, IPPROTO_TCP, TCP_MAXSEG, (
char *)&size,
sizeof(size));
2899 setsockopt(
so,
IPPROTO_DCCP, DCCP_MAXSEG, (
char *)&size,
sizeof(size));
2904 getsockopt(
so, IPPROTO_IP, IP_MTU, &size, &alen);
2914 assert(buf != NULL);
2920 const struct sockaddr_un *un = (
const struct sockaddr_un *)sa;
2923 switch(sa->sa_family) {
2926 if(
max >
sizeof(un->sun_path))
2927 max =
sizeof(un->sun_path);
2930 strncpy(buf, un->sun_path,
max);
2935 sl =
sizeof(
struct sockaddr_in);
2939 sl =
sizeof(
struct sockaddr_in6);
2955 assert(host != NULL && *host != 0);
2956 assert(svc != NULL && *svc != 0);
2962 if(strchr(host,
'/'))
2963 return unixaddr((
struct sockaddr_un *)sa, host);
2983 if(!::bind(
so, iface,
len(iface)))
2990 if(::bind(
so, iface,
len(iface)))
2992 if(::listen(
so, backlog))
3000 assert(host != NULL && *host != 0);
3001 assert(svc != NULL && *svc != 0);
3008 setsockopt(
so, SOL_SOCKET, SO_REUSEADDR, (
caddr_t)&reuse,
sizeof(reuse));
3011 if(host && strchr(host,
'/')) {
3013 socklen_t
len = unixaddr((
struct sockaddr_un *)&uaddr, host);
3014 rtn = ::bind(
so, (
struct sockaddr *)&uaddr,
len);
3023 if(host && !strcmp(host,
"*"))
3026 #if defined(SO_BINDTODEVICE) && !defined(__QNX__) 3027 if(host && !strchr(host,
'.') && !strchr(host,
':')) {
3029 memset(&ifr, 0,
sizeof(ifr));
3030 strncpy(ifr.ifr_ifrn.ifrn_name, host, IFNAMSIZ);
3031 ifr.ifr_name[IFNAMSIZ - 1] =
'\0';
3032 setsockopt(
so, SOL_SOCKET, SO_BINDTODEVICE, &ifr,
sizeof(ifr));
3039 #if defined(AF_INET6) && defined(AI_V4MAPPED) 3059 assert(
addr != NULL);
3060 assert(keysize > 0);
3065 switch(
addr->sa_family) {
3068 cp = (
caddr_t)(&((
const struct sockaddr_in6 *)(
addr))->sin6_addr);
3073 cp = (
caddr_t)(&((
const struct sockaddr_in *)(
addr))->sin_addr);
3083 return key % keysize;
3088 assert(
addr != NULL);
3089 assert(keysize > 0);
3094 switch(
addr->sa_family) {
3097 cp = (
caddr_t)(&((
const struct sockaddr_in6 *)(
addr))->sin6_addr);
3103 cp = (
caddr_t)(&((
const struct sockaddr_in *)(
addr))->sin_addr);
3114 return key % keysize;
3122 switch(
addr->sa_family) {
3125 return ntohs(((
const struct sockaddr_in6 *)(
addr))->sin6_port);
3128 return ntohs(((
const struct sockaddr_in *)(
addr))->sin_port);
3135 assert(
addr != NULL);
3136 assert(name != NULL);
3146 switch(
addr->sa_family) {
3149 String::set(name, size, ((
const struct sockaddr_un *)(
addr))->sun_path);
3155 struct sockaddr_in6 saddr6;
3156 memcpy(&saddr6,
addr,
sizeof(saddr6));
3157 saddr6.sin6_port = 0;
3158 WSAAddressToString((
struct sockaddr *)&saddr6,
sizeof(saddr6), NULL, name, &slen);
3162 struct sockaddr_in saddr;
3163 memcpy(&saddr,
addr,
sizeof(saddr));
3165 WSAAddressToString((
struct sockaddr *)&saddr,
sizeof(saddr), NULL, name, &slen);
3168 #ifdef HAVE_INET_NTOP 3171 inet_ntop(
addr->sa_family, &((
const struct sockaddr_in6 *)(
addr))->sin6_addr, name, size);
3175 inet_ntop(
addr->sa_family, &((
const struct sockaddr_in *)(
addr))->sin_addr, name, size);
3180 String::set(name, size, inet_ntoa(((
const struct sockaddr_in *)(
addr))->sin_addr));
3189 int Socket::via(
struct sockaddr *iface,
const struct sockaddr *dest, socklen_t size)
3191 assert(iface != NULL);
3192 assert(dest != NULL);
3196 socklen_t slen =
len(dest);
3199 memset(iface, 0, size);
3201 if(size && size < slen)
3205 switch(dest->sa_family) {
3210 so = ::socket(dest->sa_family, SOCK_DGRAM, 0);
3214 if(!::connect(
so, dest, slen))
3215 rtn = ::getsockname(
so, iface, &slen);
3220 switch(iface->sa_family) {
3222 ((
struct sockaddr_in*)(iface))->sin_port = 0;
3226 ((
struct sockaddr_in6*)(iface))->sin6_port = 0;
3246 assert(s1 != NULL && s2 != NULL);
3249 if(s1->sa_family != s2->sa_family)
3252 if(s1->sa_family != AF_INET)
3255 a1 = (uint8_t *)&(((
const struct sockaddr_in *)(s1))->sin_addr);
3256 a2 = (uint8_t *)&(((
const struct sockaddr_in *)(s1))->sin_addr);
3258 if(*a1 == *a2 && *a1 < 128)
3264 if(*a1 > 127 && *a1 < 192 && a1[1] == a2[1])
3278 if(storage == NULL ||
address == NULL)
3287 if(storage == NULL ||
address == NULL)
3292 memcpy(storage,
address, slen);
3298 if(s1 == NULL || s2 == NULL)
3301 socklen_t slen =
len(s1);
3303 memcpy(s1, s2, slen);
3311 assert(s1 != NULL && s2 != NULL);
3313 if(s1->sa_family != s2->sa_family)
3316 switch(s1->sa_family) {
3318 if(memcmp(&(((
const struct sockaddr_in *)s1)->sin_addr),
3319 &(((
const struct sockaddr_in *)s2)->sin_addr), 4))
3325 if(memcmp(&(((
const struct sockaddr_in6 *)s1)->sin6_addr),
3326 &(((
const struct sockaddr_in6 *)s2)->sin6_addr), 4))
3332 if(memcmp(s1, s2,
len(s1)))
3342 assert(s1 != NULL && s2 != NULL);
3344 if(s1->sa_family != s2->sa_family)
3347 switch(s1->sa_family) {
3349 if(memcmp(&(((
const struct sockaddr_in *)s1)->sin_addr),
3350 &(((
const struct sockaddr_in *)s2)->sin_addr), 4))
3353 if(!((
const struct sockaddr_in *)s1)->sin_port || !((
const struct sockaddr_in *)s2)->sin_port)
3356 if(((
const struct sockaddr_in *)s1)->sin_port != ((
const struct sockaddr_in *)s2)->sin_port)
3362 if(memcmp(&(((
const struct sockaddr_in6 *)s1)->sin6_addr),
3363 &(((
const struct sockaddr_in6 *)s2)->sin6_addr), 4))
3366 if(!((
const struct sockaddr_in6 *)s1)->sin6_port || !((
const struct sockaddr_in6 *)s2)->sin6_port)
3369 if(((
const struct sockaddr_in6 *)s1)->sin6_port != ((
const struct sockaddr_in6 *)s2)->sin6_port)
3375 if(memcmp(s1, s2,
len(s1)))
3384 assert(format != NULL);
3389 va_start(args, format);
3390 vsnprintf(buf,
sizeof(buf), format, args);
3398 assert(format != NULL);
3403 va_start(args, format);
3404 vsnprintf(buf,
sizeof(buf), format, args);
3407 return sendto(
so, buf, strlen(buf), 0, NULL);
3415 switch(sa->sa_family)
3418 return sizeof(sockaddr_in);
3421 return sizeof(sockaddr_in6);
3435 struct sockaddr_in inaddr;
3438 socklen_t
len =
sizeof(us.saddr);
3439 struct sockaddr *
addr = (
struct sockaddr *)(&us.saddr);
3443 return us.inaddr.sin_family;
3446 WSAPROTOCOL_INFO
info;
3448 if(getsockopt(
so, SOL_SOCKET, SO_PROTOCOL_INFO, (
char *) &
info, &
len))
3451 return info.iAddressFamily;
3457 assert(
str != NULL);
3459 while(*
str && strchr(
"0:.*", *
str) != NULL)
3474 assert(
str != NULL);
3477 if(strchr(
str,
':'))
3480 while(*
str && strchr(
"0123456789.", *
str) != NULL)
3496 memset(
addr, 0, slen);
3497 return ::getsockname(sock, (
struct sockaddr *)
addr, &slen);
3503 memset(
addr, 0, slen);
3504 return ::getpeername(sock, (
struct sockaddr *)
addr, &slen);