Hi all thank you for including the feature. I'm testing with my usecase and will report back if strange things happen.
Thanks again and best regards -Tobias On 04.09.2016, at 12:28, Bob Beck <b...@obtuse.com> wrote: > > On Sun, Sep 04, 2016 at 05:26:24AM -0500, Brent Cook wrote: >> On Sun, Sep 04, 2016 at 05:57:54AM -0400, Ted Unangst wrote: >>> Brent Cook wrote: >>>> @@ -246,14 +252,18 @@ An already existing socket can be upgrad >>>> .Fn tls_connect_socket . >>>> Alternatively, a secure connection can be established over a pair of >>>> existing >>>> file descriptors by calling >>>> -.Fn tls_connect_fds . >>>> +.Fn tls_connect_fds . Using >>>> +.Fn tls_connect_cbs , read and write callbacks can be specified to handle >>>> the >>>> +actual data transfer. >>> >>> I think we need just a wee bit more documentation. payload is not the >>> clearest >>> name. It sounds like connection data. I think cookie? Or cbarg? Is it >>> necessary to pass the tls context to the callback? I think that's unusual. >>> >>> read callback should be more like: >>> >>> ssize_t (*read_cb)(void *buf, size_t buflen, void *cbarg); >> >> Agreed, I was also a bit unclear on payload at first (though it grew on >> me over time, so I didn't change it). Here's an update with the >> parameter renamed and better documented. >> >> ok? > > Yeah. I'm good with this > > IMO get it in so we can tweak it in tree. > > ok beck@ > > and don't forget to bump all the minors of all the things > > >> >> Index: Makefile >> =================================================================== >> RCS file: /cvs/src/lib/libtls/Makefile,v >> retrieving revision 1.23 >> diff -u -p -u -p -r1.23 Makefile >> --- Makefile 30 Mar 2016 06:38:43 -0000 1.23 >> +++ Makefile 4 Sep 2016 10:23:42 -0000 >> @@ -13,6 +13,7 @@ LDADD+= -L${BSDOBJDIR}/lib/libssl/ssl -l >> HDRS= tls.h >> >> SRCS= tls.c \ >> + tls_bio_cb.c \ >> tls_client.c \ >> tls_config.c \ >> tls_conninfo.c \ >> Index: shlib_version >> =================================================================== >> RCS file: /cvs/src/lib/libtls/shlib_version,v >> retrieving revision 1.20 >> diff -u -p -u -p -r1.20 shlib_version >> --- shlib_version 31 Aug 2016 23:05:30 -0000 1.20 >> +++ shlib_version 4 Sep 2016 10:23:42 -0000 >> @@ -1,2 +1,2 @@ >> major=11 >> -minor=3 >> +minor=4 >> Index: tls.c >> =================================================================== >> RCS file: /cvs/src/lib/libtls/tls.c,v >> retrieving revision 1.48 >> diff -u -p -u -p -r1.48 tls.c >> --- tls.c 22 Aug 2016 17:12:35 -0000 1.48 >> +++ tls.c 4 Sep 2016 10:23:42 -0000 >> @@ -424,6 +424,10 @@ tls_reset(struct tls *ctx) >> tls_sni_ctx_free(sni); >> } >> ctx->sni_ctx = NULL; >> + >> + ctx->read_cb = NULL; >> + ctx->write_cb = NULL; >> + ctx->cb_arg = NULL; >> } >> >> int >> Index: tls.h >> =================================================================== >> RCS file: /cvs/src/lib/libtls/tls.h,v >> retrieving revision 1.35 >> diff -u -p -u -p -r1.35 tls.h >> --- tls.h 22 Aug 2016 14:58:26 -0000 1.35 >> +++ tls.h 4 Sep 2016 10:23:42 -0000 >> @@ -44,6 +44,11 @@ extern "C" { >> struct tls; >> struct tls_config; >> >> +typedef ssize_t (*tls_read_cb)(void *_ctx, void *_buf, size_t _buflen, >> + void *_cb_arg); >> +typedef ssize_t (*tls_write_cb)(void *_ctx, const void *_buf, >> + size_t _buflen, void *_cb_arg); >> + >> int tls_init(void); >> >> const char *tls_config_error(struct tls_config *_config); >> @@ -102,12 +107,16 @@ void tls_free(struct tls *_ctx); >> int tls_accept_fds(struct tls *_ctx, struct tls **_cctx, int _fd_read, >> int _fd_write); >> int tls_accept_socket(struct tls *_ctx, struct tls **_cctx, int _socket); >> +int tls_accept_cbs(struct tls *_ctx, struct tls **_cctx, >> + tls_read_cb _read_cb, tls_write_cb _write_cb, void *_cb_arg); >> int tls_connect(struct tls *_ctx, const char *_host, const char *_port); >> int tls_connect_fds(struct tls *_ctx, int _fd_read, int _fd_write, >> const char *_servername); >> int tls_connect_servername(struct tls *_ctx, const char *_host, >> const char *_port, const char *_servername); >> int tls_connect_socket(struct tls *_ctx, int _s, const char *_servername); >> +int tls_connect_cbs(struct tls *_ctx, tls_read_cb _read_cb, >> + tls_write_cb _write_cb, void *_cb_arg, const char *_servername); >> int tls_handshake(struct tls *_ctx); >> ssize_t tls_read(struct tls *_ctx, void *_buf, size_t _buflen); >> ssize_t tls_write(struct tls *_ctx, const void *_buf, size_t _buflen); >> Index: tls_bio_cb.c >> =================================================================== >> RCS file: tls_bio_cb.c >> diff -N tls_bio_cb.c >> --- /dev/null 1 Jan 1970 00:00:00 -0000 >> +++ tls_bio_cb.c 4 Sep 2016 10:23:42 -0000 >> @@ -0,0 +1,224 @@ >> +/* $ID$ */ >> +/* >> + * Copyright (c) 2016 Tobias Pape <tob...@netshed.de> >> + * >> + * Permission to use, copy, modify, and distribute this software for any >> + * purpose with or without fee is hereby granted, provided that the above >> + * copyright notice and this permission notice appear in all copies. >> + * >> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES >> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF >> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR >> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES >> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN >> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF >> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. >> + */ >> + >> +#include <stdlib.h> >> +#include <unistd.h> >> +#include <fcntl.h> >> + >> +#include "tls.h" >> +#include "tls_internal.h" >> + >> +#include <openssl/bio.h> >> + >> +static int write_cb(BIO *b, const char *buf, int num); >> +static int read_cb(BIO *b, char *buf, int size); >> +static int puts_cb(BIO *b, const char *str); >> +static long ctrl_cb(BIO *b, int cmd, long num, void *ptr); >> +static int new_cb(BIO *b); >> +static int free_cb(BIO *data); >> + >> +struct bio_cb_st { >> + int (*write_cb)(BIO *h, const char *buf, int num, void *cb_arg); >> + int (*read_cb)(BIO *h, char *buf, int size, void *cb_arg); >> + void *cb_arg; >> +}; >> + >> +static BIO_METHOD cb_method = { >> + .type = BIO_TYPE_MEM, >> + .name = "libtls_callbacks", >> + .bwrite = write_cb, >> + .bread = read_cb, >> + .bputs = puts_cb, >> + .ctrl = ctrl_cb, >> + .create = new_cb, >> + .destroy = free_cb >> +}; >> + >> +static BIO_METHOD * >> +bio_s_cb(void) >> +{ >> + return (&cb_method); >> +} >> + >> +static int >> +bio_set_write_cb(BIO *bi, >> + int (*write_cb)(BIO *h, const char *buf, int num, void *cb_arg)) >> +{ >> + struct bio_cb_st *b; >> + b = (struct bio_cb_st *)bi->ptr; >> + b->write_cb = write_cb; >> + return (0); >> +} >> + >> +static int >> +bio_set_read_cb(BIO *bi, >> + int (*read_cb)(BIO *h, char *buf, int size, void *cb_arg)) >> +{ >> + struct bio_cb_st *b; >> + b = (struct bio_cb_st *)bi->ptr; >> + b->read_cb = read_cb; >> + return (0); >> +} >> + >> +static int >> +bio_set_cb_arg(BIO *bi, void *cb_arg) >> +{ >> + struct bio_cb_st *b; >> + b = (struct bio_cb_st *)bi->ptr; >> + b->cb_arg = cb_arg; >> + return (0); >> +} >> + >> +static int >> +new_cb(BIO *bi) >> +{ >> + struct bio_cb_st *bcb; >> + >> + bcb = calloc(1, sizeof(struct bio_cb_st)); >> + if (bcb == NULL) >> + return (0); >> + >> + bi->shutdown = 1; >> + bi->init = 1; >> + bi->num = -1; >> + bi->ptr = (char *)bcb; >> + >> + return (1); >> +} >> + >> +static int >> +free_cb(BIO *bi) >> +{ >> + if (bi == NULL) >> + return (0); >> + >> + if (bi->shutdown) { >> + if ((bi->init) && (bi->ptr != NULL)) { >> + struct bio_cb_st *b; >> + b = (struct bio_cb_st *)bi->ptr; >> + free(b); >> + bi->ptr = NULL; >> + } >> + } >> + >> + return (1); >> +} >> + >> +static int >> +read_cb(BIO *b, char *buf, int size) >> +{ >> + struct bio_cb_st *bcb = b->ptr; >> + return (bcb->read_cb(b, buf, size, bcb->cb_arg)); >> +} >> + >> +static int >> +write_cb(BIO *b, const char *buf, int num) >> +{ >> + struct bio_cb_st *bcb = b->ptr; >> + return (bcb->write_cb(b, buf, num, bcb->cb_arg)); >> +} >> + >> +static int >> +puts_cb(BIO *b, const char *str) >> +{ >> + int n; >> + >> + n = strlen(str); >> + return (write_cb(b, str, n)); >> +} >> + >> +static long >> +ctrl_cb(BIO *b, int cmd, long num, void *ptr) >> +{ >> + long ret = 1; >> + >> + switch (cmd) { >> + case BIO_CTRL_GET_CLOSE: >> + ret = (long)b->shutdown; >> + break; >> + case BIO_CTRL_SET_CLOSE: >> + b->shutdown = (int)num; >> + break; >> + case BIO_CTRL_DUP: >> + break; >> + case BIO_CTRL_INFO: >> + case BIO_CTRL_GET: >> + case BIO_CTRL_SET: >> + default: >> + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); >> + } >> + >> + return (ret); >> +} >> + >> +static int >> +tls_bio_write_cb(BIO *h, const char *buf, int num, void *cb_arg) >> +{ >> + struct tls *ctx = cb_arg; >> + return (ctx->write_cb)(ctx, buf, num, ctx->cb_arg); >> +} >> + >> +static int >> +tls_bio_read_cb(BIO *h, char *buf, int size, void *cb_arg) >> +{ >> + struct tls *ctx = cb_arg; >> + return (ctx->read_cb)(ctx, buf, size, ctx->cb_arg); >> +} >> + >> +static BIO * >> +tls_get_new_cb_bio(struct tls *ctx) >> +{ >> + BIO *bcb; >> + if (ctx->read_cb == NULL || ctx->write_cb == NULL) >> + tls_set_errorx(ctx, "no callbacks registered"); >> + >> + bcb = BIO_new(bio_s_cb()); >> + if (bcb == NULL) { >> + tls_set_errorx(ctx, "failed to create callback i/o"); >> + return (NULL); >> + } >> + >> + bio_set_write_cb(bcb, tls_bio_write_cb); >> + bio_set_read_cb(bcb, tls_bio_read_cb); >> + bio_set_cb_arg(bcb, ctx); >> + >> + return (bcb); >> +} >> + >> +int >> +tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb, >> + void *cb_arg) >> +{ >> + int rv = -1; >> + BIO *bcb; >> + ctx->read_cb = read_cb; >> + ctx->write_cb = write_cb; >> + ctx->cb_arg = cb_arg; >> + >> + bcb = tls_get_new_cb_bio(ctx); >> + if (bcb == NULL) { >> + tls_set_errorx(ctx, "failed to create callback i/o"); >> + goto err; >> + } >> + >> + SSL_set_bio(ctx->ssl_conn, bcb, bcb); >> + >> + rv = 0; >> + >> + err: >> + return (rv); >> +} >> Index: tls_client.c >> =================================================================== >> RCS file: /cvs/src/lib/libtls/tls_client.c,v >> retrieving revision 1.34 >> diff -u -p -u -p -r1.34 tls_client.c >> --- tls_client.c 15 Aug 2016 14:04:23 -0000 1.34 >> +++ tls_client.c 4 Sep 2016 10:23:42 -0000 >> @@ -158,15 +158,8 @@ tls_connect_servername(struct tls *ctx, >> return (rv); >> } >> >> -int >> -tls_connect_socket(struct tls *ctx, int s, const char *servername) >> -{ >> - return tls_connect_fds(ctx, s, s, servername); >> -} >> - >> -int >> -tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, >> - const char *servername) >> +static int >> +connect_common(struct tls *ctx, const char *servername) >> { >> union tls_addr addrbuf; >> int rv = -1; >> @@ -176,11 +169,6 @@ tls_connect_fds(struct tls *ctx, int fd_ >> goto err; >> } >> >> - if (fd_read < 0 || fd_write < 0) { >> - tls_set_errorx(ctx, "invalid file descriptors"); >> - goto err; >> - } >> - >> if (servername != NULL) { >> if ((ctx->servername = strdup(servername)) == NULL) { >> tls_set_errorx(ctx, "out of memory"); >> @@ -195,6 +183,7 @@ tls_connect_fds(struct tls *ctx, int fd_ >> >> if (tls_configure_ssl(ctx, ctx->ssl_ctx) != 0) >> goto err; >> + >> if (tls_configure_ssl_keypair(ctx, ctx->ssl_ctx, >> ctx->config->keypair, 0) != 0) >> goto err; >> @@ -205,6 +194,7 @@ tls_connect_fds(struct tls *ctx, int fd_ >> goto err; >> } >> } >> + >> if (ctx->config->verify_cert && >> (tls_configure_ssl_verify(ctx, ctx->ssl_ctx, >> SSL_VERIFY_PEER) == -1)) >> @@ -214,15 +204,11 @@ tls_connect_fds(struct tls *ctx, int fd_ >> tls_set_errorx(ctx, "ssl connection failure"); >> goto err; >> } >> + >> if (SSL_set_app_data(ctx->ssl_conn, ctx) != 1) { >> tls_set_errorx(ctx, "ssl application data failure"); >> goto err; >> } >> - if (SSL_set_rfd(ctx->ssl_conn, fd_read) != 1 || >> - SSL_set_wfd(ctx->ssl_conn, fd_write) != 1) { >> - tls_set_errorx(ctx, "ssl file descriptor failure"); >> - goto err; >> - } >> >> /* >> * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not >> @@ -235,6 +221,56 @@ tls_connect_fds(struct tls *ctx, int fd_ >> tls_set_errorx(ctx, "server name indication failure"); >> goto err; >> } >> + } >> + rv = 0; >> + >> + err: >> + return (rv); >> +} >> + >> +int >> +tls_connect_socket(struct tls *ctx, int s, const char *servername) >> +{ >> + return tls_connect_fds(ctx, s, s, servername); >> +} >> + >> +int >> +tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, >> + const char *servername) >> +{ >> + int rv = -1; >> + >> + if (fd_read < 0 || fd_write < 0) { >> + tls_set_errorx(ctx, "invalid file descriptors"); >> + goto err; >> + } >> + >> + if (connect_common(ctx, servername) != 0) >> + goto err; >> + >> + if (SSL_set_rfd(ctx->ssl_conn, fd_read) != 1 || >> + SSL_set_wfd(ctx->ssl_conn, fd_write) != 1) { >> + tls_set_errorx(ctx, "ssl file descriptor failure"); >> + goto err; >> + } >> + >> + rv = 0; >> + err: >> + return (rv); >> +} >> + >> +int >> +tls_connect_cbs(struct tls *ctx, tls_read_cb read_cb, >> + tls_write_cb write_cb, void *cb_arg, const char *servername) >> +{ >> + int rv = -1; >> + >> + if (connect_common(ctx, servername) != 0) >> + goto err; >> + >> + if (tls_set_cbs(ctx, read_cb, write_cb, cb_arg) != 0) { >> + tls_set_errorx(ctx, "callback registration failure"); >> + goto err; >> } >> >> rv = 0; >> Index: tls_init.3 >> =================================================================== >> RCS file: /cvs/src/lib/libtls/tls_init.3,v >> retrieving revision 1.67 >> diff -u -p -u -p -r1.67 tls_init.3 >> --- tls_init.3 22 Aug 2016 14:55:59 -0000 1.67 >> +++ tls_init.3 4 Sep 2016 10:23:43 -0000 >> @@ -71,8 +71,10 @@ >> .Nm tls_connect_fds , >> .Nm tls_connect_servername , >> .Nm tls_connect_socket , >> +.Nm tls_connect_cbs , >> .Nm tls_accept_fds , >> .Nm tls_accept_socket , >> +.Nm tls_accept_cbs , >> .Nm tls_handshake , >> .Nm tls_read , >> .Nm tls_write , >> @@ -187,10 +189,14 @@ >> .Ft "int" >> .Fn tls_connect_socket "struct tls *ctx" "int s" "const char *servername" >> .Ft "int" >> +.Fn tls_connect_cbs "struct tls *ctx" "ssize_t (*tls_read_cb)(void *ctx, >> void *buf, size_t buflen, void *cb_arg)" "ssize_t (*tls_write_cb)(void *ctx, >> const void *buf, size_t buflen, void *cb_arg)" "void *cb_arg" "const char >> *servername" >> +.Ft "int" >> .Fn tls_accept_fds "struct tls *tls" "struct tls **cctx" "int fd_read" "int >> fd_write" >> .Ft "int" >> .Fn tls_accept_socket "struct tls *tls" "struct tls **cctx" "int socket" >> .Ft "int" >> +.Fn tls_accept_cbs "struct tls *ctx" "struct tls **cctx" "ssize_t >> (*tls_read_cb)(void *ctx, void *buf, size_t buflen, void *cb_arg)" "ssize_t >> (*tls_write_cb)(void *ctx, const void *buf, size_t buflen, void *cb_arg)" >> "void *cb_arg" >> +.Ft "int" >> .Fn tls_handshake "struct tls *ctx" >> .Ft "ssize_t" >> .Fn tls_read "struct tls *ctx" "void *buf" "size_t buflen" >> @@ -247,6 +253,9 @@ An already existing socket can be upgrad >> Alternatively, a secure connection can be established over a pair of existing >> file descriptors by calling >> .Fn tls_connect_fds . >> +Calling >> +.Fn tls_connect_cbs >> +allows specifying read and write callback functions to handle data >> transfer. The specified cb_arg parameter is passed back to the functions, >> and can contain a pointer to any caller-specified data. >> .Pp >> A server can accept a new client connection by calling >> .Fn tls_accept_socket >> @@ -254,6 +263,9 @@ on an already established socket connect >> Alternatively, a new client connection can be accepted over a pair of >> existing >> file descriptors by calling >> .Fn tls_accept_fds . >> +Calling >> +.Fn tls_accept_cbs >> +allows specifying read and write callback functions to handle data >> transfer. The specified cb_arg parameter is passed back to the functions, >> and can contain a pointer to any caller-specified data. >> .Pp >> The TLS handshake can be completed by calling >> .Fn tls_handshake . >> Index: tls_internal.h >> =================================================================== >> RCS file: /cvs/src/lib/libtls/tls_internal.h,v >> retrieving revision 1.42 >> diff -u -p -u -p -r1.42 tls_internal.h >> --- tls_internal.h 22 Aug 2016 17:12:35 -0000 1.42 >> +++ tls_internal.h 4 Sep 2016 10:23:43 -0000 >> @@ -117,6 +117,10 @@ struct tls { >> X509 *ssl_peer_cert; >> >> struct tls_conninfo *conninfo; >> + >> + tls_read_cb read_cb; >> + tls_write_cb write_cb; >> + void *cb_arg; >> }; >> >> struct tls_sni_ctx *tls_sni_ctx_new(void); >> @@ -139,6 +143,9 @@ int tls_handshake_server(struct tls *ctx >> int tls_config_load_file(struct tls_error *error, const char *filetype, >> const char *filename, char **buf, size_t *len); >> int tls_host_port(const char *hostport, char **host, char **port); >> + >> +int tls_set_cbs(struct tls *ctx, >> + tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg); >> >> int tls_error_set(struct tls_error *error, const char *fmt, ...) >> __attribute__((__format__ (printf, 2, 3))) >> Index: tls_server.c >> =================================================================== >> RCS file: /cvs/src/lib/libtls/tls_server.c,v >> retrieving revision 1.25 >> diff -u -p -u -p -r1.25 tls_server.c >> --- tls_server.c 22 Aug 2016 14:51:37 -0000 1.25 >> +++ tls_server.c 4 Sep 2016 10:23:43 -0000 >> @@ -279,14 +279,8 @@ tls_configure_server(struct tls *ctx) >> return (-1); >> } >> >> -int >> -tls_accept_socket(struct tls *ctx, struct tls **cctx, int socket) >> -{ >> - return (tls_accept_fds(ctx, cctx, socket, socket)); >> -} >> - >> -int >> -tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int >> fd_write) >> +static struct tls * >> +accept_common(struct tls *ctx) >> { >> struct tls *conn_ctx = NULL; >> >> @@ -304,10 +298,34 @@ tls_accept_fds(struct tls *ctx, struct t >> tls_set_errorx(ctx, "ssl failure"); >> goto err; >> } >> + >> if (SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx) != 1) { >> tls_set_errorx(ctx, "ssl application data failure"); >> goto err; >> } >> + >> + return conn_ctx; >> + >> + err: >> + tls_free(conn_ctx); >> + >> + return (NULL); >> +} >> + >> +int >> +tls_accept_socket(struct tls *ctx, struct tls **cctx, int socket) >> +{ >> + return (tls_accept_fds(ctx, cctx, socket, socket)); >> +} >> + >> +int >> +tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int >> fd_write) >> +{ >> + struct tls *conn_ctx; >> + >> + if ((conn_ctx = accept_common(ctx)) == NULL) >> + goto err; >> + >> if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 || >> SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) { >> tls_set_errorx(ctx, "ssl file descriptor failure"); >> @@ -317,10 +335,32 @@ tls_accept_fds(struct tls *ctx, struct t >> *cctx = conn_ctx; >> >> return (0); >> - >> err: >> tls_free(conn_ctx); >> + *cctx = NULL; >> + >> + return (-1); >> +} >> + >> +int >> +tls_accept_cbs(struct tls *ctx, struct tls **cctx, >> + tls_read_cb read_cb, tls_write_cb write_cb, void *cb_arg) >> +{ >> + struct tls *conn_ctx; >> + >> + if ((conn_ctx = accept_common(ctx)) == NULL) >> + goto err; >> + >> + if (tls_set_cbs(ctx, read_cb, write_cb, cb_arg) != 0) { >> + tls_set_errorx(ctx, "callback registration failure"); >> + goto err; >> + } >> >> + *cctx = conn_ctx; >> + >> + return (0); >> + err: >> + tls_free(conn_ctx); >> *cctx = NULL; >> >> return (-1); >> Index: tls_verify.c >> =================================================================== >> RCS file: /cvs/src/lib/libtls/tls_verify.c,v >> retrieving revision 1.16 >> diff -u -p -u -p -r1.16 tls_verify.c >> --- tls_verify.c 2 Aug 2016 07:47:11 -0000 1.16 >> +++ tls_verify.c 4 Sep 2016 10:23:43 -0000 >> @@ -24,6 +24,7 @@ >> >> #include <openssl/x509v3.h> >> >> +#include <tls.h> >> #include "tls_internal.h" >> >> static int tls_match_name(const char *cert_name, const char *name); >>