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

Reply via email to