Commit Diff


commit - 7f2e3fa483950c33c7d2f812626fb18052432832
commit + aeda4d4ea624e48cf756f264b48dcd924e736fc6
blob - 9a63d964ac11e9e9661de126e549ac39f0dceeaa
blob + c0a62bea425731e330f9f4cf6e15b25c1c1c0370
--- main.c
+++ main.c
@@ -1,21 +1,42 @@
+#include <sys/types.h>
 #include <sys/socket.h>
 
 #include <err.h>
 #include <errno.h>
+#include <event.h>
 #include <netdb.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <asr.h>
 
 #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 *, ...)