Make it build using OpenSSL 1.1.0

Rebased (azat):
- tabs instead of whitespaces
- make openssl-compat.h safe for complex expressions
- do not call sk_SSL_COMP_free() in 1.1 (fixes double free)

TODO:
- clean methods_bufferevent

Refs: #397 (cherry-picked)
(cherry picked from commit 3e9e0a0d46e4508e8782ec3787c6d86bab63046d)
This commit is contained in:
Kurt Roeckx 2016-09-19 22:05:15 +02:00 committed by Azat Khuzhin
parent 4294867cbc
commit 19e839c7bb
2 changed files with 63 additions and 32 deletions

View File

@ -60,6 +60,7 @@
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
#include "openssl-compat.h"
/* /*
* Define an OpenSSL bio that targets a bufferevent. * Define an OpenSSL bio that targets a bufferevent.
@ -103,10 +104,8 @@ print_err(int val)
static int static int
bio_bufferevent_new(BIO *b) bio_bufferevent_new(BIO *b)
{ {
b->init = 0; BIO_set_init(b, 0);
b->num = -1; BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/
b->ptr = NULL; /* We'll be putting the bufferevent in this field.*/
b->flags = 0;
return 1; return 1;
} }
@ -116,12 +115,10 @@ bio_bufferevent_free(BIO *b)
{ {
if (!b) if (!b)
return 0; return 0;
if (b->shutdown) { if (BIO_get_shutdown(b)) {
if (b->init && b->ptr) if (BIO_get_init(b) && BIO_get_data(b))
bufferevent_free(b->ptr); bufferevent_free(BIO_get_data(b));
b->init = 0; BIO_free(b);
b->flags = 0;
b->ptr = NULL;
} }
return 1; return 1;
} }
@ -137,10 +134,10 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
if (!out) if (!out)
return 0; return 0;
if (!b->ptr) if (!BIO_get_data(b))
return -1; return -1;
input = bufferevent_get_input(b->ptr); input = bufferevent_get_input(BIO_get_data(b));
if (evbuffer_get_length(input) == 0) { if (evbuffer_get_length(input) == 0) {
/* If there's no data to read, say so. */ /* If there's no data to read, say so. */
BIO_set_retry_read(b); BIO_set_retry_read(b);
@ -156,13 +153,13 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
static int static int
bio_bufferevent_write(BIO *b, const char *in, int inlen) bio_bufferevent_write(BIO *b, const char *in, int inlen)
{ {
struct bufferevent *bufev = b->ptr; struct bufferevent *bufev = BIO_get_data(b);
struct evbuffer *output; struct evbuffer *output;
size_t outlen; size_t outlen;
BIO_clear_retry_flags(b); BIO_clear_retry_flags(b);
if (!b->ptr) if (!BIO_get_data(b))
return -1; return -1;
output = bufferevent_get_output(bufev); output = bufferevent_get_output(bufev);
@ -188,15 +185,15 @@ bio_bufferevent_write(BIO *b, const char *in, int inlen)
static long static long
bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr) bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
{ {
struct bufferevent *bufev = b->ptr; struct bufferevent *bufev = BIO_get_data(b);
long ret = 1; long ret = 1;
switch (cmd) { switch (cmd) {
case BIO_CTRL_GET_CLOSE: case BIO_CTRL_GET_CLOSE:
ret = b->shutdown; ret = BIO_get_shutdown(b);
break; break;
case BIO_CTRL_SET_CLOSE: case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num; BIO_set_shutdown(b, (int)num);
break; break;
case BIO_CTRL_PENDING: case BIO_CTRL_PENDING:
ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0; ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
@ -225,23 +222,24 @@ bio_bufferevent_puts(BIO *b, const char *s)
} }
/* Method table for the bufferevent BIO */ /* Method table for the bufferevent BIO */
static BIO_METHOD methods_bufferevent = { static BIO_METHOD *methods_bufferevent;
BIO_TYPE_LIBEVENT, "bufferevent",
bio_bufferevent_write,
bio_bufferevent_read,
bio_bufferevent_puts,
NULL /* bio_bufferevent_gets */,
bio_bufferevent_ctrl,
bio_bufferevent_new,
bio_bufferevent_free,
NULL /* callback_ctrl */,
};
/* Return the method table for the bufferevents BIO */ /* Return the method table for the bufferevents BIO */
static BIO_METHOD * static BIO_METHOD *
BIO_s_bufferevent(void) BIO_s_bufferevent(void)
{ {
return &methods_bufferevent; if (methods_bufferevent == NULL) {
methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent");
if (methods_bufferevent == NULL)
return NULL;
BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write);
BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read);
BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts);
BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl);
BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new);
BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free);
}
return methods_bufferevent;
} }
/* Create a new BIO to wrap communication around a bufferevent. If close_flag /* Create a new BIO to wrap communication around a bufferevent. If close_flag
@ -254,9 +252,9 @@ BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag)
return NULL; return NULL;
if (!(result = BIO_new(BIO_s_bufferevent()))) if (!(result = BIO_new(BIO_s_bufferevent())))
return NULL; return NULL;
result->init = 1; BIO_set_init(result, 1);
result->ptr = bufferevent; BIO_set_data(result, bufferevent);
result->shutdown = close_flag ? 1 : 0; BIO_set_shutdown(result, close_flag ? 1 : 0);
return result; return result;
} }

33
openssl-compat.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef OPENSSL_COMPAT_H
#define OPENSSL_COMPAT_H
#if OPENSSL_VERSION_NUMBER < 0x10100000L
static BIO_METHOD *BIO_meth_new(int type, const char *name)
{
BIO_METHOD *biom = calloc(1, sizeof(BIO_METHOD));
if (biom != NULL) {
biom->type = type;
biom->name = name;
}
return biom;
}
#define BIO_meth_set_write(b, f) (b)->bwrite = (f)
#define BIO_meth_set_read(b, f) (b)->bread = (f)
#define BIO_meth_set_puts(b, f) (b)->bputs = (f)
#define BIO_meth_set_ctrl(b, f) (b)->ctrl = (f)
#define BIO_meth_set_create(b, f) (b)->create = (f)
#define BIO_meth_set_destroy(b, f) (b)->destroy = (f)
#define BIO_set_init(b, val) (b)->init = (val)
#define BIO_set_data(b, val) (b)->ptr = (val)
#define BIO_set_shutdown(b, val) (b)->shutdown = (val)
#define BIO_get_init(b) (b)->init
#define BIO_get_data(b) (b)->ptr
#define BIO_get_shutdown(b) (b)->shutdown
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
#endif /* OPENSSL_COMPAT_H */