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.


Eric.

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"

Reply via email to