void control_imsg(struct imsgev *iev, struct imsg *imsg) { struct ctl_conn *c; log_imsg(PROC_CONTROL, iev->proc, imsg); if (iev->proc == PROC_SMTP) { switch (imsg->hdr.type) { case IMSG_SMTP_ENQUEUE: c = control_connbyfd(imsg->hdr.peerid); if (c == NULL) return; imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, imsg->fd, NULL, 0); return; } } errx(1, "control_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type)); }
void runner_imsg(struct imsgev *iev, struct imsg *imsg) { struct envelope *e, bounce; struct scheduler_info si; log_imsg(PROC_RUNNER, iev->proc, imsg); switch (imsg->hdr.type) { case IMSG_QUEUE_COMMIT_MESSAGE: e = imsg->data; runner_message_to_scheduler(evpid_to_msgid(e->id)); runner_reset_events(); return; case IMSG_QUEUE_DELIVERY_OK: stat_decrement(STATS_RUNNER); e = imsg->data; log_debug("queue_delivery_ok: %016"PRIx64, e->id); scheduler->remove(e->id); queue_envelope_delete(e); return; case IMSG_QUEUE_DELIVERY_TEMPFAIL: stat_decrement(STATS_RUNNER); e = imsg->data; e->retry++; queue_envelope_update(e); log_debug("queue_delivery_tempfail: %016"PRIx64, e->id); scheduler_info(&si, e); scheduler->insert(&si); runner_reset_events(); return; case IMSG_QUEUE_DELIVERY_PERMFAIL: stat_decrement(STATS_RUNNER); e = imsg->data; if (e->type != D_BOUNCE && e->sender.user[0] != '\0') { bounce_record_message(e, &bounce); log_debug("queue_delivery_permfail: %016"PRIx64, bounce.id); scheduler_info(&si, &bounce); scheduler->insert(&si); runner_reset_events(); } scheduler->remove(e->id); queue_envelope_delete(e); return; case IMSG_MDA_SESS_NEW: stat_decrement(STATS_MDA_SESSION); if (env->sc_maxconn - stat_get(STATS_MDA_SESSION, STAT_ACTIVE)) env->sc_flags &= ~SMTPD_MDA_BUSY; runner_reset_events(); return; case IMSG_BATCH_DONE: stat_decrement(STATS_MTA_SESSION); if (env->sc_maxconn - stat_get(STATS_MTA_SESSION, STAT_ACTIVE)) env->sc_flags &= ~SMTPD_MTA_BUSY; runner_reset_events(); return; case IMSG_SMTP_ENQUEUE: e = imsg->data; if (imsg->fd < 0 || !bounce_session(imsg->fd, e)) { queue_envelope_update(e); log_debug("smtp_enqueue: %016"PRIx64, e->id); scheduler_info(&si, e); scheduler->insert(&si); runner_reset_events(); return; } return; case IMSG_QUEUE_PAUSE_MDA: env->sc_flags |= SMTPD_MDA_PAUSED; return; case IMSG_QUEUE_RESUME_MDA: env->sc_flags &= ~SMTPD_MDA_PAUSED; runner_reset_events(); return; case IMSG_QUEUE_PAUSE_MTA: env->sc_flags |= SMTPD_MTA_PAUSED; return; case IMSG_QUEUE_RESUME_MTA: env->sc_flags &= ~SMTPD_MTA_PAUSED; runner_reset_events(); return; case IMSG_CTL_VERBOSE: log_verbose(*(int *)imsg->data); return; case IMSG_RUNNER_SCHEDULE: scheduler->force(*(u_int64_t *)imsg->data); runner_reset_events(); return; case IMSG_RUNNER_REMOVE: { runner_remove(*(u_int64_t *)imsg->data); runner_reset_events(); return; } } errx(1, "runner_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type)); }
static int rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding, unsigned int cmd) { int ret = 0; struct imsgbuf *ibuf; struct imsg imsg; int n, done = 0; const void *toptr; char *pkiname; size_t tlen; struct msg m; uint64_t id; if ((pkiname = RSA_get_ex_data(rsa, 0)) == NULL) return (0); /* * Send a synchronous imsg because we cannot defer the RSA * operation in OpenSSL's engine layer. */ m_create(p_ca, cmd, 0, 0, -1); rsae_reqid++; m_add_id(p_ca, rsae_reqid); m_add_string(p_ca, pkiname); m_add_data(p_ca, (const void *)from, (size_t)flen); m_add_size(p_ca, (size_t)RSA_size(rsa)); m_add_size(p_ca, (size_t)padding); m_flush(p_ca); ibuf = &p_ca->imsgbuf; while (!done) { if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) fatalx("imsg_read"); if (n == 0) fatalx("pipe closed"); while (!done) { if ((n = imsg_get(ibuf, &imsg)) == -1) fatalx("imsg_get error"); if (n == 0) break; log_imsg(PROC_PONY, PROC_CA, &imsg); switch (imsg.hdr.type) { case IMSG_CA_PRIVENC: case IMSG_CA_PRIVDEC: break; default: /* Another imsg is queued up in the buffer */ pony_imsg(p_ca, &imsg); imsg_free(&imsg); continue; } m_msg(&m, &imsg); m_get_id(&m, &id); if (id != rsae_reqid) fatalx("invalid response id"); m_get_int(&m, &ret); if (ret > 0) m_get_data(&m, &toptr, &tlen); m_end(&m); if (ret > 0) memcpy(to, toptr, tlen); done = 1; imsg_free(&imsg); } } mproc_event_add(p_ca); return (ret); }