PgAddr remote_addr; /* ip:port for remote endpoint */
PgAddr local_addr; /* ip:port for local endpoint */
+ struct DNSToken *dns_token; /* ongoing request */
+
VarCache vars; /* state of interesting server parameters */
SBuf sbuf; /* stream buffer, must be last */
struct DNSContext;
+struct DNSToken;
typedef void (*adns_callback_f)(void *arg, const struct sockaddr *sa, int salen);
void adns_reload(struct DNSContext *ctx);
void adns_free_context(struct DNSContext *ctx);
-void adns_resolve(struct DNSContext *ctx, const char *name, adns_callback_f cb_func, void *arg);
+struct DNSToken *adns_resolve(struct DNSContext *ctx, const char *name, adns_callback_f cb_func, void *arg);
+
+void adns_cancel(struct DNSContext *ctx, struct DNSToken *tk);
#endif
-struct UserCallback {
+struct DNSToken {
struct List node;
adns_callback_f cb_func;
void *cb_arg;
static void deliver_info(struct DNSRequest *req)
{
- struct UserCallback *ucb;
+ struct DNSToken *ucb;
struct List *el;
const struct addrinfo *ai = req->current;
char sabuf[128];
el = list_pop(&req->ucb_list);
if (!el)
return;
- ucb = container_of(el, struct UserCallback, node);
+ ucb = container_of(el, struct DNSToken, node);
/* launch callback */
log_noise("dns: deliver_info(%s) addr=%s", req->name,
static void req_free(struct AANode *node, void *arg)
{
- struct UserCallback *ucb;
+ struct DNSToken *ucb;
struct DNSRequest *req;
struct List *el;
req = container_of(node, struct DNSRequest, node);
while ((el = list_pop(&req->ucb_list)) != NULL) {
- ucb = container_of(el, struct UserCallback, node);
+ ucb = container_of(el, struct DNSToken, node);
free(ucb);
}
req_reset(req);
}
}
-void adns_resolve(struct DNSContext *ctx, const char *name, adns_callback_f cb_func, void *cb_arg)
+struct DNSToken *adns_resolve(struct DNSContext *ctx, const char *name, adns_callback_f cb_func, void *cb_arg)
{
int namelen = strlen(name);
struct DNSRequest *req;
- struct UserCallback *ucb;
+ struct DNSToken *ucb;
struct AANode *node;
/* setup actual lookup */
} else
deliver_info(req);
}
- return;
+ return ucb;
nomem:
log_warning("dns(%s): req failed, no mem", name);
cb_func(cb_arg, NULL, 0);
+ return NULL;
}
/* struct addrinfo -> deliver_info() */
deliver_info(req);
}
+void adns_cancel(struct DNSContext *ctx, struct DNSToken *tk)
+{
+ list_del(&tk->node);
+ memset(tk, 0, sizeof(*tk));
+ free(tk);
+}
+
notify = false;
}
+ if (server->dns_token) {
+ adns_cancel(adns, server->dns_token);
+ server->dns_token = NULL;
+ }
+
change_server_state(server, SV_JUSTFREE);
if (!sbuf_close(&server->sbuf))
log_noise("sbuf_close failed, retry later");
struct PgDatabase *db = server->pool->db;
struct sockaddr_in sa_in;
+ server->dns_token = NULL;
+
if (!sa) {
disconnect_server(server, true, "server dns lookup failed");
return;
sa = (struct sockaddr *)&sa_in;
sa_len = sizeof(sa_in);
} else {
+ struct DNSToken *tk;
slog_noise(server, "dns socket: %s", db->host);
/* launch dns lookup */
- adns_resolve(adns, db->host, dns_callback, server);
+ tk = adns_resolve(adns, db->host, dns_callback, server);
+ if (tk)
+ server->dns_token = tk;
return;
}