diff options
author | 2013-12-14 20:32:41 +0100 | |
---|---|---|
committer | 2013-12-14 20:32:41 +0100 | |
commit | 7fc42b3c47578617e1129a592bb51c9dd6104170 (patch) | |
tree | 42a95f055ddfa6c7029401280c426770462ffaa9 | |
parent | Merge branch 'master' into portable (diff) | |
parent | woops, API change not propagated to mda.c (diff) | |
download | OpenSMTPD-7fc42b3c47578617e1129a592bb51c9dd6104170.tar.xz OpenSMTPD-7fc42b3c47578617e1129a592bb51c9dd6104170.zip |
Merge branch 'master' into portable
-rw-r--r-- | smtpd/limit.c | 5 | ||||
-rw-r--r-- | smtpd/mda.c | 12 | ||||
-rw-r--r-- | smtpd/mta.c | 7 | ||||
-rw-r--r-- | smtpd/mta_session.c | 65 | ||||
-rw-r--r-- | smtpd/queue.c | 6 | ||||
-rw-r--r-- | smtpd/scheduler.c | 6 | ||||
-rw-r--r-- | smtpd/scheduler_backend.c | 5 | ||||
-rw-r--r-- | smtpd/smtpd-api.h | 1 | ||||
-rw-r--r-- | smtpd/smtpd.h | 9 |
9 files changed, 39 insertions, 77 deletions
diff --git a/smtpd/limit.c b/smtpd/limit.c index 49200325..5461e699 100644 --- a/smtpd/limit.c +++ b/smtpd/limit.c @@ -58,6 +58,8 @@ limit_mta_set_defaults(struct mta_limits *limits) limits->sessdelay_transaction = 1; limits->sessdelay_keepalive = 10; + limits->max_failures_per_session = 25; + limits->family = AF_UNSPEC; limits->task_hiwat = 50; @@ -104,6 +106,9 @@ limit_mta_set(struct mta_limits *limits, const char *key, int64_t value) else if (!strcmp(key, "session-keepalive")) limits->sessdelay_keepalive = value; + else if (!strcmp(key, "max-failures-per-session")) + limits->max_failures_per_session = value; + else if (!strcmp(key, "task-hiwat")) limits->task_hiwat = value; else if (!strcmp(key, "task-lowat")) diff --git a/smtpd/mda.c b/smtpd/mda.c index 111f82a2..3dc4425e 100644 --- a/smtpd/mda.c +++ b/smtpd/mda.c @@ -209,7 +209,7 @@ mda_imsg(struct mproc *p, struct imsg *imsg) if (imsg->fd == -1) { log_debug("debug: mda: cannot get message fd"); - queue_tempfail(e->id, 0, "Cannot get message fd"); + queue_tempfail(e->id, "Cannot get message fd"); mda_log(e, "TempFail", "Cannot get message fd"); mda_done(s); return; @@ -222,7 +222,7 @@ mda_imsg(struct mproc *p, struct imsg *imsg) if ((s->datafp = fdopen(imsg->fd, "r")) == NULL) { log_warn("warn: mda: fdopen"); close(imsg->fd); - queue_tempfail(e->id, 0, "fdopen failed"); + queue_tempfail(e->id, "fdopen failed"); mda_log(e, "TempFail", "fdopen failed"); mda_done(s); return; @@ -250,7 +250,7 @@ mda_imsg(struct mproc *p, struct imsg *imsg) if (n == -1) { log_warn("warn: mda: " "fail to write delivery info"); - queue_tempfail(e->id, 0, "Out of memory"); + queue_tempfail(e->id, "Out of memory"); mda_log(e, "TempFail", "Out of memory"); mda_done(s); return; @@ -341,7 +341,7 @@ mda_imsg(struct mproc *p, struct imsg *imsg) e = s->evp; if (imsg->fd == -1) { log_warn("warn: mda: fail to retrieve mda fd"); - queue_tempfail(e->id, 0, "Cannot get mda fd"); + queue_tempfail(e->id, "Cannot get mda fd"); mda_log(e, "TempFail", "Cannot get mda fd"); mda_done(s); return; @@ -384,7 +384,7 @@ mda_imsg(struct mproc *p, struct imsg *imsg) /* update queue entry */ if (error) { - queue_tempfail(e->id, 0, error); + queue_tempfail(e->id, error); snprintf(buf, sizeof buf, "Error (%s)", error); mda_log(e, "TempFail", buf); } @@ -679,7 +679,7 @@ mda_fail(struct mda_user *user, int permfail, const char *error) } else { mda_log(e, "TempFail", error); - queue_tempfail(e->id, 0, error); + queue_tempfail(e->id, error); } mda_envelope_free(e); } diff --git a/smtpd/mta.c b/smtpd/mta.c index 0b0e02ef..80f124b0 100644 --- a/smtpd/mta.c +++ b/smtpd/mta.c @@ -716,7 +716,7 @@ mta_delivery_flush_event(int fd, short event, void *arg) if (e->delivery == IMSG_DELIVERY_OK) queue_ok(e->id); else if (e->delivery == IMSG_DELIVERY_TEMPFAIL) - queue_tempfail(e->id, e->penalty, e->status); + queue_tempfail(e->id, e->status); else if (e->delivery == IMSG_DELIVERY_PERMFAIL) queue_permfail(e->id, e->status); else if (e->delivery == IMSG_DELIVERY_LOOP) @@ -763,11 +763,10 @@ mta_delivery_log(struct mta_envelope *e, const char *source, const char *relay, } void -mta_delivery_notify(struct mta_envelope *e, uint32_t penalty) +mta_delivery_notify(struct mta_envelope *e) { struct timeval tv; - e->penalty = penalty; tree_xset(&flush_evp, e->id, e); if (tree_count(&flush_evp) == 1) { tv.tv_sec = 0; @@ -1359,7 +1358,7 @@ mta_flush(struct mta_relay *relay, int fail, const char *error) } mta_delivery_log(e, NULL, relay->domain->name, fail, error); - mta_delivery_notify(e, 0); + mta_delivery_notify(e); n++; } diff --git a/smtpd/mta_session.c b/smtpd/mta_session.c index ab791193..53f5c2c4 100644 --- a/smtpd/mta_session.c +++ b/smtpd/mta_session.c @@ -128,9 +128,7 @@ struct mta_session { struct mta_envelope *currevp; FILE *datafp; -#define MAX_FAILED_ENVELOPES 15 - struct mta_envelope *failed[MAX_FAILED_ENVELOPES]; - int failedcount; + size_t failures; }; static void mta_session_init(void); @@ -151,7 +149,6 @@ static int mta_check_loop(FILE *); static void mta_start_tls(struct mta_session *); static int mta_verify_certificate(struct mta_session *); static struct mta_session *mta_tree_pop(struct tree *, uint64_t); -static void mta_flush_failedqueue(struct mta_session *); void mta_hoststat_update(const char *, const char *); void mta_hoststat_reschedule(const char *); void mta_hoststat_cache(const char *, uint64_t); @@ -434,8 +431,6 @@ mta_free(struct mta_session *s) runq_cancel(hangon, NULL, s); } - mta_flush_failedqueue(s); - io_clear(&s->io); iobuf_clear(&s->iobuf); @@ -962,7 +957,7 @@ mta_response(struct mta_session *s, char *line) s->currevp = TAILQ_NEXT(s->currevp, entry); if (line[0] == '2') { - mta_flush_failedqueue(s); + s->failures = 0; /* * this host is up, reschedule envelopes that * were cached for reschedule. @@ -975,6 +970,7 @@ mta_response(struct mta_session *s, char *line) delivery = IMSG_DELIVERY_PERMFAIL; else delivery = IMSG_DELIVERY_TEMPFAIL; + s->failures++; /* remove failed envelope from task list */ TAILQ_REMOVE(&s->task->envelopes, e, entry); @@ -998,24 +994,17 @@ mta_response(struct mta_session *s, char *line) mta_delivery_log(e, sa_to_text(sa), buf, delivery, line); - /* push failed envelope to the session fail queue */ - s->failed[s->failedcount] = e; - s->failedcount++; - - /* - * if session fail queue is full: - * - flush failed queue (failure w/ penalty) - * - flush remaining tasks with TempFail - * - mark route down - */ - if (s->failedcount == MAX_FAILED_ENVELOPES) { - mta_flush_failedqueue(s); - mta_flush_task(s, IMSG_DELIVERY_TEMPFAIL, - "Host temporarily disabled", 0, 1); - mta_route_down(s->relay, s->route); - mta_enter_state(s, MTA_QUIT); - break; - } + if (domain) + mta_hoststat_update(domain + 1, e->status); + mta_delivery_notify(e); + + if (s->relay->limits->max_failures_per_session && + s->failures == s->relay->limits->max_failures_per_session) { + mta_flush_task(s, IMSG_DELIVERY_TEMPFAIL, + "Too many consecutive errors, closing connection", 0, 1); + mta_enter_state(s, MTA_QUIT); + break; + } /* * if no more envelopes, flush failed queue @@ -1035,7 +1024,6 @@ mta_response(struct mta_session *s, char *line) break; case MTA_DATA: - mta_flush_failedqueue(s); if (line[0] == '2' || line[0] == '3') { mta_enter_state(s, MTA_BODY); break; @@ -1080,7 +1068,6 @@ mta_response(struct mta_session *s, char *line) break; case MTA_RSET: - mta_flush_failedqueue(s); s->rcptcount = 0; if (s->relay->limits->sessdelay_transaction) { log_debug("debug: mta: waiting for %llds after reset", @@ -1361,7 +1348,7 @@ mta_flush_task(struct mta_session *s, int delivery, const char *error, size_t co mta_delivery_log(e, sa_to_text(sa), relay, delivery, error); - mta_delivery_notify(e, 0); + mta_delivery_notify(e); domain = strchr(e->dest, '@'); if (domain) { @@ -1388,28 +1375,6 @@ mta_flush_task(struct mta_session *s, int delivery, const char *error, size_t co } static void -mta_flush_failedqueue(struct mta_session *s) -{ - int i; - struct mta_envelope *e; - const char *domain; - uint32_t penalty; - - penalty = s->failedcount == MAX_FAILED_ENVELOPES ? 1 : 0; - for (i = 0; i < s->failedcount; ++i) { - e = s->failed[i]; - - domain = strchr(e->dest, '@'); - if (domain) - mta_hoststat_update(domain + 1, e->status); - - mta_delivery_notify(e, penalty); - } - - s->failedcount = 0; -} - -static void mta_error(struct mta_session *s, const char *fmt, ...) { va_list ap; diff --git a/smtpd/queue.c b/smtpd/queue.c index 5beb4b59..8051aa32 100644 --- a/smtpd/queue.c +++ b/smtpd/queue.c @@ -71,7 +71,6 @@ queue_imsg(struct mproc *p, struct imsg *imsg) const char *reason; uint64_t reqid, evpid, holdq; uint32_t msgid; - uint32_t penalty; time_t nexttry; int fd, ret, v, flags; @@ -350,7 +349,6 @@ queue_imsg(struct mproc *p, struct imsg *imsg) case IMSG_DELIVERY_TEMPFAIL: m_msg(&m, imsg); m_get_evpid(&m, &evpid); - m_get_u32(&m, &penalty); m_get_string(&m, &reason); m_end(&m); if (queue_envelope_load(evpid, &evp) == 0) { @@ -367,7 +365,6 @@ queue_imsg(struct mproc *p, struct imsg *imsg) log_warnx("warn: could not update envelope %016"PRIx64, evpid); m_create(p_scheduler, IMSG_DELIVERY_TEMPFAIL, 0, 0, -1); m_add_envelope(p_scheduler, &evp); - m_add_u32(p_scheduler, penalty); m_close(p_scheduler); return; @@ -666,11 +663,10 @@ queue_ok(uint64_t evpid) } void -queue_tempfail(uint64_t evpid, uint32_t penalty, const char *reason) +queue_tempfail(uint64_t evpid, const char *reason) { m_create(p_queue, IMSG_DELIVERY_TEMPFAIL, 0, 0, -1); m_add_evpid(p_queue, evpid); - m_add_u32(p_queue, penalty); m_add_string(p_queue, reason); m_close(p_queue); } diff --git a/smtpd/scheduler.c b/smtpd/scheduler.c index 24ab51a8..49f73b35 100644 --- a/smtpd/scheduler.c +++ b/smtpd/scheduler.c @@ -78,7 +78,6 @@ scheduler_imsg(struct mproc *p, struct imsg *imsg) uint64_t evpid, id, holdq; uint32_t msgid; uint32_t inflight; - uint32_t penalty; size_t n, i; time_t timestamp; int v, r, type; @@ -91,7 +90,7 @@ scheduler_imsg(struct mproc *p, struct imsg *imsg) m_end(&m); log_trace(TRACE_SCHEDULER, "scheduler: inserting evp:%016" PRIx64, evp.id); - scheduler_info(&si, &evp, 0); + scheduler_info(&si, &evp); stat_increment("scheduler.envelope.incoming", 1); backend->insert(&si); return; @@ -156,11 +155,10 @@ scheduler_imsg(struct mproc *p, struct imsg *imsg) case IMSG_DELIVERY_TEMPFAIL: m_msg(&m, imsg); m_get_envelope(&m, &evp); - m_get_u32(&m, &penalty); m_end(&m); log_trace(TRACE_SCHEDULER, "scheduler: updating evp:%016" PRIx64, evp.id); - scheduler_info(&si, &evp, penalty); + scheduler_info(&si, &evp); backend->update(&si); ninflight -= 1; stat_increment("scheduler.delivery.tempfail", 1); diff --git a/smtpd/scheduler_backend.c b/smtpd/scheduler_backend.c index e836954f..1be11b51 100644 --- a/smtpd/scheduler_backend.c +++ b/smtpd/scheduler_backend.c @@ -53,7 +53,7 @@ scheduler_backend_lookup(const char *name) } void -scheduler_info(struct scheduler_info *sched, struct envelope *evp, uint32_t penalty) +scheduler_info(struct scheduler_info *sched, struct envelope *evp) { sched->evpid = evp->id; sched->type = evp->type; @@ -63,7 +63,6 @@ scheduler_info(struct scheduler_info *sched, struct envelope *evp, uint32_t pena sched->lasttry = evp->lasttry; sched->lastbounce = evp->lastbounce; sched->nexttry = 0; - sched->penalty = penalty; } time_t @@ -77,7 +76,7 @@ scheduler_compute_schedule(struct scheduler_info *sched) else delay = 10; - retry = sched->retry + sched->penalty; + retry = sched->retry; delay = ((delay * retry) * retry) / 2; return (sched->creation + delay); diff --git a/smtpd/smtpd-api.h b/smtpd/smtpd-api.h index 803b60b0..dae36a95 100644 --- a/smtpd/smtpd-api.h +++ b/smtpd/smtpd-api.h @@ -164,7 +164,6 @@ struct scheduler_info { time_t lasttry; time_t lastbounce; time_t nexttry; - uint8_t penalty; }; #define SCHED_NONE 0x00 diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h index 8f084f63..ae057ef9 100644 --- a/smtpd/smtpd.h +++ b/smtpd/smtpd.h @@ -722,6 +722,8 @@ struct mta_limits { time_t sessdelay_transaction; time_t sessdelay_keepalive; + size_t max_failures_per_session; + int family; int task_hiwat; @@ -783,7 +785,6 @@ struct mta_envelope { char *rcpt; struct mta_task *task; int delivery; - int penalty; char status[SMTPD_MAXLINESIZE]; }; @@ -1211,7 +1212,7 @@ void mta_route_down(struct mta_relay *, struct mta_route *); void mta_route_collect(struct mta_relay *, struct mta_route *); void mta_source_error(struct mta_relay *, struct mta_route *, const char *); void mta_delivery_log(struct mta_envelope *, const char *, const char *, int, const char *); -void mta_delivery_notify(struct mta_envelope *, uint32_t); +void mta_delivery_notify(struct mta_envelope *); struct mta_task *mta_route_next_task(struct mta_relay *, struct mta_route *); const char *mta_host_to_text(struct mta_host *); const char *mta_relay_to_text(struct mta_relay *); @@ -1229,7 +1230,7 @@ int cmdline_symset(char *); /* queue.c */ pid_t queue(void); void queue_ok(uint64_t); -void queue_tempfail(uint64_t, uint32_t, const char *); +void queue_tempfail(uint64_t, const char *); void queue_permfail(uint64_t, const char *); void queue_loop(uint64_t); void queue_flow_control(void); @@ -1262,7 +1263,7 @@ pid_t scheduler(void); /* scheduler_bakend.c */ struct scheduler_backend *scheduler_backend_lookup(const char *); -void scheduler_info(struct scheduler_info *, struct envelope *, uint32_t); +void scheduler_info(struct scheduler_info *, struct envelope *); time_t scheduler_compute_schedule(struct scheduler_info *); |