#error this code needs to be able to address individual octets
#endif
-/** Resolver UDP socket. */
-static struct Socket res_socket;
+/** IPv4 resolver UDP socket. */
+static struct Socket res_socket_v4;
+/** IPv6 resolver UDP socket. */
+static struct Socket res_socket_v6;
/** Next DNS lookup timeout. */
static struct Timer res_timeout;
/** Check for whether the resolver has been initialized yet. */
if (!request_list.next)
request_list.next = request_list.prev = &request_list;
- if (!s_active(&res_socket))
+ if (!s_active(&res_socket_v4))
{
- int fd;
- fd = os_socket(&VirtualHost, SOCK_DGRAM, "Resolver UDP socket");
- if (fd < 0) return;
- if (!socket_add(&res_socket, res_readreply, NULL, SS_DATAGRAM,
- SOCK_EVENT_READABLE, fd)) return;
- timer_init(&res_timeout);
+ int fd = os_socket(&VirtualHost_v4, SOCK_DGRAM, "Resolver UDPv4 socket");
+ if (fd >= 0)
+ socket_add(&res_socket_v4, res_readreply, NULL,
+ SS_DATAGRAM, SOCK_EVENT_READABLE, fd);
+ }
+
+ if (!s_active(&res_socket_v6))
+ {
+ int fd = os_socket(&VirtualHost_v6, SOCK_DGRAM, "Resolver UDPv6 socket");
+ if (fd >= 0)
+ socket_add(&res_socket_v6, res_readreply, NULL,
+ SS_DATAGRAM, SOCK_EVENT_READABLE, fd);
}
+
+ if (s_active(&res_socket_v4) || s_active(&res_socket_v6))
+ timer_init(&res_timeout);
}
/** Append local domain to hostname if needed.
if (max_queries == 0)
max_queries = 1;
- for (i = 0; i < max_queries; i++)
- if (os_sendto_nonb(s_fd(&res_socket), msg, len, NULL, 0, &irc_nsaddr_list[i]) == IO_SUCCESS)
+ for (i = 0; i < max_queries; i++) {
+ int fd = irc_in_addr_is_ipv4(&irc_nsaddr_list[i].addr) ? s_fd(&res_socket_v4) : s_fd(&res_socket_v6);
+ if (os_sendto_nonb(fd, msg, len, NULL, 0, &irc_nsaddr_list[i]) == IO_SUCCESS)
++sent;
+ }
return(sent);
}
unsigned int rc;
int answer_count;
- assert(ev_socket(ev) == &res_socket);
+ assert((ev_socket(ev) == &res_socket_v4) || (ev_socket(ev) == &res_socket_v6));
sock = ev_socket(ev);
if (IO_SUCCESS != os_recvfrom_nonb(s_fd(sock), buf, sizeof(buf), &rc, &lsin)
":Resolver: requests %d(%d)", request_count, request_mem);
return request_mem;
}
-
-/** Check whether an address looks valid.
- * This means not all 0s and not all 1s.
- * @param[in] addr Address to check for validity.
- * @return Non-zero if the address looks valid.
- */
-int irc_in_addr_valid(const struct irc_in_addr *addr)
-{
- unsigned int ii;
- unsigned short val;
-
- val = addr->in6_16[0];
- if (val != 0 && val != 0xffff)
- return 1;
- for (ii = 1; ii < 8; ii++)
- if (addr->in6_16[ii] != val)
- return 1;
- return 0;
-}
-
-/** Compare two IP addresses.
- * @param[in] a First address to compare.
- * @param[in] b Second address to compare.
- * @return Non-zero if the two addresses differ, zero if they are identical.
- */
-int irc_in_addr_cmp(const struct irc_in_addr *a, const struct irc_in_addr *b)
-{
- if (irc_in_addr_is_ipv4(a))
- return a->in6_16[6] != b->in6_16[6]
- || a->in6_16[7] != b->in6_16[7]
- || !irc_in_addr_is_ipv4(b);
- else
- return memcmp(a, b, sizeof(*a));
-}
-
-/** Indicate whether an IP address is a loopback address.
- * @param[in] addr Address to check.
- * @return Non-zero if the address is loopback; zero if not.
- */
-int irc_in_addr_is_loopback(const struct irc_in_addr *addr)
-{
- if (addr->in6_16[0] != 0
- || addr->in6_16[1] != 0
- || addr->in6_16[2] != 0
- || addr->in6_16[3] != 0
- || addr->in6_16[4] != 0)
- return 0;
- if ((addr->in6_16[5] == 0xffff) || (addr->in6_16[5] == 0 && addr->in6_16[6] != 0))
- return (ntohs(addr->in6_16[6]) & 0xff00) == 0x7f00;
- else
- return addr->in6_16[5] == 0 && addr->in6_16[6] == 0 && htons(addr->in6_16[7]) == 1;
-}