commit aeda4d4ea624e48cf756f264b48dcd924e736fc6 from: Martijn van Duren date: Thu Mar 28 16:55:52 2019 UTC Add async support for dns lookups, so we don't block other connections commit - 7f2e3fa483950c33c7d2f812626fb18052432832 commit + aeda4d4ea624e48cf756f264b48dcd924e736fc6 blob - 9a63d964ac11e9e9661de126e549ac39f0dceeaa blob + c0a62bea425731e330f9f4cf6e15b25c1c1c0370 --- main.c +++ main.c @@ -1,21 +1,42 @@ +#include #include #include #include +#include #include #include #include #include #include +#include #include "smtp_proc.h" +struct dnsbl_session; + +struct dnsbl_query { + struct asr_query *query; + struct event_asr *event; + int resolved; + int blacklist; + struct dnsbl_session *session; +}; + +struct dnsbl_session { + uint64_t reqid; + uint64_t token; + struct dnsbl_query *query; +}; + static char **blacklists = NULL; static size_t nblacklists = 0; void usage(void); -enum filter_decision dnsbl_connect(char *, int, time_t, char *, char *, - uint64_t, uint64_t, struct smtp_filter_connect *); +void dnsbl_connect(char *, int, time_t, char *, char *, uint64_t, uint64_t, + struct smtp_filter_connect *); +void dnsbl_resolve(struct asr_result *, void *); +void dnsbl_session_free(struct dnsbl_session *); int main(int argc, char *argv[]) @@ -57,16 +78,23 @@ main(int argc, char *argv[]) return 0; } -enum filter_decision +void dnsbl_connect(char *type, int version, time_t tm, char *direction, char *phase, uint64_t reqid, uint64_t token, struct smtp_filter_connect *params) { + struct dnsbl_session *session; char query[255]; - char reply[1500]; - struct hostent *hent; u_char *addr; int i, try; + if ((session = calloc(1, sizeof(*session))) == NULL) + err(1, NULL); + if ((session->query = calloc(nblacklists, sizeof(*(session->query)))) + == NULL) + err(1, NULL); + session->reqid = reqid; + session->token = token; + addr = (u_char *)&(params->addr); for (i = 0; i < nblacklists; i++) { if (params->af == AF_INET) { @@ -100,23 +128,52 @@ dnsbl_connect(char *type, int version, time_t tm, char } else errx(1, "Invalid address family received"); - if ((hent = gethostbyname(query)) == NULL) { - if (h_errno == HOST_NOT_FOUND) - break; - if (h_errno != TRY_AGAIN) { - smtp_filter_disconnect(reqid, token, - "Blacklist check failed"); - return FILTER_DISCONNECT; - } - } else { - smtp_filter_disconnect(reqid, token, - "Listed at %s", blacklists[i]); - return FILTER_DISCONNECT; - } + session->query[i].query = gethostbyname_async(query, NULL); + session->query[i].event = event_asr_run(session->query[i].query, + dnsbl_resolve, &(session->query[i])); + session->query[i].blacklist = i; + session->query[i].session = session; } - return FILTER_PROCEED; } +void +dnsbl_resolve(struct asr_result *result, void *arg) +{ + struct dnsbl_query *query = arg; + struct dnsbl_session *session = query->session; + int i, blacklist; + + query->resolved = 1; + query->event = NULL; + query->query = NULL; + if (result->ar_hostent != NULL) { + smtp_filter_disconnect(session->reqid, session->token, + "Host listed at %s", blacklists[query->blacklist]); + dnsbl_session_free(session); + return; + } + + for (i = 0; i < nblacklists; i++) { + if (!session->query[i].resolved) + return; + } + smtp_filter_proceed(session->reqid, session->token); + dnsbl_session_free(session); +} + +void +dnsbl_session_free(struct dnsbl_session *session) +{ + int i; + + for (i = 0; i < nblacklists; i++) { + if (!session->query[i].resolved) + event_asr_abort(session->query[i].event); + } + free(session->query); + free(session); +} + __dead void usage(void) { blob - 22c4b10fd084867d309b965b788550cb6613cfaa blob + 3f637237b5a2f04c6b9d9dd2ab692a7b2199402d --- smtp_proc.c +++ smtp_proc.c @@ -55,8 +55,8 @@ static int ready = 0; static int resolved = 1; int -smtp_register_filter_connect(enum filter_decision (*cb)(char *, int, time_t, - char *, char *, uint64_t, uint64_t, struct smtp_filter_connect *)) +smtp_register_filter_connect(void (*cb)(char *, int, time_t, char *, char *, + uint64_t, uint64_t, struct smtp_filter_connect *)) { return smtp_register("filter", "connect", "smtp-in", (smtp_cb) cb); } blob - 32f5edae76536f943271a670f009dbabaca1ed72 blob + 0d634c86bcf021e0031d0b73af37fa750387bc63 --- smtp_proc.h +++ smtp_proc.h @@ -16,7 +16,7 @@ enum filter_decision { FILTER_REWRITE }; -int smtp_register_filter_connect(enum filter_decision (*cb)(char *, int, time_t, +int smtp_register_filter_connect(void (*cb)(char *, int, time_t, char *, char *, uint64_t, uint64_t, struct smtp_filter_connect *)); void smtp_filter_proceed(uint64_t, uint64_t); void smtp_filter_reject(uint64_t, uint64_t, int, const char *, ...)