diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2010-09-08 13:32:14 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2010-09-08 13:32:14 +0000 |
commit | a5a022bf8743a142c6ffa311255c3c8ccc09782e (patch) | |
tree | 37d46a18222569d1d0b990b07c6877375888bd03 /usr.sbin | |
parent | a9359ecea89eecce1ea6fcd922998bcc8cf875a9 (diff) |
we do dns resolutions in a separate process because we don't have an async
resolver. if we run scarce on resources and we cannot fork a separate dns
process or we cannot socketpair() tell the caller that we have a temporary
failure rather than issueing a fatal(). message will stay in queue and be
rescheduled later ...
bug reported and bugfix tested by Sacha El Masry <lists@devilray.eu>
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/smtpd/dns.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/usr.sbin/smtpd/dns.c b/usr.sbin/smtpd/dns.c index 677f40ff9e8..323a83b056e 100644 --- a/usr.sbin/smtpd/dns.c +++ b/usr.sbin/smtpd/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.22 2010/06/29 03:47:24 deraadt Exp $ */ +/* $OpenBSD: dns.c,v 1.23 2010/09/08 13:32:13 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -118,7 +118,13 @@ dns_async(struct smtpd *env, struct imsgev *asker, int type, struct dns *query) rd->asker = asker; query->env = env; - fd = dns(); + /* dns() will fail if we are scarce on resources or processes */ + if ((fd = dns()) == -1) { + query->error = EAI_AGAIN; + imsg_compose_event(rd->asker, type, 0, 0, -1, query, sizeof(*query)); + return; + } + imsg_init(&rd->iev.ibuf, fd); rd->iev.handler = parent_dispatch_dns; rd->iev.events = EV_READ; @@ -197,14 +203,21 @@ dns(void) pid_t pid; struct imsgev *iev; - if (socketpair(AF_UNIX, SOCK_STREAM, AF_UNSPEC, fd) == -1) - fatal("socketpair"); + if (socketpair(AF_UNIX, SOCK_STREAM, AF_UNSPEC, fd) == -1) { + log_warn("socketpair"); + return -1; + } session_socket_blockmode(fd[0], BM_NONBLOCK); session_socket_blockmode(fd[1], BM_NONBLOCK); - if ((pid = fork()) == -1) - fatal("dns: fork"); + if ((pid = fork()) == -1) { + log_warn("fork"); + close(fd[0]); + close(fd[1]); + return -1; + } + if (pid > 0) { close(fd[1]); return (fd[0]); |