ip_resolver.cpp
Go to the documentation of this file.
1 #include "precompiled.hpp"
2 #include <string>
3 #include <cstring>
4 
5 #include "macros.hpp"
6 #include "stdint.hpp"
7 #include "err.hpp"
8 #include "ip.hpp"
9 
10 #ifndef ZMQ_HAVE_WINDOWS
11 #include <sys/types.h>
12 #include <arpa/inet.h>
13 #include <netinet/tcp.h>
14 #include <net/if.h>
15 #include <netdb.h>
16 #include <ctype.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #endif
20 
21 #include "ip_resolver.hpp"
22 
24 {
25  return generic.sa_family;
26 }
27 
29 {
30  if (family () == AF_INET) {
31  // IPv4 Multicast: address MSBs are 1110
32  // Range: 224.0.0.0 - 239.255.255.255
33  return IN_MULTICAST (ntohl (ipv4.sin_addr.s_addr));
34  }
35  // IPv6 Multicast: ff00::/8
36  return IN6_IS_ADDR_MULTICAST (&ipv6.sin6_addr) != 0;
37 }
38 
39 uint16_t zmq::ip_addr_t::port () const
40 {
41  if (family () == AF_INET6) {
42  return ntohs (ipv6.sin6_port);
43  }
44  return ntohs (ipv4.sin_port);
45 }
46 
47 const struct sockaddr *zmq::ip_addr_t::as_sockaddr () const
48 {
49  return &generic;
50 }
51 
53 {
54  return static_cast<zmq_socklen_t> (family () == AF_INET6 ? sizeof (ipv6)
55  : sizeof (ipv4));
56 }
57 
58 void zmq::ip_addr_t::set_port (uint16_t port_)
59 {
60  if (family () == AF_INET6) {
61  ipv6.sin6_port = htons (port_);
62  } else {
63  ipv4.sin_port = htons (port_);
64  }
65 }
66 
67 // Construct an "ANY" address for the given family
69 {
70  ip_addr_t addr;
71 
72  if (family_ == AF_INET) {
73  sockaddr_in *ip4_addr = &addr.ipv4;
74  memset (ip4_addr, 0, sizeof (*ip4_addr));
75  ip4_addr->sin_family = AF_INET;
76  ip4_addr->sin_addr.s_addr = htonl (INADDR_ANY);
77  } else if (family_ == AF_INET6) {
78  sockaddr_in6 *ip6_addr = &addr.ipv6;
79 
80  memset (ip6_addr, 0, sizeof (*ip6_addr));
81  ip6_addr->sin6_family = AF_INET6;
82 #ifdef ZMQ_HAVE_VXWORKS
83  struct in6_addr newaddr = IN6ADDR_ANY_INIT;
84  memcpy (&ip6_addr->sin6_addr, &newaddr, sizeof (in6_addr));
85 #else
86  memcpy (&ip6_addr->sin6_addr, &in6addr_any, sizeof (in6addr_any));
87 #endif
88  } else {
89  assert (0 == "unsupported address family");
90  }
91 
92  return addr;
93 }
94 
96  _bindable_wanted (false),
97  _nic_name_allowed (false),
98  _ipv6_wanted (false),
99  _port_expected (false),
100  _dns_allowed (false),
101  _path_allowed (false)
102 {
103 }
104 
107 {
108  _bindable_wanted = bindable_;
109 
110  return *this;
111 }
112 
115 {
116  _nic_name_allowed = allow_;
117 
118  return *this;
119 }
120 
122 {
123  _ipv6_wanted = ipv6_;
124 
125  return *this;
126 }
127 
128 // If true we expect that the host will be followed by a colon and a port
129 // number or service name
132 {
133  _port_expected = expect_;
134 
135  return *this;
136 }
137 
139 {
140  _dns_allowed = allow_;
141 
142  return *this;
143 }
144 
146 {
147  _path_allowed = allow_;
148 
149  return *this;
150 }
151 
153 {
154  return _bindable_wanted;
155 }
156 
158 {
159  return _nic_name_allowed;
160 }
161 
163 {
164  return _ipv6_wanted;
165 }
166 
168 {
169  return _port_expected;
170 }
171 
173 {
174  return _dns_allowed;
175 }
176 
178 {
179  return _path_allowed;
180 }
181 
183  _options (opts_)
184 {
185 }
186 
187 int zmq::ip_resolver_t::resolve (ip_addr_t *ip_addr_, const char *name_)
188 {
189  std::string addr;
190  uint16_t port;
191 
192  if (_options.expect_port ()) {
193  // We expect 'addr:port'. It's important to use str*r*chr to only get
194  // the latest colon since IPv6 addresses use colons as delemiters.
195  const char *delim = strrchr (name_, ':');
196 
197  if (delim == NULL) {
198  errno = EINVAL;
199  return -1;
200  }
201 
202  addr = std::string (name_, delim - name_);
203  const std::string port_str = std::string (delim + 1);
204 
205  if (port_str == "*") {
206  if (_options.bindable ()) {
207  // Resolve wildcard to 0 to allow autoselection of port
208  port = 0;
209  } else {
210  errno = EINVAL;
211  return -1;
212  }
213  } else if (port_str == "0") {
214  // Using "0" for a bind address is equivalent to using "*". For a
215  // connectable address it could be used to connect to port 0.
216  port = 0;
217  } else {
218  // Parse the port number (0 is not a valid port).
219  port = static_cast<uint16_t> (atoi (port_str.c_str ()));
220  if (port == 0) {
221  errno = EINVAL;
222  return -1;
223  }
224  }
225  } else {
226  addr = std::string (name_);
227  port = 0;
228  }
229 
230  // Check if path is allowed in ip address, if allowed it must be truncated
231  if (_options.allow_path ()) {
232  const size_t pos = addr.find ('/');
233  if (pos != std::string::npos)
234  addr = addr.substr (0, pos);
235  }
236 
237  // Trim any square brackets surrounding the address. Used for
238  // IPv6 addresses to remove the confusion with the port
239  // delimiter.
240  // TODO Should we validate that the brackets are present if
241  // 'addr' contains ':' ?
242  const size_t brackets_length = 2;
243  if (addr.size () >= brackets_length && addr[0] == '['
244  && addr[addr.size () - 1] == ']') {
245  addr = addr.substr (1, addr.size () - brackets_length);
246  }
247 
248  // Look for an interface name / zone_id in the address
249  // Reference: https://tools.ietf.org/html/rfc4007
250  const std::size_t pos = addr.rfind ('%');
251  uint32_t zone_id = 0;
252 
253  if (pos != std::string::npos) {
254  std::string if_str = addr.substr (pos + 1);
255  if (if_str.empty ()) {
256  errno = EINVAL;
257  return -1;
258  }
259  addr = addr.substr (0, pos);
260 
261  if (isalpha (if_str.at (0))) {
262  zone_id = do_if_nametoindex (if_str.c_str ());
263  } else {
264  zone_id = static_cast<uint32_t> (atoi (if_str.c_str ()));
265  }
266 
267  if (zone_id == 0) {
268  errno = EINVAL;
269  return -1;
270  }
271  }
272 
273  bool resolved = false;
274  const char *addr_str = addr.c_str ();
275 
276  if (_options.bindable () && addr == "*") {
277  // Return an ANY address
278  *ip_addr_ = ip_addr_t::any (_options.ipv6 () ? AF_INET6 : AF_INET);
279  resolved = true;
280  }
281 
282  if (!resolved && _options.allow_nic_name ()) {
283  // Try to resolve the string as a NIC name.
284  const int rc = resolve_nic_name (ip_addr_, addr_str);
285 
286  if (rc == 0) {
287  resolved = true;
288  } else if (errno != ENODEV) {
289  return rc;
290  }
291  }
292 
293  if (!resolved) {
294  const int rc = resolve_getaddrinfo (ip_addr_, addr_str);
295 
296  if (rc != 0) {
297  return rc;
298  }
299  resolved = true;
300  }
301 
302  // Store the port into the structure. We could get 'getaddrinfo' to do it
303  // for us but since we don't resolve service names it's a bit overkill and
304  // we'd still have to do it manually when the address is resolved by
305  // 'resolve_nic_name'
306  ip_addr_->set_port (port);
307 
308  if (ip_addr_->family () == AF_INET6) {
309  ip_addr_->ipv6.sin6_scope_id = zone_id;
310  }
311 
312  assert (resolved == true);
313  return 0;
314 }
315 
317  const char *addr_)
318 {
319 #if defined ZMQ_HAVE_OPENVMS && defined __ia64
320  __addrinfo64 *res = NULL;
321  __addrinfo64 req;
322 #else
323  addrinfo *res = NULL;
324  addrinfo req;
325 #endif
326 
327  memset (&req, 0, sizeof (req));
328 
329  // Choose IPv4 or IPv6 protocol family. Note that IPv6 allows for
330  // IPv4-in-IPv6 addresses.
331  req.ai_family = _options.ipv6 () ? AF_INET6 : AF_INET;
332 
333  // Arbitrary, not used in the output, but avoids duplicate results.
334  req.ai_socktype = SOCK_STREAM;
335 
336  req.ai_flags = 0;
337 
338  if (_options.bindable ()) {
339  req.ai_flags |= AI_PASSIVE;
340  }
341 
342  if (!_options.allow_dns ()) {
343  req.ai_flags |= AI_NUMERICHOST;
344  }
345 
346 #if defined AI_V4MAPPED
347  // In this API we only require IPv4-mapped addresses when
348  // no native IPv6 interfaces are available (~AI_ALL).
349  // This saves an additional DNS roundtrip for IPv4 addresses.
350  if (req.ai_family == AF_INET6) {
351  req.ai_flags |= AI_V4MAPPED;
352  }
353 #endif
354 
355  // Resolve the literal address. Some of the error info is lost in case
356  // of error, however, there's no way to report EAI errors via errno.
357  int rc = do_getaddrinfo (addr_, NULL, &req, &res);
358 
359 #if defined AI_V4MAPPED
360  // Some OS do have AI_V4MAPPED defined but it is not supported in getaddrinfo()
361  // returning EAI_BADFLAGS. Detect this and retry
362  if (rc == EAI_BADFLAGS && (req.ai_flags & AI_V4MAPPED)) {
363  req.ai_flags &= ~AI_V4MAPPED;
364  rc = do_getaddrinfo (addr_, NULL, &req, &res);
365  }
366 #endif
367 
368 #if defined ZMQ_HAVE_WINDOWS
369  // Resolve specific case on Windows platform when using IPv4 address
370  // with ZMQ_IPv6 socket option.
371  if ((req.ai_family == AF_INET6) && (rc == WSAHOST_NOT_FOUND)) {
372  req.ai_family = AF_INET;
373  rc = do_getaddrinfo (addr_, NULL, &req, &res);
374  }
375 #endif
376 
377  if (rc) {
378  switch (rc) {
379  case EAI_MEMORY:
380  errno = ENOMEM;
381  break;
382  default:
383  if (_options.bindable ()) {
384  errno = ENODEV;
385  } else {
386  errno = EINVAL;
387  }
388  break;
389  }
390  return -1;
391  }
392 
393  // Use the first result.
394  zmq_assert (res != NULL);
395  zmq_assert (static_cast<size_t> (res->ai_addrlen) <= sizeof (*ip_addr_));
396  memcpy (ip_addr_, res->ai_addr, res->ai_addrlen);
397 
398  // Cleanup getaddrinfo after copying the possibly referenced result.
399  do_freeaddrinfo (res);
400 
401  return 0;
402 }
403 
404 #ifdef ZMQ_HAVE_SOLARIS
405 #include <sys/sockio.h>
406 
407 // On Solaris platform, network interface name can be queried by ioctl.
408 int zmq::ip_resolver_t::resolve_nic_name (ip_addr_t *ip_addr_, const char *nic_)
409 {
410  // Create a socket.
411  const int fd = open_socket (AF_INET, SOCK_DGRAM, 0);
412  errno_assert (fd != -1);
413 
414  // Retrieve number of interfaces.
415  lifnum ifn;
416  ifn.lifn_family = AF_INET;
417  ifn.lifn_flags = 0;
418  int rc = ioctl (fd, SIOCGLIFNUM, (char *) &ifn);
419  errno_assert (rc != -1);
420 
421  // Allocate memory to get interface names.
422  const size_t ifr_size = sizeof (struct lifreq) * ifn.lifn_count;
423  char *ifr = (char *) malloc (ifr_size);
424  alloc_assert (ifr);
425 
426  // Retrieve interface names.
427  lifconf ifc;
428  ifc.lifc_family = AF_INET;
429  ifc.lifc_flags = 0;
430  ifc.lifc_len = ifr_size;
431  ifc.lifc_buf = ifr;
432  rc = ioctl (fd, SIOCGLIFCONF, (char *) &ifc);
433  errno_assert (rc != -1);
434 
435  // Find the interface with the specified name and AF_INET family.
436  bool found = false;
437  lifreq *ifrp = ifc.lifc_req;
438  for (int n = 0; n < (int) (ifc.lifc_len / sizeof (lifreq)); n++, ifrp++) {
439  if (!strcmp (nic_, ifrp->lifr_name)) {
440  rc = ioctl (fd, SIOCGLIFADDR, (char *) ifrp);
441  errno_assert (rc != -1);
442  if (ifrp->lifr_addr.ss_family == AF_INET) {
443  ip_addr_->ipv4 = *(sockaddr_in *) &ifrp->lifr_addr;
444  found = true;
445  break;
446  }
447  }
448  }
449 
450  // Clean-up.
451  free (ifr);
452  close (fd);
453 
454  if (!found) {
455  errno = ENODEV;
456  return -1;
457  }
458  return 0;
459 }
460 
461 #elif defined ZMQ_HAVE_AIX || defined ZMQ_HAVE_HPUX \
462  || defined ZMQ_HAVE_ANDROID || defined ZMQ_HAVE_VXWORKS
463 #include <sys/ioctl.h>
464 #ifdef ZMQ_HAVE_VXWORKS
465 #include <ioLib.h>
466 #endif
467 
468 int zmq::ip_resolver_t::resolve_nic_name (ip_addr_t *ip_addr_, const char *nic_)
469 {
470 #if defined ZMQ_HAVE_AIX || defined ZMQ_HAVE_HPUX
471  // IPv6 support not implemented for AIX or HP/UX.
472  if (_options.ipv6 ()) {
473  errno = ENODEV;
474  return -1;
475  }
476 #endif
477 
478  // Create a socket.
479  const int sd =
480  open_socket (_options.ipv6 () ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
481  errno_assert (sd != -1);
482 
483  struct ifreq ifr;
484 
485  // Copy interface name for ioctl get.
486  strncpy (ifr.ifr_name, nic_, sizeof (ifr.ifr_name));
487 
488  // Fetch interface address.
489  const int rc = ioctl (sd, SIOCGIFADDR, (caddr_t) &ifr, sizeof (ifr));
490 
491  // Clean up.
492  close (sd);
493 
494  if (rc == -1) {
495  errno = ENODEV;
496  return -1;
497  }
498 
499  const int family = ifr.ifr_addr.sa_family;
500  if (family == (_options.ipv6 () ? AF_INET6 : AF_INET)
501  && !strcmp (nic_, ifr.ifr_name)) {
502  memcpy (ip_addr_, &ifr.ifr_addr,
503  (family == AF_INET) ? sizeof (struct sockaddr_in)
504  : sizeof (struct sockaddr_in6));
505  } else {
506  errno = ENODEV;
507  return -1;
508  }
509 
510  return 0;
511 }
512 
513 #elif ((defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_FREEBSD \
514  || defined ZMQ_HAVE_OSX || defined ZMQ_HAVE_OPENBSD \
515  || defined ZMQ_HAVE_QNXNTO || defined ZMQ_HAVE_NETBSD \
516  || defined ZMQ_HAVE_DRAGONFLY || defined ZMQ_HAVE_GNU) \
517  && defined ZMQ_HAVE_IFADDRS)
518 
519 #include <ifaddrs.h>
520 
521 // On these platforms, network interface name can be queried
522 // using getifaddrs function.
523 int zmq::ip_resolver_t::resolve_nic_name (ip_addr_t *ip_addr_, const char *nic_)
524 {
525  // Get the addresses.
526  ifaddrs *ifa = NULL;
527  int rc = 0;
528  const int max_attempts = 10;
529  const int backoff_msec = 1;
530  for (int i = 0; i < max_attempts; i++) {
531  rc = getifaddrs (&ifa);
532  if (rc == 0 || (rc < 0 && errno != ECONNREFUSED))
533  break;
534  usleep ((backoff_msec << i) * 1000);
535  }
536 
537  if (rc != 0 && ((errno == EINVAL) || (errno == EOPNOTSUPP))) {
538  // Windows Subsystem for Linux compatibility
539  errno = ENODEV;
540  return -1;
541  }
542  errno_assert (rc == 0);
543  zmq_assert (ifa != NULL);
544 
545  // Find the corresponding network interface.
546  bool found = false;
547  for (const ifaddrs *ifp = ifa; ifp != NULL; ifp = ifp->ifa_next) {
548  if (ifp->ifa_addr == NULL)
549  continue;
550 
551  const int family = ifp->ifa_addr->sa_family;
552  if (family == (_options.ipv6 () ? AF_INET6 : AF_INET)
553  && !strcmp (nic_, ifp->ifa_name)) {
554  memcpy (ip_addr_, ifp->ifa_addr,
555  (family == AF_INET) ? sizeof (struct sockaddr_in)
556  : sizeof (struct sockaddr_in6));
557  found = true;
558  break;
559  }
560  }
561 
562  // Clean-up;
563  freeifaddrs (ifa);
564 
565  if (!found) {
566  errno = ENODEV;
567  return -1;
568  }
569  return 0;
570 }
571 
572 #elif (defined ZMQ_HAVE_WINDOWS)
573 
574 #include <netioapi.h>
575 
576 int zmq::ip_resolver_t::get_interface_name (unsigned long index_,
577  char **dest_) const
578 {
579 #ifdef ZMQ_HAVE_WINDOWS_UWP
580  char *buffer = (char *) malloc (1024);
581 #else
582  char *buffer = static_cast<char *> (malloc (IF_MAX_STRING_SIZE));
583 #endif
585 
586  char *if_name_result = NULL;
587 
588 #if _WIN32_WINNT > _WIN32_WINNT_WINXP && !defined ZMQ_HAVE_WINDOWS_UWP
589  if_name_result = if_indextoname (index_, buffer);
590 #endif
591 
592  if (if_name_result == NULL) {
593  free (buffer);
594  return -1;
595  }
596 
597  *dest_ = buffer;
598  return 0;
599 }
600 
601 int zmq::ip_resolver_t::wchar_to_utf8 (const WCHAR *src_, char **dest_) const
602 {
603  int rc;
604  const int buffer_len =
605  WideCharToMultiByte (CP_UTF8, 0, src_, -1, NULL, 0, NULL, 0);
606 
607  char *buffer = static_cast<char *> (malloc (buffer_len));
609 
610  rc =
611  WideCharToMultiByte (CP_UTF8, 0, src_, -1, buffer, buffer_len, NULL, 0);
612 
613  if (rc == 0) {
614  free (buffer);
615  return -1;
616  }
617 
618  *dest_ = buffer;
619  return 0;
620 }
621 
622 int zmq::ip_resolver_t::resolve_nic_name (ip_addr_t *ip_addr_, const char *nic_)
623 {
624  int rc;
625  bool found = false;
626  const int max_attempts = 10;
627 
628  int iterations = 0;
629  IP_ADAPTER_ADDRESSES *addresses;
630  unsigned long out_buf_len = sizeof (IP_ADAPTER_ADDRESSES);
631 
632  do {
633  addresses = static_cast<IP_ADAPTER_ADDRESSES *> (malloc (out_buf_len));
634  alloc_assert (addresses);
635 
636  rc =
637  GetAdaptersAddresses (AF_UNSPEC,
638  GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST
639  | GAA_FLAG_SKIP_DNS_SERVER,
640  NULL, addresses, &out_buf_len);
641  if (rc == ERROR_BUFFER_OVERFLOW) {
642  free (addresses);
643  addresses = NULL;
644  } else {
645  break;
646  }
647  iterations++;
648  } while ((rc == ERROR_BUFFER_OVERFLOW) && (iterations < max_attempts));
649 
650  if (rc == 0) {
651  for (const IP_ADAPTER_ADDRESSES *current_addresses = addresses;
652  current_addresses; current_addresses = current_addresses->Next) {
653  char *if_name = NULL;
654  char *if_friendly_name = NULL;
655 
656  const int str_rc1 =
657  get_interface_name (current_addresses->IfIndex, &if_name);
658  const int str_rc2 = wchar_to_utf8 (current_addresses->FriendlyName,
659  &if_friendly_name);
660 
661  // Find a network adapter by its "name" or "friendly name"
662  if (((str_rc1 == 0) && (!strcmp (nic_, if_name)))
663  || ((str_rc2 == 0) && (!strcmp (nic_, if_friendly_name)))) {
664  // Iterate over all unicast addresses bound to the current network interface
665  for (const IP_ADAPTER_UNICAST_ADDRESS *current_unicast_address =
666  current_addresses->FirstUnicastAddress;
667  current_unicast_address;
668  current_unicast_address = current_unicast_address->Next) {
669  const ADDRESS_FAMILY family =
670  current_unicast_address->Address.lpSockaddr->sa_family;
671 
672  if (family == (_options.ipv6 () ? AF_INET6 : AF_INET)) {
673  memcpy (
674  ip_addr_, current_unicast_address->Address.lpSockaddr,
675  (family == AF_INET) ? sizeof (struct sockaddr_in)
676  : sizeof (struct sockaddr_in6));
677  found = true;
678  break;
679  }
680  }
681 
682  if (found)
683  break;
684  }
685 
686  if (str_rc1 == 0)
687  free (if_name);
688  if (str_rc2 == 0)
689  free (if_friendly_name);
690  }
691 
692  free (addresses);
693  }
694 
695  if (!found) {
696  errno = ENODEV;
697  return -1;
698  }
699  return 0;
700 }
701 
702 #else
703 
704 // On other platforms we assume there are no sane interface names.
705 int zmq::ip_resolver_t::resolve_nic_name (ip_addr_t *ip_addr_, const char *nic_)
706 {
707  LIBZMQ_UNUSED (ip_addr_);
708  LIBZMQ_UNUSED (nic_);
709 
710  errno = ENODEV;
711  return -1;
712 }
713 
714 #endif
715 
716 int zmq::ip_resolver_t::do_getaddrinfo (const char *node_,
717  const char *service_,
718  const struct addrinfo *hints_,
719  struct addrinfo **res_)
720 {
721  return getaddrinfo (node_, service_, hints_, res_);
722 }
723 
724 void zmq::ip_resolver_t::do_freeaddrinfo (struct addrinfo *res_)
725 {
726  freeaddrinfo (res_);
727 }
728 
729 
730 unsigned int zmq::ip_resolver_t::do_if_nametoindex (const char *ifname_)
731 {
732 #ifdef HAVE_IF_NAMETOINDEX
733  return if_nametoindex (ifname_);
734 #else
735  LIBZMQ_UNUSED (ifname_);
736  // The function 'if_nametoindex' is not supported on Windows XP.
737  // If we are targeting XP using a vxxx_xp toolset then fail.
738  // This is brutal as this code could be run on later windows clients
739  // meaning the IPv6 zone_id cannot have an interface name.
740  // This could be fixed with a runtime check.
741  return 0;
742 #endif
743 }
zmq::ip_addr_t::ipv6
sockaddr_in6 ipv6
Definition: ip_resolver.hpp:20
zmq::ip_addr_t::any
static ip_addr_t any(int family_)
Definition: ip_resolver.cpp:68
ip.hpp
NULL
NULL
Definition: test_security_zap.cpp:405
EINVAL
#define EINVAL
Definition: errno.hpp:25
zmq::ip_resolver_options_t::expect_port
bool expect_port()
Definition: ip_resolver.cpp:167
zmq::ip_resolver_t::resolve_getaddrinfo
int resolve_getaddrinfo(ip_addr_t *ip_addr_, const char *addr_)
Definition: ip_resolver.cpp:316
precompiled.hpp
zmq_assert
#define zmq_assert(x)
Definition: err.hpp:102
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
errno
int errno
zmq::ip_resolver_options_t::allow_nic_name
bool allow_nic_name()
Definition: ip_resolver.cpp:157
found
return found
Definition: socket_poller.cpp:456
ECONNREFUSED
#define ECONNREFUSED
Definition: zmq.h:122
alloc_assert
#define alloc_assert(x)
Definition: err.hpp:146
errno_assert
#define errno_assert(x)
Definition: err.hpp:113
zmq::ip_resolver_t::do_getaddrinfo
virtual int do_getaddrinfo(const char *node_, const char *service_, const struct addrinfo *hints_, struct addrinfo **res_)
Definition: ip_resolver.cpp:716
zmq::ip_resolver_options_t::ipv6
bool ipv6()
Definition: ip_resolver.cpp:162
zmq::ip_resolver_options_t::allow_path
bool allow_path()
Definition: ip_resolver.cpp:177
zmq::ip_addr_t::ipv4
sockaddr_in ipv4
Definition: ip_resolver.hpp:19
zmq::ip_addr_t
Definition: ip_resolver.hpp:16
macros.hpp
stdint.hpp
buffer
GLuint buffer
Definition: glcorearb.h:2939
LIBZMQ_UNUSED
#define LIBZMQ_UNUSED(object)
Definition: macros.hpp:6
zmq::ip_resolver_t::do_if_nametoindex
virtual unsigned int do_if_nametoindex(const char *ifname_)
Definition: ip_resolver.cpp:730
zmq::ip_resolver_options_t::allow_dns
bool allow_dns()
Definition: ip_resolver.cpp:172
name_
string name_
Definition: googletest.cc:182
buffer
Definition: buffer_processor.h:43
zmq::ip_resolver_t::resolve
int resolve(ip_addr_t *ip_addr_, const char *name_)
Definition: ip_resolver.cpp:187
index_
int index_
Definition: gmock-matchers_test.cc:6752
zmq::open_socket
fd_t open_socket(int domain_, int type_, int protocol_)
Definition: ip.cpp:73
n
GLdouble n
Definition: glcorearb.h:4153
zmq::ip_addr_t::set_port
void set_port(uint16_t)
Definition: ip_resolver.cpp:58
zmq::ip_addr_t::as_sockaddr
const struct sockaddr * as_sockaddr() const
Definition: ip_resolver.cpp:47
i
int i
Definition: gmock-matchers_test.cc:764
zmq::ip_resolver_t::resolve_nic_name
int resolve_nic_name(ip_addr_t *ip_addr_, const char *nic_)
Definition: ip_resolver.cpp:705
zmq::ip_addr_t::sockaddr_len
zmq_socklen_t sockaddr_len() const
Definition: ip_resolver.cpp:52
req
void * req
Definition: test_req_relaxed.cpp:10
zmq::ip_resolver_options_t::ip_resolver_options_t
ip_resolver_options_t()
Definition: ip_resolver.cpp:95
zmq::ip_addr_t::family
int family() const
Definition: ip_resolver.cpp:23
zmq::ip_resolver_options_t
Definition: ip_resolver.hpp:34
zmq::zmq_socklen_t
socklen_t zmq_socklen_t
Definition: address.hpp:107
err.hpp
zmq::ip_addr_t::port
uint16_t port() const
Definition: ip_resolver.cpp:39
zmq::ip_addr_t::is_multicast
bool is_multicast() const
Definition: ip_resolver.cpp:28
zmq::ip_resolver_t::do_freeaddrinfo
virtual void do_freeaddrinfo(struct addrinfo *res_)
Definition: ip_resolver.cpp:724
ip_resolver.hpp
false
#define false
Definition: cJSON.c:70
zmq::ip_resolver_options_t::bindable
bool bindable()
Definition: ip_resolver.cpp:152
zmq::ip_resolver_t::ip_resolver_t
ip_resolver_t(ip_resolver_options_t opts_)
Definition: ip_resolver.cpp:182


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:54