+2005-06-27 Michael Poole <mdpoole@troilus.org>
+
+ * include/client.h (struct Connection): Remove con_dns_reply (and
+ associated macros).
+
+ * include/res.h (gethost_byname): Change calling signature to
+ clarify memory ownership.
+ (gethost_byaddr): Likewise.
+
+ * include/s_bsd.h (release_dns_reply): Remove function.
+
+ * ircd/hash.c: #include "match.h" to quash warning.
+
+ * ircd/ircd_auth.c (struct IAuth): Remove i_query field.
+ (iauth_dns_callback): Adjust for new gethost_byname signature.
+ (iauth_reconnect): Likewise.
+
+ * ircd/ircd_res.c (struct reslist): Make elements of query field
+ inline rather than in a contained structure.
+ (make_request): Reflect removal of DNSQuery.
+ (do_query_name): Likewise.
+ (do_query_number): Likewise.
+ (make_dnsreply): Remove now-unused function.
+ (timeout_resolver): Adjust to new callback signature.
+ (delete_resolver_queries): Reflect removal of DNSQuery.
+ (gethost_byname): Update to new signature.
+ (gethost_byaddr): Likewise.
+ (res_readreply): Reflect removal of DNSReply.
+
+ * ircd/list.c (dealloc_connection): con_dns_reply no longer
+ exists, so do not free it.
+
+ * ircd/s_auth.c (auth_verify_hostname): constify.
+ (auth_dns_callback): Adjust to new callback signature.
+ (start_auth): Adjust to new gethost_byaddr() signature.
+
+ * ircd/s_bsd.c (connect_dns_callback): Adjust to new callback
+ signature.
+ (release_dns_reply): Remove unused function.
+ (connect_server): Adjust to new gethost_byname() signature.
+
+ * ircd/s_conf.c (conf_dns_callback): Adjust to new callback
+ signature.
+ (conf_dns_lookup): Adjust to new gethost_byname() signature.
+ (attach_iline): Use cli_sockhost() instead of DNS reply.
+ (conf_check_server): Simplify use of DNS results.
+
+ * ircd/s_serv.c (server_estab): Remove call to removed function.
+
+ * ircd/s_user.c (register_user): Remove call to removed function.
+
2005-06-27 Michael Poole <mdpoole@troilus.org>
* include/s_misc.h (get_sockhost): Remove the unused (and
struct SLink* con_confs; /**< Associated configuration records. */
HandlerType con_handler; /**< Message index into command table
for parsing. */
- struct DNSReply* con_dns_reply; /**< DNS reply received during client
- registration. */
struct ListingArgs* con_listing; /**< Current LIST status. */
unsigned long con_unreg; /**< Indicate what still needs to be done */
unsigned int con_max_sendq; /**< cached max send queue for client */
#define cli_confs(cli) con_confs(cli_connect(cli))
/** Get handler type for client. */
#define cli_handler(cli) con_handler(cli_connect(cli))
-/** Get DNS reply for client. */
-#define cli_dns_reply(cli) con_dns_reply(cli_connect(cli))
/** Get LIST status for client. */
#define cli_listing(cli) con_listing(cli_connect(cli))
/** Get cached max SendQ for client. */
#define con_confs(con) ((con)->con_confs)
/** Get command handler for the connection. */
#define con_handler(con) ((con)->con_handler)
-/** Get DNS reply for the connection. */
-#define con_dns_reply(con) ((con)->con_dns_reply)
/** Get the LIST status for the connection. */
#define con_listing(con) ((con)->con_listing)
/** Get remining steps before registration completes. */
unsigned short port; /**< Port number, host-endian. */
};
-/** DNS reply structure. */
-struct DNSReply
-{
- char *h_name; /**< Hostname. */
- struct irc_in_addr addr; /**< IP address. */
-};
-
-/** DNS callback structure. */
-struct DNSQuery
-{
- void *vptr; /**< pointer used by callback to identify request */
- void (*callback)(void* vptr, struct DNSReply *reply); /**< callback to call */
-};
+/** DNS callback function signature. */
+typedef void (*dns_callback_f)(void *vptr, const struct irc_in_addr *addr, const char *h_name);
/** DNS query and response header. */
typedef struct
extern size_t cres_mem(struct Client* cptr);
extern void delete_resolver_queries(const void *vptr);
extern void report_dns_servers(struct Client *source_p, const struct StatDesc *sd, char *param);
-extern void gethost_byname(const char *name, const struct DNSQuery *query);
-extern void gethost_byaddr(const struct irc_in_addr *addr, const struct DNSQuery *query);
+extern void gethost_byname(const char *name, dns_callback_f callback, void *ctx);
+extern void gethost_byaddr(const struct irc_in_addr *addr, dns_callback_f callback, void *ctx);
/** Evaluate to non-zero if \a ADDR is a valid address (not all 0s and not all 1s). */
#define irc_in_addr_valid(ADDR) (((ADDR)->in6_16[0] && ~(ADDR)->in6_16[0]) \
*/
extern unsigned int deliver_it(struct Client *cptr, struct MsgQ *buf);
extern int connect_server(struct ConfItem* aconf, struct Client* by);
-extern void release_dns_reply(struct Client* cptr);
extern int net_close_unregistered_connections(struct Client* source);
extern void close_connection(struct Client *cptr);
extern void add_connection(struct Listener* listener, int fd);
#include "ircd_reply.h"
#include "ircd_string.h"
#include "ircd.h"
+#include "match.h"
#include "msg.h"
#include "numeric.h"
#include "random.h"
struct Timer i_reconn_timer; /**< when to reconnect the connection */
struct Timer i_request_timer; /**< when the current request times out */
struct IAuthFlags i_flags; /**< connection state/status/flags */
- struct DNSQuery i_query; /**< DNS lookup for iauth server */
unsigned int i_recvM; /**< messages received */
unsigned int i_sendM; /**< messages sent */
unsigned int i_recvK; /**< kilobytes received */
* @param[in] vptr Pointer to the IAuth struct.
* @param[in] he DNS reply parameters.
*/
-static void iauth_dns_callback(void *vptr, struct DNSReply *he)
+static void iauth_dns_callback(void *vptr, const struct irc_in_addr *addr, const char *h_name)
{
struct IAuth *iauth = vptr;
- if (!he) {
+ if (!addr) {
log_write(LS_IAUTH, L_NOTICE, 0, "IAuth connection to %s failed: host lookup failed", i_host(iauth));
} else {
- memcpy(&i_addr(iauth).addr, &he->addr, sizeof(i_addr(iauth).addr));
+ memcpy(&i_addr(iauth).addr, addr, sizeof(i_addr(iauth).addr));
if (!irc_in_addr_valid(&i_addr(iauth).addr)) {
log_write(LS_IAUTH, L_NOTICE, 0, "IAuth connection to %s failed: host came back as unresolved", i_host(iauth));
return;
log_write(LS_IAUTH, L_DEBUG, 0, "IAuth attempt connection to %s port %p.", i_host(iauth), i_port(iauth));
if (!irc_in_addr_valid(&i_addr(iauth).addr)
&& !ircd_aton(&i_addr(iauth).addr, i_host(iauth))) {
- i_query(iauth).vptr = iauth;
- i_query(iauth).callback = iauth_dns_callback;
- gethost_byname(i_host(iauth), &i_query(iauth));
+ gethost_byname(i_host(iauth), iauth_dns_callback, iauth);
return;
}
local = irc_in_addr_is_ipv4(&i_addr(iauth).addr) ? &VirtualHost_v4 : &VirtualHost_v6;
time_t timeout; /**< When this request times out. */
struct irc_in_addr addr; /**< Address for this request. */
char *name; /**< Hostname for this request. */
- struct DNSQuery query; /**< Query callback for this request. */
+ dns_callback_f callback; /**< Callback function on completion. */
+ void *callback_ctx; /**< Context pointer for callback. */
};
/** Base of request list. */
static struct dlink request_list;
static void rem_request(struct reslist *request);
-static struct reslist *make_request(const struct DNSQuery *query);
-static void do_query_name(const struct DNSQuery *query,
+static struct reslist *make_request(dns_callback_f callback, void *ctx);
+static void do_query_name(dns_callback_f callback, void *ctx,
const char* name, struct reslist *request, int);
-static void do_query_number(const struct DNSQuery *query,
+static void do_query_number(dns_callback_f callback, void *ctx,
const struct irc_in_addr *,
struct reslist *request);
static void query_name(const char *name, int query_class, int query_type,
static void resend_query(struct reslist *request);
static int proc_answer(struct reslist *request, HEADER *header, char *, char *);
static struct reslist *find_id(int id);
-static struct DNSReply *make_dnsreply(struct reslist *request);
static void res_readreply(struct Event *ev);
static void timeout_resolver(struct Event *notused);
* @return Newly allocated and linked-in reslist.
*/
static struct reslist *
-make_request(const struct DNSQuery* query)
+make_request(dns_callback_f callback, void *ctx)
{
struct reslist *request;
request->resend = 1;
request->timeout = feature_int(FEAT_IRCD_RES_TIMEOUT);
memset(&request->addr, 0, sizeof(request->addr));
- memcpy(&request->query, query, sizeof(request->query));
+ request->callback = callback;
+ request->callback_ctx = ctx;
add_dlink(&request->node, &request_list);
return(request);
if (--request->retries <= 0)
{
Debug((DEBUG_DNS, "Request %p out of retries; destroying", request));
- (*request->query.callback)(request->query.vptr, 0);
+ (*request->callback)(request->callback_ctx, NULL, NULL);
rem_request(request);
continue;
}
{
next_ptr = ptr->next;
request = (struct reslist*)ptr;
- if (vptr == request->query.vptr) {
+ if (vptr == request->callback_ctx) {
Debug((DEBUG_DNS, "Removing request %p with vptr %p", request, vptr));
rem_request(request);
}
* @param[in] query Callback information.
*/
void
-gethost_byname(const char *name, const struct DNSQuery *query)
+gethost_byname(const char *name, dns_callback_f callback, void *ctx)
{
- do_query_name(query, name, NULL, T_AAAA);
+ do_query_name(callback, ctx, name, NULL, T_AAAA);
}
/** Try to look up hostname for an address.
* @param[in] query Callback information.
*/
void
-gethost_byaddr(const struct irc_in_addr *addr, const struct DNSQuery *query)
+gethost_byaddr(const struct irc_in_addr *addr, dns_callback_f callback, void *ctx)
{
- do_query_number(query, addr, NULL);
+ do_query_number(callback, ctx, addr, NULL);
}
/** Send a query to look up the address for a name.
* @param[in] type Preferred request type.
*/
static void
-do_query_name(const struct DNSQuery *query, const char *name,
+do_query_name(dns_callback_f callback, void *ctx, const char *name,
struct reslist *request, int type)
{
char host_name[HOSTLEN + 1];
if (request == NULL)
{
- request = make_request(query);
+ request = make_request(callback, ctx);
DupString(request->name, host_name);
#ifdef IPV6
if (type != T_A)
* @param[in] request DNS lookup structure (may be NULL).
*/
static void
-do_query_number(const struct DNSQuery *query, const struct irc_in_addr *addr,
+do_query_number(dns_callback_f callback, void *ctx, const struct irc_in_addr *addr,
struct reslist *request)
{
char ipbuf[128];
}
if (request == NULL)
{
- request = make_request(query);
+ request = make_request(callback, ctx);
request->state= REQ_PTR;
request->type = T_PTR;
memcpy(&request->addr, addr, sizeof(request->addr));
switch(request->type)
{
case T_PTR:
- do_query_number(NULL, &request->addr, request);
+ do_query_number(NULL, NULL, &request->addr, request);
break;
case T_A:
- do_query_name(NULL, request->name, request, request->type);
+ do_query_name(NULL, NULL, request->name, request, request->type);
break;
case T_AAAA:
/* didn't work, try A */
if (request->state == REQ_AAAA)
- do_query_name(NULL, request->name, request, T_A);
+ do_query_name(NULL, NULL, request->name, request, T_A);
default:
break;
}
char buf[sizeof(HEADER) + MAXPACKET];
HEADER *header;
struct reslist *request = NULL;
- struct DNSReply *reply = NULL;
unsigned int rc;
int answer_count;
* send any more (no retries granted).
*/
Debug((DEBUG_DNS, "Request %p has bad response (state %d type %d rcode %d)", request, request->state, request->type, header->rcode));
- (*request->query.callback)(request->query.vptr, 0);
+ (*request->callback)(request->callback_ctx, NULL, NULL);
rem_request(request);
}
}
* don't bother trying again, the client address doesn't resolve
*/
Debug((DEBUG_DNS, "Request %p PTR had empty name", request));
- (*request->query.callback)(request->query.vptr, reply);
+ (*request->callback)(request->callback_ctx, NULL, NULL);
rem_request(request);
return;
}
*/
#ifdef IPV6
if (!irc_in_addr_is_ipv4(&request->addr))
- do_query_name(&request->query, request->name, NULL, T_AAAA);
+ do_query_name(request->callback, request->callback_ctx, request->name, NULL, T_AAAA);
else
#endif
- do_query_name(&request->query, request->name, NULL, T_A);
+ do_query_name(request->callback, request->callback_ctx, request->name, NULL, T_A);
Debug((DEBUG_DNS, "Request %p switching to forward resolution", request));
rem_request(request);
}
/*
* got a name and address response, client resolved
*/
- reply = make_dnsreply(request);
- (*request->query.callback)(request->query.vptr, (reply) ? reply : 0);
+ (*request->callback)(request->callback_ctx, &request->addr, request->name);
Debug((DEBUG_DNS, "Request %p got forward resolution", request));
rem_request(request);
}
}
}
-/** Build a DNSReply for a completed request.
- * @param[in] request Completed DNS request.
- * @return Newly allocated DNSReply containing host name and address.
- */
-static struct DNSReply *
-make_dnsreply(struct reslist *request)
-{
- struct DNSReply *cp;
- assert(request != 0);
-
- cp = (struct DNSReply *)MyMalloc(sizeof(struct DNSReply));
-
- DupString(cp->h_name, request->name);
- memcpy(&cp->addr, &request->addr, sizeof(cp->addr));
- return(cp);
-}
-
/** Statistics callback to list DNS servers.
* @param[in] source_p Client requesting statistics.
* @param[in] sd Stats descriptor for request (ignored).
Debug((DEBUG_LIST, "Deallocating connection %p", con));
- if (con_dns_reply(con)) {
- MyFree(con_dns_reply(con));
- con_dns_reply(con) = 0;
- }
if (-1 < con_fd(con))
close(con_fd(con));
MsgQClear(&(con_sendQ(con)));
* @return Non-zero if the hostname is valid.
*/
static int
-auth_verify_hostname(char *host, int maxlen)
+auth_verify_hostname(const char *host, int maxlen)
{
int i;
* @param vptr The pending struct AuthRequest.
* @param hp Pointer to the DNS reply (or NULL, if lookup failed).
*/
-static void auth_dns_callback(void* vptr, struct DNSReply* hp)
+static void auth_dns_callback(void* vptr, const struct irc_in_addr *addr, const char *h_name)
{
struct AuthRequest* auth = (struct AuthRequest*) vptr;
assert(auth);
*/
ClearDNSPending(auth);
- if (hp) {
+ if (addr) {
/*
* Verify that the host to ip mapping is correct both ways and that
* the ip#(s) for the socket is listed for the host.
*/
- if (irc_in_addr_cmp(&hp->addr, &cli_ip(auth->client))) {
+ if (irc_in_addr_cmp(addr, &cli_ip(auth->client))) {
if (IsUserPort(auth->client))
sendheader(auth->client, REPORT_IP_MISMATCH);
sendto_opmask_butone(0, SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%s]",
- cli_sock_ip(auth->client), hp->h_name,
- ircd_ntoa(&hp->addr));
+ cli_sock_ip(auth->client), h_name,
+ ircd_ntoa(addr));
if (feature_bool(FEAT_KILL_IPMISMATCH)) {
auth_kill_client(auth);
return;
}
}
- else if (!auth_verify_hostname(hp->h_name, HOSTLEN))
+ else if (!auth_verify_hostname(h_name, HOSTLEN))
{
if (IsUserPort(auth->client))
sendheader(auth->client, REPORT_INVAL_DNS);
}
else
{
- cli_dns_reply(auth->client) = hp;
- ircd_strncpy(cli_sockhost(auth->client), hp->h_name, HOSTLEN);
+ ircd_strncpy(cli_sockhost(auth->client), h_name, HOSTLEN);
if (IsUserPort(auth->client))
sendheader(auth->client, REPORT_FIN_DNS);
}
if (irc_in_addr_is_loopback(&cli_ip(client)))
strcpy(cli_sockhost(client), cli_name(&me));
else {
- struct DNSQuery query;
-
- query.vptr = auth;
- query.callback = auth_dns_callback;
-
if (IsUserPort(auth->client))
sendheader(client, REPORT_DO_DNS);
-
- gethost_byaddr(&cli_ip(client), &query);
+ gethost_byaddr(&cli_ip(client), auth_dns_callback, auth);
SetDNSPending(auth);
}
}
* @param vptr The struct ConfItem representing the Connect block.
* @param hp A pointer to the DNS lookup results (NULL on failure).
*/
-static void connect_dns_callback(void* vptr, struct DNSReply* hp)
+static void connect_dns_callback(void* vptr, const struct irc_in_addr *addr, const char *h_name)
{
struct ConfItem* aconf = (struct ConfItem*) vptr;
assert(aconf);
aconf->dns_pending = 0;
- if (hp) {
- memcpy(&aconf->address, &hp->addr, sizeof(aconf->address));
- MyFree(hp);
+ if (addr) {
+ memcpy(&aconf->address, addr, sizeof(aconf->address));
connect_server(aconf, 0);
}
else
return bytes_written;
}
-/** Free the client's DNS reply, if any.
- * @param cptr Client to operate on.
- */
-void release_dns_reply(struct Client* cptr)
-{
- assert(0 != cptr);
- assert(MyConnect(cptr));
-
- if (cli_dns_reply(cptr)) {
- MyFree(cli_dns_reply(cptr)->h_name);
- MyFree(cli_dns_reply(cptr));
- cli_dns_reply(cptr) = 0;
- }
-}
-
/** Complete non-blocking connect()-sequence. Check access and
* terminate connection, if trouble detected.
* @param cptr Client to which we have connected, with all ConfItem structs attached.
if (!irc_in_addr_valid(&aconf->address.addr)
&& !ircd_aton(&aconf->address.addr, aconf->host)) {
char buf[HOSTLEN + 1];
- struct DNSQuery query;
- query.vptr = aconf;
- query.callback = connect_dns_callback;
host_from_uh(buf, aconf->host, HOSTLEN);
- buf[HOSTLEN] = '\0';
-
- gethost_byname(buf, &query);
+ gethost_byname(buf, connect_dns_callback, aconf);
aconf->dns_pending = 1;
return 0;
}
* @param vptr Pointer to struct ConfItem for the block.
* @param hp DNS reply, or NULL if the lookup failed.
*/
-static void conf_dns_callback(void* vptr, struct DNSReply* hp)
+static void conf_dns_callback(void* vptr, const struct irc_in_addr *addr, const char *h_name)
{
struct ConfItem* aconf = (struct ConfItem*) vptr;
assert(aconf);
aconf->dns_pending = 0;
- if (hp) {
- memcpy(&aconf->address.addr, &hp->addr, sizeof(aconf->address.addr));
- MyFree(hp);
- }
+ if (addr)
+ memcpy(&aconf->address.addr, addr, sizeof(aconf->address.addr));
}
/** Start a nameserver lookup of the conf host. If the conf entry is
{
if (!aconf->dns_pending) {
char buf[HOSTLEN + 1];
- struct DNSQuery query;
- query.vptr = aconf;
- query.callback = conf_dns_callback;
- host_from_uh(buf, aconf->host, HOSTLEN);
- buf[HOSTLEN] = '\0';
- gethost_byname(buf, &query);
+ host_from_uh(buf, aconf->host, HOSTLEN);
+ gethost_byname(buf, conf_dns_callback, aconf);
aconf->dns_pending = 1;
}
}
enum AuthorizationCheckResult attach_iline(struct Client* cptr)
{
struct ConfItem* aconf;
- struct DNSReply* hp;
assert(0 != cptr);
- hp = cli_dns_reply(cptr);
for (aconf = GlobalConfList; aconf; aconf = aconf->next) {
if (aconf->status != CONF_CLIENT)
continue;
if (match(aconf->username, cli_username(cptr)))
continue;
}
- if (aconf->host && (!hp || match(aconf->host, hp->h_name)))
+ if (aconf->host && match(aconf->host, cli_sockhost(cptr)))
continue;
if ((aconf->addrbits >= 0)
&& !ipmask_check(&cli_ip(cptr), &aconf->address.addr, aconf->addrbits))
}
}
- if (!c_conf) {
- if (cli_dns_reply(cptr)) {
- struct DNSReply* hp = cli_dns_reply(cptr);
- const char* name = hp->h_name;
- /*
- * If we are missing a C or N line from above, search for
- * it under all known hostnames we have for this ip#.
- */
- if ((c_conf = find_conf_byhost(lp, hp->h_name, CONF_SERVER)))
- ircd_strncpy(cli_sockhost(cptr), name, HOSTLEN);
- else
- c_conf = find_conf_byip(lp, &hp->addr, CONF_SERVER);
- }
- else {
- /*
- * Check for C lines with the hostname portion the ip number
- * of the host the server runs on. This also checks the case where
- * there is a server connecting from 'localhost'.
- */
- c_conf = find_conf_byhost(lp, cli_sockhost(cptr), CONF_SERVER);
- }
- }
+ /* Try finding the Connect block by DNS name and IP next. */
+ if (!c_conf && !(c_conf = find_conf_byhost(lp, cli_sockhost(cptr), CONF_SERVER)))
+ c_conf = find_conf_byip(lp, &cli_ip(cptr), CONF_SERVER);
+
/*
* Attach by IP# only if all other checks have failed.
* It is quite possible to get here with the strange things that can
SetServer(cptr);
cli_handler(cptr) = SERVER_HANDLER;
Count_unknownbecomesserver(UserStats);
-
- release_dns_reply(cptr);
-
SetBurst(cptr);
/* nextping = CurrentTime; */
SetUser(sptr);
cli_handler(sptr) = CLIENT_HANDLER;
- release_dns_reply(sptr);
SetLocalNumNick(sptr);
send_reply(sptr,
RPL_WELCOME,