static int queue_ram_message_delete(uint32_t msgid) { struct qr_message *msg; struct qr_envelope *evp; uint64_t evpid; if ((msg = tree_pop(&messages, msgid)) == NULL) { log_warnx("warn: queue-ram: not found"); return (0); } while (tree_poproot(&messages, &evpid, (void**)&evp)) { stat_decrement("queue.ram.envelope.size", evp->len); free(evp->buf); free(evp); } stat_decrement("queue.ram.message.size", msg->len); free(msg->buf); free(msg); return (0); }
void mta_imsg(struct imsgev *iev, struct imsg *imsg) { struct mta_route *route; struct mta_batch2 *batch; struct mta_task *task; struct envelope *e; struct ssl *ssl; uint64_t id; if (iev->proc == PROC_QUEUE) { switch (imsg->hdr.type) { case IMSG_BATCH_CREATE: id = *(uint64_t*)(imsg->data); batch = xmalloc(sizeof *batch, "mta_batch"); batch->id = id; tree_init(&batch->tasks); tree_xset(&batches, batch->id, batch); log_trace(TRACE_MTA, "mta: batch:%016" PRIx64 " created", batch->id); return; case IMSG_BATCH_APPEND: e = xmemdup(imsg->data, sizeof *e, "mta:envelope"); route = mta_route_for(e); batch = tree_xget(&batches, e->batch_id); if ((task = tree_get(&batch->tasks, route->id)) == NULL) { log_trace(TRACE_MTA, "mta: new task for %s", mta_route_to_text(route)); task = xmalloc(sizeof *task, "mta_task"); TAILQ_INIT(&task->envelopes); task->route = route; tree_xset(&batch->tasks, route->id, task); task->msgid = evpid_to_msgid(e->id); task->sender = e->sender; route->refcount += 1; } /* Technically, we could handle that by adding a msg * level, but the batch sent by the scheduler should * be valid. */ if (task->msgid != evpid_to_msgid(e->id)) errx(1, "msgid mismatch in batch"); /* XXX honour route->maxrcpt */ TAILQ_INSERT_TAIL(&task->envelopes, e, entry); stat_increment("mta.envelope", 1); log_debug("mta: received evp:%016" PRIx64 " for <%s@%s>", e->id, e->dest.user, e->dest.domain); return; case IMSG_BATCH_CLOSE: id = *(uint64_t*)(imsg->data); batch = tree_xpop(&batches, id); log_trace(TRACE_MTA, "mta: batch:%016" PRIx64 " closed", batch->id); /* for all tasks, queue them on there route */ while (tree_poproot(&batch->tasks, &id, (void**)&task)) { if (id != task->route->id) errx(1, "route id mismatch!"); task->route->refcount -= 1; task->route->ntask += 1; TAILQ_INSERT_TAIL(&task->route->tasks, task, entry); stat_increment("mta.task", 1); mta_route_drain(task->route); } free(batch); return; case IMSG_QUEUE_MESSAGE_FD: mta_session_imsg(iev, imsg); return; } } if (iev->proc == PROC_LKA) { switch (imsg->hdr.type) { case IMSG_LKA_SECRET: case IMSG_DNS_HOST: case IMSG_DNS_HOST_END: case IMSG_DNS_PTR: mta_session_imsg(iev, imsg); return; } } if (iev->proc == PROC_PARENT) { switch (imsg->hdr.type) { case IMSG_CONF_START: if (env->sc_flags & SMTPD_CONFIGURING) return; env->sc_flags |= SMTPD_CONFIGURING; env->sc_ssl = xcalloc(1, sizeof *env->sc_ssl, "mta:sc_ssl"); return; case IMSG_CONF_SSL: if (!(env->sc_flags & SMTPD_CONFIGURING)) return; ssl = xmemdup(imsg->data, sizeof *ssl, "mta:ssl"); ssl->ssl_cert = xstrdup((char*)imsg->data + sizeof *ssl, "mta:ssl_cert"); ssl->ssl_key = xstrdup((char*)imsg->data + sizeof *ssl + ssl->ssl_cert_len, "mta:ssl_key"); SPLAY_INSERT(ssltree, env->sc_ssl, ssl); return; case IMSG_CONF_END: if (!(env->sc_flags & SMTPD_CONFIGURING)) return; env->sc_flags &= ~SMTPD_CONFIGURING; return; case IMSG_CTL_VERBOSE: log_verbose(*(int *)imsg->data); return; } } errx(1, "mta_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type)); }