+2004-11-09 Michael Poole <mdpoole@troilus.org>
+
+ * include/res.h (init_resolver): Delete, and initialize lazily.
+
+ * ircd/ircd.c (main): Do not call init_resolver().
+
+ * ircd/ircd_res.c (restart_resolver): Use default VirtualHost for
+ local resolver socket address.
+ (init_resolver): Delete.
+ (make_request): Call restart_resolver() if necessary.
+ (query_name): Use ircrandom() instead of rand().
+
+ * ircd/os_generic.c (sockaddr_from_irc): Convert last argument to
+ a file descriptor that indicates the socket family to use.
+ (os_sendto_nonb,os_socket,os_connect_nonb): Update to match.
+
2004-11-09 Michael Poole <mdpoole@troilus.org>
* ircd/engine_epoll.c (engine_delete): Do not attempt to remove a
#include "ircd.h"
#include "numeric.h"
#include "fileio.h" /* for fbopen / fbclose / fbputs */
+#include "random.h"
#include "s_bsd.h"
#include "s_debug.h"
#include "s_stats.h"
static struct Socket res_socket;
/** Next DNS lookup timeout. */
static struct Timer res_timeout;
+/** Check for whether the resolver has been initialized yet. */
+#define resolver_started() (request_list.next != NULL)
/** Maximum DNS packet length.
* RFC says 512, but we add extra for expanded names.
if (!s_active(&res_socket))
{
int fd;
- fd = os_socket(NULL, SOCK_DGRAM, "Resolver UDP socket");
+ 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;
}
}
-/** Initialize resolver.
- * This seends the pseudo-random number generator and calls
- * restart_resolver().
- * @return Resolver socket file descriptor.
- */
-int
-init_resolver(void)
-{
- srand(CurrentTime);
- restart_resolver();
- return(s_fd(&res_socket));
-}
-
/** Append local domain to hostname if needed.
* If \a hname does not contain any '.'s, append #irc_domain to it.
* @param[in,out] hname Hostname to check.
{
struct reslist *request;
+ if (!resolver_started())
+ restart_resolver();
+
request = (struct reslist *)MyMalloc(sizeof(struct reslist));
memset(request, 0, sizeof(struct reslist));
*/
do
{
- header->id = (header->id + rand()) & 0xffff;
+ header->id = (header->id + ircrandom()) & 0xffff;
} while (find_id(header->id));
request->id = header->id;
++request->sends;
/** Convert IRC socket address to native format.
* @param[out] v6 Native socket address.
* @param[in] irc IRC socket address.
- * @param[in] persist If non-zero, and \a irc is an IPv4 address,
- * create an AF_INET size address.
+ * @param[in] compat_fd If non-negative, an FD specifying address family.
* @return Length of address written to \a v6.
*/
-int sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, int persist)
+int sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, int compat_fd)
{
+ struct sockaddr_in6 sin6;
+ socklen_t slen;
+ int family;
+
+ slen = sizeof(sin6);
+ if ((0 <= compat_fd) && (0 == getsockname(compat_fd, (struct sockaddr*)&sin6, &slen)))
+ family = sin6.sin6_family;
+ else if (irc_in_addr_is_ipv4(&VirtualHost.addr))
+ family = AF_INET;
+ else
+ family = AF_INET6;
+
memset(v6, 0, sizeof(*v6));
if (!irc) {
memset(v6, 0, sizeof(v6));
v6->sin6_family = AF_INET6;
return sizeof(*v6);
}
- else if (persist && irc_in_addr_is_ipv4(&irc->addr)) {
+ else if ((family == AF_INET) && irc_in_addr_is_ipv4(&irc->addr)) {
struct sockaddr_in *v4 = (struct sockaddr_in*)v6;
v4->sin_family = AF_INET;
memcpy(&v4->sin_addr, &irc->addr.in6_16[6], sizeof(v4->sin_addr));
irc->port = ntohs(v4->sin_port);
}
-int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int persist)
+int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int compat_fd)
{
v4->sin_family = AF_INET;
if (irc) {
} else{
memset(&v4, 0, sizeof(v4));
}
- (void)persist;
+ (void)compat_fd;
return sizeof(*v4);
}
*count_out = 0;
errno = 0;
- size = sockaddr_from_irc(&addr, peer, 1);
+ size = sockaddr_from_irc(&addr, peer, fd);
if (-1 < (res = sendto(fd, buf, length, flags, (struct sockaddr*)&addr, size))) {
if (count_out)
*count_out = (unsigned) res;
struct sockaddr_native addr;
int size, fd;
- size = sockaddr_from_irc(&addr, local, 1);
+ size = sockaddr_from_irc(&addr, local, -1);
fd = socket(addr.sn_family, type, 0);
if (fd < 0) {
report_error(SOCKET_ERROR_MSG, port_name, errno);
struct sockaddr_native addr;
int size;
- size = sockaddr_from_irc(&addr, sin, 1);
+ size = sockaddr_from_irc(&addr, sin, fd);
if (connect(fd, (struct sockaddr*) &addr, size))
return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
return IO_SUCCESS;