On Mon, Nov 28, 2016 at 08:50:14PM +0100, Eric Faurot wrote: > Hi, > > After the recent series of cleanups, it is now possible to make > struct io opaque: > > - move struct io definition in ioev.c > - replace io_init/io_clear with io_new/io_free > - allocate an iobuf for each new io internally > - use struct io pointer in the rest of the code > - remove remaining uses of iobuf_* > > The diff is mostly mechanical. >
ok gilles@ been running with this since saturday morning and tested both out and in path, as well as bounce, without a regression > Index: bounce.c > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/bounce.c,v > retrieving revision 1.76 > diff -u -p -r1.76 bounce.c > --- bounce.c 22 Nov 2016 07:28:42 -0000 1.76 > +++ bounce.c 28 Nov 2016 12:51:26 -0000 > @@ -80,8 +80,7 @@ struct bounce_session { > struct bounce_message *msg; > FILE *msgfp; > int state; > - struct iobuf iobuf; > - struct io io; > + struct io *io; > uint64_t boundary; > }; > > @@ -229,12 +228,11 @@ bounce_fd(int fd) > s = xcalloc(1, sizeof(*s), "bounce_fd"); > s->smtpname = xstrdup(msg->smtpname, "bounce_fd"); > s->state = BOUNCE_EHLO; > - iobuf_xinit(&s->iobuf, 0, 0, "bounce_run"); > - io_init(&s->io, &s->iobuf); > - io_set_callback(&s->io, bounce_io, s); > - io_set_fd(&s->io, fd); > - io_set_timeout(&s->io, 30000); > - io_set_read(&s->io); > + s->io = io_new(); > + io_set_callback(s->io, bounce_io, s); > + io_set_fd(s->io, fd); > + io_set_timeout(s->io, 30000); > + io_set_read(s->io); > s->boundary = generate_uid(); > > log_debug("debug: bounce: new session %p", s); > @@ -313,7 +311,7 @@ bounce_send(struct bounce_session *s, co > > log_trace(TRACE_BOUNCE, "bounce: %p: >>> %s", s, p); > > - io_xprintf(&s->io, "%s\n", p); > + io_xprintf(s->io, "%s\n", p); > > free(p); > } > @@ -452,7 +450,7 @@ bounce_next(struct bounce_session *s) > case BOUNCE_DATA_NOTICE: > /* Construct an appropriate notice. */ > > - io_xprintf(&s->io, > + io_xprintf(s->io, > "Subject: Delivery status notification: %s\n" > "From: Mailer Daemon <MAILER-DAEMON@%s>\n" > "To: %s\n" > @@ -470,7 +468,7 @@ bounce_next(struct bounce_session *s) > s->boundary, > s->smtpname); > > - io_xprintf(&s->io, > + io_xprintf(s->io, > "--%16" PRIu64 "/%s\n" > "Content-Description: Notification\n" > "Content-Type: text/plain; charset=us-ascii\n" > @@ -481,14 +479,14 @@ bounce_next(struct bounce_session *s) > > switch (s->msg->bounce.type) { > case B_ERROR: > - io_xprint(&s->io, notice_error); > + io_xprint(s->io, notice_error); > break; > case B_WARNING: > - io_xprintf(&s->io, notice_warning, > + io_xprintf(s->io, notice_warning, > bounce_duration(s->msg->bounce.delay)); > break; > case B_DSN: > - io_xprint(&s->io, s->msg->bounce.mta_without_dsn ? > + io_xprint(s->io, s->msg->bounce.mta_without_dsn ? > notice_relay : notice_success); > break; > default: > @@ -496,32 +494,32 @@ bounce_next(struct bounce_session *s) > } > > TAILQ_FOREACH(evp, &s->msg->envelopes, entry) { > - io_xprint(&s->io, evp->report); > + io_xprint(s->io, evp->report); > } > - io_xprint(&s->io, "\n"); > + io_xprint(s->io, "\n"); > > if (s->msg->bounce.type == B_WARNING) > - io_xprintf(&s->io, notice_warning2, > + io_xprintf(s->io, notice_warning2, > bounce_duration(s->msg->bounce.expire)); > > - io_xprintf(&s->io, > + io_xprintf(s->io, > " Below is a copy of the original message:\n" > "\n"); > > - io_xprintf(&s->io, > + io_xprintf(s->io, > "--%16" PRIu64 "/%s\n" > "Content-Description: Delivery Report\n" > "Content-Type: message/delivery-status\n" > "\n", > s->boundary, s->smtpname); > > - io_xprintf(&s->io, > + io_xprintf(s->io, > "Reporting-MTA: dns; %s\n" > "\n", > s->smtpname); > > TAILQ_FOREACH(evp, &s->msg->envelopes, entry) { > - io_xprintf(&s->io, > + io_xprintf(s->io, > "Final-Recipient: rfc822; %s@%s\n" > "Action: %s\n" > "Status: %s\n" > @@ -533,21 +531,21 @@ bounce_next(struct bounce_session *s) > } > > log_trace(TRACE_BOUNCE, "bounce: %p: >>> [... %zu bytes ...]", > - s, io_queued(&s->io)); > + s, io_queued(s->io)); > > s->state = BOUNCE_DATA_MESSAGE; > break; > > case BOUNCE_DATA_MESSAGE: > - io_xprintf(&s->io, > + io_xprintf(s->io, > "--%16" PRIu64 "/%s\n" > "Content-Description: Message headers\n" > "Content-Type: text/rfc822-headers\n" > "\n", > s->boundary, s->smtpname); > > - n = io_queued(&s->io); > - while (io_queued(&s->io) < BOUNCE_HIWAT) { > + n = io_queued(s->io); > + while (io_queued(s->io) < BOUNCE_HIWAT) { > if ((len = getline(&line, &sz, s->msgfp)) == -1) > break; > if (len == 1 && line[0] == '\n' && /* end of headers */ > @@ -556,7 +554,7 @@ bounce_next(struct bounce_session *s) > free(line); > fclose(s->msgfp); > s->msgfp = NULL; > - io_xprintf(&s->io, > + io_xprintf(s->io, > "\n--%16" PRIu64 "/%s--\n", s->boundary, > s->smtpname); > bounce_send(s, "."); > @@ -564,7 +562,7 @@ bounce_next(struct bounce_session *s) > return (0); > } > line[len - 1] = '\0'; > - io_xprintf(&s->io, "%s%s\n", > + io_xprintf(s->io, "%s%s\n", > (len == 2 && line[0] == '.') ? "." : "", line); > } > free(line); > @@ -578,11 +576,11 @@ bounce_next(struct bounce_session *s) > return (-1); > } > > - io_xprintf(&s->io, > + io_xprintf(s->io, > "\n--%16" PRIu64 "/%s--\n", s->boundary, s->smtpname); > > log_trace(TRACE_BOUNCE, "bounce: %p: >>> [... %zu bytes ...]", > - s, io_queued(&s->io) - n); > + s, io_queued(s->io) - n); > > if (feof(s->msgfp)) { > fclose(s->msgfp); > @@ -695,8 +693,7 @@ bounce_free(struct bounce_session *s) > { > log_debug("debug: bounce: %p: deleting session", s); > > - iobuf_clear(&s->iobuf); > - io_clear(&s->io); > + io_free(s->io); > > free(s->smtpname); > free(s); > @@ -721,8 +718,8 @@ bounce_io(struct io *io, int evt, void * > switch (evt) { > case IO_DATAIN: > nextline: > - line = io_getline(&s->io, &len); > - if (line == NULL && io_datalen(&s->io) >= LINE_MAX) { > + line = io_getline(s->io, &len); > + if (line == NULL && io_datalen(s->io) >= LINE_MAX) { > bounce_status(s, "Input too long"); > bounce_free(s); > return; > @@ -767,7 +764,7 @@ bounce_io(struct io *io, int evt, void * > bounce_free(s); > return; > } > - if (io_queued(&s->io) == 0) > + if (io_queued(s->io) == 0) > io_set_read(io); > break; > > Index: filter.c > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/filter.c,v > retrieving revision 1.23 > diff -u -p -r1.23 filter.c > --- filter.c 22 Nov 2016 07:28:42 -0000 1.23 > +++ filter.c 28 Nov 2016 12:51:27 -0000 > @@ -70,8 +70,7 @@ struct filter_session { > struct filter *fcurr; > > int error; > - struct io iev; > - struct iobuf ibuf; > + struct io *iev; > size_t idatalen; > FILE *ofile; > > @@ -295,8 +294,8 @@ filter_event(uint64_t id, int event) > filter_post_event(id, event, TAILQ_FIRST(s->filters), NULL); > > if (event == EVENT_DISCONNECT) { > - io_clear(&s->iev); > - iobuf_clear(&s->ibuf); > + if (s->iev) > + io_free(s->iev); > if (s->ofile) > fclose(s->ofile); > free(s); > @@ -315,7 +314,6 @@ filter_connect(uint64_t id, const struct > if (filter == NULL) > filter = "<no-filter>"; > s->filters = dict_xget(&chains, filter); > - io_init(&s->iev, NULL); > tree_xset(&sessions, s->id, s); > > filter_event(id, EVENT_CONNECT); > @@ -670,11 +668,10 @@ filter_tx(struct filter_session *s, int > io_set_nonblocking(sp[0]); > io_set_nonblocking(sp[1]); > > - iobuf_init(&s->ibuf, 0, 0); > - io_init(&s->iev, &s->ibuf); > - io_set_callback(&s->iev, filter_tx_io, s); > - io_set_fd(&s->iev, sp[0]); > - io_set_read(&s->iev); > + s->iev = io_new(); > + io_set_callback(s->iev, filter_tx_io, s); > + io_set_fd(s->iev, sp[0]); > + io_set_read(s->iev); > > return (sp[1]); > } > @@ -691,8 +688,8 @@ filter_tx_io(struct io *io, int evt, voi > > switch (evt) { > case IO_DATAIN: > - data = io_data(&s->iev); > - len = io_datalen(&s->iev); > + data = io_data(s->iev); > + len = io_datalen(s->iev); > > log_trace(TRACE_FILTERS, > "filter: filter_tx_io: datain (%zu) for req %016"PRIx64"", > @@ -705,7 +702,7 @@ filter_tx_io(struct io *io, int evt, voi > break; > } > s->idatalen += n; > - io_drop(&s->iev, n); > + io_drop(s->iev, n); > return; > > case IO_DISCONNECTED: > @@ -721,8 +718,8 @@ filter_tx_io(struct io *io, int evt, voi > break; > } > > - io_clear(&s->iev); > - iobuf_clear(&s->ibuf); > + io_free(s->iev); > + s->iev = NULL; > fclose(s->ofile); > s->ofile = NULL; > > Index: ioev.c > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/ioev.c,v > retrieving revision 1.37 > diff -u -p -r1.37 ioev.c > --- ioev.c 25 Nov 2016 16:17:41 -0000 1.37 > +++ ioev.c 28 Nov 2016 12:51:27 -0000 > @@ -21,6 +21,7 @@ > > #include <err.h> > #include <errno.h> > +#include <event.h> > #include <fcntl.h> > #include <inttypes.h> > #include <stdlib.h> > @@ -46,6 +47,20 @@ enum { > IO_STATE_MAX, > }; > > +struct io { > + int sock; > + void *arg; > + void (*cb)(struct io*, int, void *); > + struct iobuf *iobuf; > + size_t lowat; > + int timeout; > + int flags; > + int state; > + struct event ev; > + void *ssl; > + const char *error; /* only valid immediately on callback */ > +}; > + > const char* io_strflags(int); > const char* io_evstr(short); > > @@ -223,20 +238,36 @@ _io_init() > _io_debug = getenv("IO_DEBUG") != NULL; > } > > -void > -io_init(struct io *io, struct iobuf *iobuf) > +struct io * > +io_new(void) > { > + struct io *io; > + > _io_init(); > > - memset(io, 0, sizeof *io); > + if ((io = calloc(1, sizeof(*io))) == NULL) > + return NULL; > > io->sock = -1; > io->timeout = -1; > - io->iobuf = iobuf; > + io->iobuf = calloc(1, sizeof(*io->iobuf)); > + > + if (io->iobuf == NULL) { > + free(io); > + return NULL; > + } > + > + if (iobuf_init(io->iobuf, 0, 0) == -1) { > + free(io->iobuf); > + free(io); > + return NULL; > + } > + > + return io; > } > > void > -io_clear(struct io *io) > +io_free(struct io *io) > { > io_debug("io_clear(%p)\n", io); > > @@ -257,6 +288,10 @@ io_clear(struct io *io) > close(io->sock); > io->sock = -1; > } > + > + iobuf_clear(io->iobuf); > + free(io->iobuf); > + free(io); > } > > void > Index: ioev.h > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/ioev.h,v > retrieving revision 1.14 > diff -u -p -r1.14 ioev.h > --- ioev.h 24 Nov 2016 21:25:21 -0000 1.14 > +++ ioev.h 28 Nov 2016 12:51:27 -0000 > @@ -15,8 +15,6 @@ > * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > */ > > -#include <event.h> > - > enum { > IO_CONNECTED = 0, /* connection successful */ > IO_TLSREADY, /* TLS started successfully */ > @@ -36,26 +34,13 @@ enum { > #define IO_RESET 0x10 /* internal */ > #define IO_HELD 0x20 /* internal */ > > -struct iobuf; > -struct io { > - int sock; > - void *arg; > - void (*cb)(struct io*, int, void *); > - struct iobuf *iobuf; > - size_t lowat; > - int timeout; > - int flags; > - int state; > - struct event ev; > - void *ssl; > - const char *error; /* only valid immediately on callback */ > -}; > +struct io; > > void io_set_nonblocking(int); > void io_set_nolinger(int); > > -void io_init(struct io*, struct iobuf*); > -void io_clear(struct io*); > +struct io *io_new(void); > +void io_free(struct io *); > void io_set_read(struct io *); > void io_set_write(struct io *); > void io_set_fd(struct io *, int); > Index: mda.c > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/mda.c,v > retrieving revision 1.124 > diff -u -p -r1.124 mda.c > --- mda.c 24 Nov 2016 12:58:27 -0000 1.124 > +++ mda.c 28 Nov 2016 12:51:27 -0000 > @@ -79,8 +79,7 @@ struct mda_session { > uint64_t id; > struct mda_user *user; > struct mda_envelope *evp; > - struct io io; > - struct iobuf iobuf; > + struct io *io; > FILE *datafp; > }; > > @@ -253,10 +252,10 @@ mda_imsg(struct mproc *p, struct imsg *i > if (e->method == A_MDA || e->method == A_FILENAME) { > time(&now); > if (e->sender[0]) > - n = io_printf(&s->io, "From %s %s", > + n = io_printf(s->io, "From %s %s", > e->sender, ctime(&now)); > else > - n = io_printf(&s->io, > + n = io_printf(s->io, > "From MAILER-DAEMON@%s %s", > env->sc_hostname, ctime(&now)); > } > @@ -267,13 +266,13 @@ mda_imsg(struct mproc *p, struct imsg *i > * XXX: remove existing Return-Path, > * if any > */ > - n = io_printf(&s->io, > + n = io_printf(s->io, > "Return-Path: %s\n" > "Delivered-To: %s\n", > e->sender, > e->rcpt ? e->rcpt : e->dest); > else > - n = io_printf(&s->io, > + n = io_printf(s->io, > "Delivered-To: %s\n", > e->rcpt ? e->rcpt : e->dest); > } > @@ -431,8 +430,8 @@ mda_imsg(struct mproc *p, struct imsg *i > imsg->fd, s->id, s->evp->id); > > io_set_nonblocking(imsg->fd); > - io_set_fd(&s->io, imsg->fd); > - io_set_write(&s->io); > + io_set_fd(s->io, imsg->fd); > + io_set_write(s->io); > return; > > case IMSG_MDA_DONE: > @@ -456,7 +455,7 @@ mda_imsg(struct mproc *p, struct imsg *i > */ > error = NULL; > if (strcmp(parent_error, "exited okay") == 0) { > - if (s->datafp || io_queued(&s->io)) > + if (s->datafp || (s->io && io_queued(s->io))) > error = "mda exited prematurely"; > } else > error = out[0] ? out : parent_error; > @@ -514,14 +513,15 @@ mda_io(struct io *io, int evt, void *arg > log_debug("debug: mda: all data sent for session" > " %016"PRIx64 " evpid %016"PRIx64, > s->id, s->evp->id); > - io_clear(io); > + io_free(io); > + s->io = NULL; > return; > } > > - while (io_queued(&s->io) < MDA_HIWAT) { > + while (io_queued(s->io) < MDA_HIWAT) { > if ((len = getline(&ln, &sz, s->datafp)) == -1) > break; > - if (io_write(&s->io, ln, len) == -1) { > + if (io_write(s->io, ln, len) == -1) { > m_create(p_parent, IMSG_MDA_KILL, > 0, 0, -1); > m_add_id(p_parent, s->id); > @@ -552,7 +552,7 @@ mda_io(struct io *io, int evt, void *arg > s->id, s->evp->id); > fclose(s->datafp); > s->datafp = NULL; > - if (io_queued(&s->io) == 0) > + if (io_queued(s->io) == 0) > goto done; > } > return; > @@ -747,8 +747,8 @@ mda_done(struct mda_session *s) > > if (s->datafp) > fclose(s->datafp); > - io_clear(&s->io); > - iobuf_clear(&s->iobuf); > + if (s->io) > + io_free(s->io); > > free(s); > > @@ -954,10 +954,8 @@ mda_session(struct mda_user * u) > s = xcalloc(1, sizeof *s, "mda_session"); > s->id = generate_uid(); > s->user = u; > - if (iobuf_init(&s->iobuf, 0, 0) == -1) > - fatal("mda_session"); > - io_init(&s->io, &s->iobuf); > - io_set_callback(&s->io, mda_io, s); > + s->io = io_new(); > + io_set_callback(s->io, mda_io, s); > > tree_xset(&sessions, s->id, s); > > Index: mta_session.c > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/mta_session.c,v > retrieving revision 1.94 > diff -u -p -r1.94 mta_session.c > --- mta_session.c 25 Nov 2016 11:43:55 -0000 1.94 > +++ mta_session.c 28 Nov 2016 12:51:28 -0000 > @@ -115,8 +115,7 @@ struct mta_session { > int ready; > > struct event ev; > - struct iobuf iobuf; > - struct io io; > + struct io *io; > int ext; > > size_t msgtried; > @@ -196,7 +195,6 @@ mta_session(struct mta_relay *relay, str > s->id = generate_uid(); > s->relay = relay; > s->route = route; > - io_init(&s->io, NULL); > > if (relay->flags & RELAY_SSL && relay->flags & RELAY_AUTH) > s->flags |= MTA_USE_AUTH; > @@ -329,7 +327,7 @@ mta_session_imsg(struct mproc *p, struct > ssl = ssl_mta_init(NULL, NULL, 0, > env->sc_tls_ciphers); > if (ssl == NULL) > fatal("mta: ssl_mta_init"); > - io_start_tls(&s->io, ssl); > + io_start_tls(s->io, ssl); > return; > } > } > @@ -341,7 +339,7 @@ mta_session_imsg(struct mproc *p, struct > resp_ca_cert->cert, resp_ca_cert->cert_len, > env->sc_tls_ciphers); > if (ssl == NULL) > fatal("mta: ssl_mta_init"); > - io_start_tls(&s->io, ssl); > + io_start_tls(s->io, ssl); > > explicit_bzero(resp_ca_cert->cert, resp_ca_cert->cert_len); > free(resp_ca_cert->cert); > @@ -364,7 +362,7 @@ mta_session_imsg(struct mproc *p, struct > } > > mta_tls_verified(s); > - io_resume(&s->io, IO_PAUSE_IN); > + io_resume(s->io, IO_PAUSE_IN); > return; > > case IMSG_MTA_LOOKUP_HELO: > @@ -427,8 +425,8 @@ mta_free(struct mta_session *s) > runq_cancel(hangon, NULL, s); > } > > - io_clear(&s->io); > - iobuf_clear(&s->iobuf); > + if (s->io) > + io_free(s->io); > > if (s->task) > fatalx("current task should have been deleted already"); > @@ -497,8 +495,10 @@ mta_connect(struct mta_session *s) > s->helo = xstrdup(env->sc_hostname, "mta_connect"); > } > > - io_clear(&s->io); > - iobuf_clear(&s->iobuf); > + if (s->io) { > + io_free(s->io); > + s->io = NULL; > + } > > s->use_smtps = s->use_starttls = s->use_smtp_tls = 0; > > @@ -556,20 +556,19 @@ mta_connect(struct mta_session *s) > portno, s->route->dst->ptrname); > > mta_enter_state(s, MTA_INIT); > - iobuf_xinit(&s->iobuf, 0, 0, "mta_connect"); > - io_init(&s->io, &s->iobuf); > - io_set_callback(&s->io, mta_io, s); > - io_set_timeout(&s->io, 300000); > - if (io_connect(&s->io, sa, s->route->src->sa) == -1) { > + s->io = io_new(); > + io_set_callback(s->io, mta_io, s); > + io_set_timeout(s->io, 300000); > + if (io_connect(s->io, sa, s->route->src->sa) == -1) { > /* > * This error is most likely a "no route", > * so there is no need to try again. > */ > - log_debug("debug: mta: io_connect failed: %s", > io_error(&s->io)); > + log_debug("debug: mta: io_connect failed: %s", io_error(s->io)); > if (errno == EADDRNOTAVAIL) > - mta_source_error(s->relay, s->route, io_error(&s->io)); > + mta_source_error(s->relay, s->route, io_error(s->io)); > else > - mta_error(s, "Connection failed: %s", io_error(&s->io)); > + mta_error(s, "Connection failed: %s", io_error(s->io)); > mta_free(s); > } > } > @@ -842,7 +841,7 @@ mta_enter_state(struct mta_session *s, i > > case MTA_LMTP_EOM: > /* LMTP reports status of each delivery, so enable read */ > - io_set_read(&s->io); > + io_set_read(s->io); > break; > > case MTA_RSET: > @@ -1033,7 +1032,7 @@ mta_response(struct mta_session *s, char > */ > sa_len = sizeof(ss); > sa = (struct sockaddr *)&ss; > - if (getsockname(io_fileno(&s->io), sa, &sa_len) < 0) > + if (getsockname(io_fileno(s->io), sa, &sa_len) < 0) > mta_delivery_log(e, NULL, buf, delivery, line); > else > mta_delivery_log(e, sa_to_text(sa), > @@ -1161,11 +1160,11 @@ mta_io(struct io *io, int evt, void *arg > > case IO_TLSREADY: > log_info("%016"PRIx64" mta event=starttls ciphers=%s", > - s->id, ssl_to_text(io_ssl(&s->io))); > + s->id, ssl_to_text(io_ssl(s->io))); > s->flags |= MTA_TLS; > > if (mta_verify_certificate(s)) { > - io_pause(&s->io, IO_PAUSE_IN); > + io_pause(s->io, IO_PAUSE_IN); > break; > } > > @@ -1174,9 +1173,9 @@ mta_io(struct io *io, int evt, void *arg > > case IO_DATAIN: > nextline: > - line = io_getline(&s->io, &len); > + line = io_getline(s->io, &len); > if (line == NULL) { > - if (io_datalen(&s->io) >= LINE_MAX) { > + if (io_datalen(s->io) >= LINE_MAX) { > mta_error(s, "Input too long"); > mta_free(s); > } > @@ -1259,7 +1258,7 @@ mta_io(struct io *io, int evt, void *arg > return; > } > > - if (io_datalen(&s->io)) { > + if (io_datalen(s->io)) { > log_debug("debug: mta: remaining data in input buffer"); > mta_error(s, "Remote host sent too much data"); > if (s->flags & MTA_WAIT) > @@ -1278,7 +1277,7 @@ mta_io(struct io *io, int evt, void *arg > } > } > > - if (io_queued(&s->io) == 0) > + if (io_queued(s->io) == 0) > io_set_read(io); > break; > > @@ -1359,7 +1358,7 @@ mta_send(struct mta_session *s, char *fm > > log_trace(TRACE_MTA, "mta: %p: >>> %s", s, p); > > - io_xprintf(&s->io, "%s\r\n", p); > + io_xprintf(s->io, "%s\r\n", p); > > free(p); > } > @@ -1374,14 +1373,14 @@ mta_queue_data(struct mta_session *s) > size_t sz = 0, q; > ssize_t len; > > - q = io_queued(&s->io); > + q = io_queued(s->io); > > - while (io_queued(&s->io) < MTA_HIWAT) { > + while (io_queued(s->io) < MTA_HIWAT) { > if ((len = getline(&ln, &sz, s->datafp)) == -1) > break; > if (ln[len - 1] == '\n') > ln[len - 1] = '\0'; > - io_xprintf(&s->io, "%s%s\r\n", *ln == '.' ? "." : "", ln); > + io_xprintf(s->io, "%s%s\r\n", *ln == '.' ? "." : "", ln); > } > > free(ln); > @@ -1396,7 +1395,7 @@ mta_queue_data(struct mta_session *s) > s->datafp = NULL; > } > > - return (io_queued(&s->io) - q); > + return (io_queued(s->io) - q); > } > > static void > @@ -1433,7 +1432,7 @@ mta_flush_task(struct mta_session *s, in > */ > sa = (struct sockaddr *)&ss; > sa_len = sizeof(ss); > - if (getsockname(io_fileno(&s->io), sa, &sa_len) < 0) > + if (getsockname(io_fileno(s->io), sa, &sa_len) < 0) > mta_delivery_log(e, NULL, relay, delivery, error); > else > mta_delivery_log(e, sa_to_text(sa), > @@ -1560,10 +1559,10 @@ mta_verify_certificate(struct mta_sessio > >= sizeof req_ca_vrfy.name) > return 0; > > - x = SSL_get_peer_certificate(io_ssl(&s->io)); > + x = SSL_get_peer_certificate(io_ssl(s->io)); > if (x == NULL) > return 0; > - xchain = SSL_get_peer_cert_chain(io_ssl(&s->io)); > + xchain = SSL_get_peer_cert_chain(io_ssl(s->io)); > > /* > * Client provided a certificate and possibly a certificate chain. > @@ -1657,7 +1656,7 @@ mta_tls_verified(struct mta_session *s) > { > X509 *x; > > - x = SSL_get_peer_certificate(io_ssl(&s->io)); > + x = SSL_get_peer_certificate(io_ssl(s->io)); > if (x) { > log_info("smtp-out: Server certificate verification %s " > "on session %016"PRIx64, > @@ -1668,7 +1667,7 @@ mta_tls_verified(struct mta_session *s) > > if (s->use_smtps) { > mta_enter_state(s, MTA_BANNER); > - io_set_read(&s->io); > + io_set_read(s->io); > } > else > mta_enter_state(s, MTA_EHLO); > Index: smtp_session.c > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/smtp_session.c,v > retrieving revision 1.300 > diff -u -p -r1.300 smtp_session.c > --- smtp_session.c 24 Nov 2016 21:25:21 -0000 1.300 > +++ smtp_session.c 28 Nov 2016 12:51:29 -0000 > @@ -116,8 +116,7 @@ struct smtp_tx { > > size_t datain; > size_t odatalen; > - struct iobuf obuf; > - struct io oev; > + struct io *oev; > int hdrdone; > int rcvcount; > int dataeom; > @@ -131,8 +130,7 @@ struct smtp_tx { > > struct smtp_session { > uint64_t id; > - struct iobuf iobuf; > - struct io io; > + struct io *io; > struct listener *listener; > void *ssl_ctx; > struct sockaddr_storage ss; > @@ -642,19 +640,14 @@ smtp_session(struct listener *listener, > if ((s = calloc(1, sizeof(*s))) == NULL) > return (-1); > > - if (iobuf_init(&s->iobuf, LINE_MAX, LINE_MAX) == -1) { > - free(s); > - return (-1); > - } > - > s->id = generate_uid(); > s->listener = listener; > memmove(&s->ss, ss, sizeof(*ss)); > - io_init(&s->io, &s->iobuf); > - io_set_callback(&s->io, smtp_io, s); > - io_set_fd(&s->io, sock); > - io_set_timeout(&s->io, SMTPD_SESSION_TIMEOUT * 1000); > - io_set_write(&s->io); > + s->io = io_new(); > + io_set_callback(s->io, smtp_io, s); > + io_set_fd(s->io, sock); > + io_set_timeout(s->io, SMTPD_SESSION_TIMEOUT * 1000); > + io_set_write(s->io); > > s->state = STATE_NEW; > > @@ -966,8 +959,8 @@ smtp_session_imsg(struct mproc *p, struc > sizeof *resp_ca_cert, "smtp:ca_cert"); > ssl_ctx = dict_get(env->sc_ssl_dict, resp_ca_cert->name); > ssl = ssl_smtp_init(ssl_ctx, s->listener->flags & F_TLS_VERIFY); > - io_set_read(&s->io); > - io_start_tls(&s->io, ssl); > + io_set_read(s->io); > + io_start_tls(s->io, ssl); > > explicit_bzero(resp_ca_cert->cert, resp_ca_cert->cert_len); > free(resp_ca_cert->cert); > @@ -988,7 +981,7 @@ smtp_session_imsg(struct mproc *p, struc > return; > } > smtp_tls_verified(s); > - io_resume(&s->io, IO_PAUSE_IN); > + io_resume(s->io, IO_PAUSE_IN); > return; > } > > @@ -1002,7 +995,7 @@ smtp_tls_verified(struct smtp_session *s > { > X509 *x; > > - x = SSL_get_peer_certificate(io_ssl(&s->io)); > + x = SSL_get_peer_certificate(io_ssl(s->io)); > if (x) { > log_info("%016"PRIx64" smtp " > "event=client-cert-check address=%s host=%s result=\"%s\"", > @@ -1013,7 +1006,7 @@ smtp_tls_verified(struct smtp_session *s > > if (s->listener->flags & F_SMTPS) { > stat_increment("smtp.smtps", 1); > - io_set_write(&s->io); > + io_set_write(s->io); > smtp_send_banner(s); > } > else { > @@ -1185,20 +1178,19 @@ smtp_filter_fd(uint64_t id, int fd) > return; > } > > - iobuf_init(&s->tx->obuf, 0, 0); > io_set_nonblocking(fd); > - io_init(&s->tx->oev, &s->tx->obuf); > - io_set_callback(&s->tx->oev, smtp_data_io, s); > - io_set_fd(&s->tx->oev, fd); > + s->tx->oev = io_new(); > + io_set_callback(s->tx->oev, smtp_data_io, s); > + io_set_fd(s->tx->oev, fd); > > - io_print(&s->tx->oev, "Received: "); > + io_print(s->tx->oev, "Received: "); > if (!(s->listener->flags & F_MASK_SOURCE)) { > - io_printf(&s->tx->oev, "from %s (%s [%s])", > + io_printf(s->tx->oev, "from %s (%s [%s])", > s->helo, > s->hostname, > ss_to_text(&s->ss)); > } > - io_printf(&s->tx->oev, "\n\tby %s (%s) with %sSMTP%s%s id %08x", > + io_printf(s->tx->oev, "\n\tby %s (%s) with %sSMTP%s%s id %08x", > s->smtpname, > SMTPD_NAME, > s->flags & SF_EHLO ? "E" : "", > @@ -1207,33 +1199,33 @@ smtp_filter_fd(uint64_t id, int fd) > s->tx->msgid); > > if (s->flags & SF_SECURE) { > - x = SSL_get_peer_certificate(io_ssl(&s->io)); > - io_printf(&s->tx->oev, " (%s:%s:%d:%s)", > - SSL_get_version(io_ssl(&s->io)), > - SSL_get_cipher_name(io_ssl(&s->io)), > - SSL_get_cipher_bits(io_ssl(&s->io), NULL), > + x = SSL_get_peer_certificate(io_ssl(s->io)); > + io_printf(s->tx->oev, " (%s:%s:%d:%s)", > + SSL_get_version(io_ssl(s->io)), > + SSL_get_cipher_name(io_ssl(s->io)), > + SSL_get_cipher_bits(io_ssl(s->io), NULL), > (s->flags & SF_VERIFIED) ? "YES" : (x ? "FAIL" : "NO")); > if (x) > X509_free(x); > > if (s->listener->flags & F_RECEIVEDAUTH) { > - io_printf(&s->tx->oev, " auth=%s", s->username[0] ? > "yes" : "no"); > + io_printf(s->tx->oev, " auth=%s", s->username[0] ? > "yes" : "no"); > if (s->username[0]) > - io_printf(&s->tx->oev, " user=%s", s->username); > + io_printf(s->tx->oev, " user=%s", s->username); > } > } > > if (s->tx->rcptcount == 1) { > - io_printf(&s->tx->oev, "\n\tfor <%s@%s>", > + io_printf(s->tx->oev, "\n\tfor <%s@%s>", > s->tx->evp.rcpt.user, > s->tx->evp.rcpt.domain); > } > > - io_printf(&s->tx->oev, ";\n\t%s\n", time_to_text(time(NULL))); > + io_printf(s->tx->oev, ";\n\t%s\n", time_to_text(time(NULL))); > > - s->tx->odatalen = io_queued(&s->tx->oev); > + s->tx->odatalen = io_queued(s->tx->oev); > > - io_set_write(&s->tx->oev); > + io_set_write(s->tx->oev); > > smtp_enter_state(s, STATE_BODY); > smtp_reply(s, "354 Enter mail, end with \".\"" > @@ -1257,13 +1249,13 @@ smtp_io(struct io *io, int evt, void *ar > > case IO_TLSREADY: > log_info("%016"PRIx64" smtp event=starttls address=%s host=%s > ciphers=\"%s\"", > - s->id, ss_to_text(&s->ss), s->hostname, > ssl_to_text(io_ssl(&s->io))); > + s->id, ss_to_text(&s->ss), s->hostname, > ssl_to_text(io_ssl(s->io))); > > s->flags |= SF_SECURE; > s->helo[0] = '\0'; > > if (smtp_verify_certificate(s)) { > - io_pause(&s->io, IO_PAUSE_IN); > + io_pause(s->io, IO_PAUSE_IN); > break; > } > > @@ -1280,8 +1272,8 @@ smtp_io(struct io *io, int evt, void *ar > > case IO_DATAIN: > nextline: > - line = io_getline(&s->io, &len); > - if ((line == NULL && io_datalen(&s->io) >= LINE_MAX) || > + line = io_getline(s->io, &len); > + if ((line == NULL && io_datalen(s->io) >= LINE_MAX) || > (line && len >= LINE_MAX)) { > s->flags |= SF_BADINPUT; > smtp_reply(s, "500 %s: Line too long", > @@ -1302,7 +1294,7 @@ smtp_io(struct io *io, int evt, void *ar > } > > /* Pipelining not supported */ > - if (io_datalen(&s->io)) { > + if (io_datalen(s->io)) { > s->flags |= SF_BADINPUT; > smtp_reply(s, "500 %s %s: Pipelining not supported", > esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND), > @@ -1321,7 +1313,7 @@ smtp_io(struct io *io, int evt, void *ar > io_set_write(io); > > s->tx->dataeom = 1; > - if (io_queued(&s->tx->oev) == 0) > + if (io_queued(s->tx->oev) == 0) > smtp_data_io_done(s); > return; > } > @@ -1400,7 +1392,6 @@ smtp_tx(struct smtp_session *s) > return 0; > > TAILQ_INIT(&tx->rcpts); > - io_init(&tx->oev, NULL); > > s->tx = tx; > tx->session = s; > @@ -1454,6 +1445,9 @@ smtp_tx_free(struct smtp_tx *tx) > free(rcpt); > } > > + if (tx->oev) > + io_free(tx->oev); > + > tx->session->tx = NULL; > > free(tx); > @@ -1472,21 +1466,21 @@ smtp_data_io(struct io *io, int evt, voi > case IO_DISCONNECTED: > case IO_ERROR: > log_debug("debug: smtp: %p: io error on mfa", s); > - io_clear(&s->tx->oev); > - iobuf_clear(&s->tx->obuf); > + io_free(s->tx->oev); > + s->tx->oev = NULL; > s->tx->msgflags |= MF_ERROR_IO; > - if (io_paused(&s->io, IO_PAUSE_IN)) { > + if (io_paused(s->io, IO_PAUSE_IN)) { > log_debug("debug: smtp: %p: resuming session after mfa > error", s); > - io_resume(&s->io, IO_PAUSE_IN); > + io_resume(s->io, IO_PAUSE_IN); > } > break; > > case IO_LOWAT: > - if (s->tx->dataeom && io_queued(&s->tx->oev) == 0) { > + if (s->tx->dataeom && io_queued(s->tx->oev) == 0) { > smtp_data_io_done(s); > - } else if (io_paused(&s->io, IO_PAUSE_IN)) { > + } else if (io_paused(s->io, IO_PAUSE_IN)) { > log_debug("debug: smtp: %p: filter congestion over: > resuming session", s); > - io_resume(&s->io, IO_PAUSE_IN); > + io_resume(s->io, IO_PAUSE_IN); > } > break; > > @@ -1499,8 +1493,11 @@ static void > smtp_data_io_done(struct smtp_session *s) > { > log_debug("debug: smtp: %p: data io done (%zu bytes)", s, > s->tx->odatalen); > - io_clear(&s->tx->oev); > - iobuf_clear(&s->tx->obuf); > + > + if (s->tx->oev) { > + io_free(s->tx->oev); > + s->tx->oev = NULL; > + } > > if (s->tx->msgflags & MF_ERROR) { > > @@ -2075,7 +2072,7 @@ smtp_lookup_servername(struct smtp_sessi > if (s->listener->hostnametable[0]) { > sa_len = sizeof(ss); > sa = (struct sockaddr *)&ss; > - if (getsockname(io_fileno(&s->io), sa, &sa_len) == -1) { > + if (getsockname(io_fileno(s->io), sa, &sa_len) == -1) { > log_warn("warn: getsockname()"); > } > else { > @@ -2103,7 +2100,7 @@ smtp_connected(struct smtp_session *s) > s->id, ss_to_text(&s->ss), s->hostname); > > sl = sizeof(ss); > - if (getsockname(io_fileno(&s->io), (struct sockaddr*)&ss, &sl) == -1) { > + if (getsockname(io_fileno(s->io), (struct sockaddr*)&ss, &sl) == -1) { > smtp_free(s, strerror(errno)); > return; > } > @@ -2162,7 +2159,7 @@ smtp_message_printf(struct smtp_session > return -1; > > va_start(ap, fmt); > - len = io_vprintf(&s->tx->oev, fmt, ap); > + len = io_vprintf(s->tx->oev, fmt, ap); > va_end(ap); > > if (len < 0) { > @@ -2192,7 +2189,7 @@ smtp_reply(struct smtp_session *s, char > > log_trace(TRACE_SMTP, "smtp: %p: >>> %s", s, buf); > > - io_xprintf(&s->io, "%s\r\n", buf); > + io_xprintf(s->io, "%s\r\n", buf); > > switch (buf[0]) { > case '5': > @@ -2239,11 +2236,8 @@ smtp_free(struct smtp_session *s, const > tree_pop(&wait_filter_data, s->id); > > if (s->tx) { > - if (s->tx->msgid) { > + if (s->tx->msgid) > smtp_queue_rollback(s); > - io_clear(&s->tx->oev); > - iobuf_clear(&s->tx->obuf); > - } > smtp_filter_tx_rollback(s); > smtp_tx_free(s->tx); > } > @@ -2256,8 +2250,7 @@ smtp_free(struct smtp_session *s, const > if (s->flags & SF_SECURE && s->listener->flags & F_STARTTLS) > stat_decrement("smtp.tls", 1); > > - io_clear(&s->io); > - iobuf_clear(&s->iobuf); > + io_free(s->io); > free(s); > > smtp_collect(); > @@ -2346,10 +2339,10 @@ smtp_verify_certificate(struct smtp_sess > >= sizeof req_ca_vrfy.name) > return 0; > > - x = SSL_get_peer_certificate(io_ssl(&s->io)); > + x = SSL_get_peer_certificate(io_ssl(s->io)); > if (x == NULL) > return 0; > - xchain = SSL_get_peer_cert_chain(io_ssl(&s->io)); > + xchain = SSL_get_peer_cert_chain(io_ssl(s->io)); > > /* > * Client provided a certificate and possibly a certificate chain. > @@ -2635,9 +2628,9 @@ smtp_filter_dataline(struct smtp_session > return; > } > > - if (io_queued(&s->tx->oev) > DATA_HIWAT && !io_paused(&s->io, > IO_PAUSE_IN)) { > + if (io_queued(s->tx->oev) > DATA_HIWAT && !io_paused(s->io, > IO_PAUSE_IN)) { > log_debug("debug: smtp: %p: filter congestion: pausing > session", s); > - io_pause(&s->io, IO_PAUSE_IN); > + io_pause(s->io, IO_PAUSE_IN); > } > } > > Index: smtpd.h > =================================================================== > RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v > retrieving revision 1.525 > diff -u -p -r1.525 smtpd.h > --- smtpd.h 25 Nov 2016 09:21:21 -0000 1.525 > +++ smtpd.h 28 Nov 2016 12:51:29 -0000 > @@ -22,6 +22,8 @@ > #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) > #endif > > +#include <event.h> > + > #include "smtpd-defines.h" > #include "smtpd-api.h" > #include "ioev.h" > -- Gilles Chehade https://www.poolp.org @poolpOrg