commit c75461cdd1e2359cc1e270732b5c49cadb278ccf from: Martijn van Duren date: Fri Mar 29 08:41:43 2019 UTC Implement an on disconnect. If the client disconnects before we resolve the blacklist, there's no need to await everything commit - 47628d21f7a30b2113052998b86c24d42631eec8 commit + c75461cdd1e2359cc1e270732b5c49cadb278ccf blob - 3f8c0c98f6f645d86408130fc996f5915263d38e blob + 660a13669fd91ed4caf6f7b39c21d586ca4aa7c6 --- main.c +++ main.c @@ -1,3 +1,4 @@ +#include #include #include @@ -28,17 +29,23 @@ struct dnsbl_session { uint64_t reqid; uint64_t token; struct dnsbl_query *query; + RB_ENTRY(dnsbl_session) entry; }; +RB_HEAD(dnsbl_sessions, dnsbl_session) dnsbl_sessions = RB_INITIALIZER(NULL); +RB_PROTOTYPE(dnsbl_sessions, dnsbl_session, entry, dnsbl_session_cmp); + static char **blacklists = NULL; static size_t nblacklists = 0; void usage(void); void dnsbl_connect(char *, int, struct timespec *, char *, char *, uint64_t, uint64_t, char *, struct inx_addr *); +void dnsbl_disconnect(char *, int, struct timespec *, char *, char *, uint64_t); void dnsbl_resolve(struct asr_result *, void *); void dnsbl_timeout(int, short, void *); void dnsbl_session_free(struct dnsbl_session *); +int dnsbl_session_cmp(struct dnsbl_session *, struct dnsbl_session *); int main(int argc, char *argv[]) @@ -75,6 +82,7 @@ main(int argc, char *argv[]) errx(1, "No blacklist specified"); smtp_register_filter_connect(dnsbl_connect); + smtp_in_register_report_disconnect(dnsbl_disconnect); smtp_run(); return 0; @@ -98,6 +106,7 @@ dnsbl_connect(char *type, int version, struct timespec err(1, NULL); session->reqid = reqid; session->token = token; + RB_INSERT(dnsbl_sessions, &dnsbl_sessions, session); if (xaddr->af == AF_INET) addr = (u_char *)&(xaddr->addr); @@ -190,10 +199,22 @@ dnsbl_timeout(int fd, short event, void *arg) } void +dnsbl_disconnect(char *type, int version, struct timespec *tm, char *direction, + char *phase, uint64_t reqid) +{ + struct dnsbl_session *session, search; + + search.reqid = reqid; + if ((session = RB_FIND(dnsbl_sessions, &dnsbl_sessions, &search)) != NULL) + dnsbl_session_free(session); +} + +void dnsbl_session_free(struct dnsbl_session *session) { int i; + RB_REMOVE(dnsbl_sessions, &dnsbl_sessions, session); for (i = 0; i < nblacklists; i++) { if (!session->query[i].resolved) { event_asr_abort(session->query[i].event); @@ -204,6 +225,12 @@ dnsbl_session_free(struct dnsbl_session *session) free(session); } +int +dnsbl_session_cmp(struct dnsbl_session *s1, struct dnsbl_session *s2) +{ + return (s1->reqid < s2->reqid ? -1 : s1->reqid > s2->reqid); +} + __dead void usage(void) { @@ -211,3 +238,5 @@ usage(void) getprogname()); exit(1); } + +RB_GENERATE(dnsbl_sessions, dnsbl_session, entry, dnsbl_session_cmp);