MT#55283 switch to BIO_set_callback_arg

Use a BIO WRITE callback instead of BIO_read'ing from the BIO after each
operation. This is a more direct way to intercept data that needs to be
sent out.

Implement MTU-related BIO callbacks.

Deduct the assumed IP MTU overhead from the configured MTU during
startup.

Unlike the previous code, this does not necessarily send DTLS from the
same socket that received a message, nor to the same address that sent
one, and instead always uses the selected_sfd and ->endpoint. This may
or may not be a regression.

Closes #1806

Change-Id: I4d4456df3f378d00782cbfa64afdb2a038217e6c
(cherry picked from commit 08332161cf)
(cherry picked from commit dd7e56d1f6)
mr12.5.1
Richard Fuchs 9 months ago
parent d0ed54e004
commit e95d51585a

@ -604,6 +604,51 @@ static int try_connect(struct dtls_connection *d) {
return ret;
}
static long dtls_bio_callback(BIO *bio, int oper, const char *argp, size_t len, int argi, long argl,
int ret, size_t *proc)
{
if (oper == (BIO_CB_CTRL | BIO_CB_RETURN)) {
if (argi == BIO_CTRL_DGRAM_QUERY_MTU)
return rtpe_config.dtls_mtu; // this is with overhead already subtracted
if (argi == BIO_CTRL_DGRAM_GET_MTU_OVERHEAD)
return DTLS_MTU_OVERHEAD;
return ret;
}
if (oper != BIO_CB_WRITE)
return ret;
if (!argp || len <= 0)
return ret;
struct packet_stream *ps = (struct packet_stream *) BIO_get_callback_arg(bio);
if (!ps)
return ret;
struct stream_fd *sfd = ps->selected_sfd;
if (!sfd)
return ret;
struct dtls_connection *d = dtls_ptr(sfd);
if (!d)
return ret;
__DBG("dtls packet output: len %zu %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
len,
argp[0], argp[1], argp[2], argp[3],
argp[4], argp[5], argp[6], argp[7],
argp[8], argp[9], argp[10], argp[11],
argp[12], argp[13], argp[14], argp[15]);
const endpoint_t *fsin = &ps->endpoint;
if (fsin->port == 9 || fsin->address.family == NULL)
return ret;
ilogs(srtp, LOG_DEBUG, "Sending DTLS packet");
socket_sendto(&sfd->socket, argp, len, fsin);
atomic64_inc_na(&ps->stats_out->packets);
atomic64_add_na(&ps->stats_out->bytes, len);
return ret;
}
int dtls_connection_init(struct dtls_connection *d, struct packet_stream *ps, int active,
struct dtls_cert *cert)
{
@ -656,6 +701,14 @@ int dtls_connection_init(struct dtls_connection *d, struct packet_stream *ps, in
if (!d->r_bio || !d->w_bio)
goto error;
BIO_set_callback_ex(d->w_bio, dtls_bio_callback);
BIO_set_callback_arg(d->w_bio, (char *) ps);
#if defined(BIO_CTRL_DGRAM_SET_MTU)
BIO_ctrl(d->w_bio, BIO_CTRL_DGRAM_SET_MTU, rtpe_config.dtls_mtu, NULL);
BIO_ctrl(d->r_bio, BIO_CTRL_DGRAM_SET_MTU, rtpe_config.dtls_mtu, NULL);
#endif
SSL_set_app_data(d->ssl, d);
SSL_set_bio(d->ssl, d->r_bio, d->w_bio);
d->init = 1;
@ -792,7 +845,6 @@ error:
int dtls(stream_fd *sfd, const str *s, const endpoint_t *fsin) {
struct packet_stream *ps = sfd->stream;
int ret;
unsigned char buf[0x10000];
if (!ps)
return 0;
@ -856,42 +908,6 @@ int dtls(stream_fd *sfd, const str *s, const endpoint_t *fsin) {
}
}
while (1) {
ret = BIO_ctrl_pending(d->w_bio);
if (ret <= 0)
break;
if (ret > sizeof(buf)) {
ilogs(srtp, LOG_ERROR, "BIO buffer overflow");
(void) BIO_reset(d->w_bio);
break;
}
ret = BIO_read(d->w_bio, buf, ret);
if (ret <= 0)
break;
__DBG("dtls packet output: len %u %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
ret,
buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6], buf[7],
buf[8], buf[9], buf[10], buf[11],
buf[12], buf[13], buf[14], buf[15]);
if (!fsin) {
fsin = &ps->endpoint;
if (fsin->port == 9 || fsin->address.family == NULL)
fsin = NULL;
}
if (fsin) {
ilogs(srtp, LOG_DEBUG, "Sending DTLS packet");
socket_sendto(&sfd->socket, buf, ret, fsin);
atomic64_inc_na(&ps->stats_out->packets);
atomic64_add_na(&ps->stats_out->bytes, ret);
}
}
return dret;
}

@ -955,6 +955,8 @@ static void options(int *argc, char ***argv) {
However, this does not preclude link layers with an MTU smaller than this minimum MTU from conveying IP data. Internet IPv4 path MTU is 68 bytes.*/
die("Invalid --dtls-mtu (%i)", rtpe_config.dtls_mtu);
rtpe_config.dtls_mtu -= DTLS_MTU_OVERHEAD;
if (rtpe_config.jb_length < 0)
die("Invalid negative jitter buffer size");

@ -13,6 +13,7 @@
#include "types.h"
#define DTLS_MAX_DIGEST_LEN 64
#define DTLS_MTU_OVERHEAD 48 // 40 bytes IPv6 + 8 bytes UDP
struct packet_stream;
struct sockaddr_in6;

Loading…
Cancel
Save