Browse Source

TT#50652 separate out and move crypt handler routines

Change-Id: Ia30aa8912f02ca2ea427b3c659a4b8696dc4a2a0
changes/78/27878/1
Richard Fuchs 7 years ago
parent
commit
d449861d96
4 changed files with 181 additions and 147 deletions
  1. +0
    -78
      daemon/call.c
  2. +138
    -45
      daemon/media_socket.c
  3. +1
    -24
      include/call.h
  4. +42
    -0
      include/media_socket.h

+ 0
- 78
daemon/call.c View File

@ -59,65 +59,6 @@ struct xmlrpc_helper {
GQueue strings;
};
const struct transport_protocol transport_protocols[] = {
[PROTO_RTP_AVP] = {
.index = PROTO_RTP_AVP,
.name = "RTP/AVP",
.rtp = 1,
.srtp = 0,
.avpf = 0,
.tcp = 0,
},
[PROTO_RTP_SAVP] = {
.index = PROTO_RTP_SAVP,
.name = "RTP/SAVP",
.rtp = 1,
.srtp = 1,
.avpf = 0,
.tcp = 0,
},
[PROTO_RTP_AVPF] = {
.index = PROTO_RTP_AVPF,
.name = "RTP/AVPF",
.rtp = 1,
.srtp = 0,
.avpf = 1,
.tcp = 0,
},
[PROTO_RTP_SAVPF] = {
.index = PROTO_RTP_SAVPF,
.name = "RTP/SAVPF",
.rtp = 1,
.srtp = 1,
.avpf = 1,
.tcp = 0,
},
[PROTO_UDP_TLS_RTP_SAVP] = {
.index = PROTO_UDP_TLS_RTP_SAVP,
.name = "UDP/TLS/RTP/SAVP",
.rtp = 1,
.srtp = 1,
.avpf = 0,
.tcp = 0,
},
[PROTO_UDP_TLS_RTP_SAVPF] = {
.index = PROTO_UDP_TLS_RTP_SAVPF,
.name = "UDP/TLS/RTP/SAVPF",
.rtp = 1,
.srtp = 1,
.avpf = 1,
.tcp = 0,
},
[PROTO_UDPTL] = {
.index = PROTO_UDPTL,
.name = "udptl",
.rtp = 0,
.srtp = 0,
.avpf = 0,
.tcp = 0,
},
};
const int num_transport_protocols = G_N_ELEMENTS(transport_protocols);
/* XXX rework these */
struct stats rtpe_statsps;
@ -2859,22 +2800,3 @@ void call_get_all_calls(GQueue *q) {
rwlock_unlock_r(&rtpe_callhash_lock);
}
const struct transport_protocol *transport_protocol(const str *s) {
int i;
if (!s || !s->s)
goto out;
for (i = 0; i < num_transport_protocols; i++) {
if (strlen(transport_protocols[i].name) != s->len)
continue;
if (strncasecmp(transport_protocols[i].name, s->s, s->len))
continue;
return &transport_protocols[i];
}
out:
return NULL;
}

+ 138
- 45
daemon/media_socket.c View File

@ -38,20 +38,7 @@
#endif
typedef int (*rewrite_func)(str *, struct packet_stream *, struct stream_fd *, const endpoint_t *,
const struct timeval *, struct ssrc_ctx *);
struct streamhandler_io {
rewrite_func rtp_crypt;
rewrite_func rtcp_crypt;
rtcp_filter_func *rtcp_filter;
int (*kernel)(struct rtpengine_srtp *, struct packet_stream *);
};
struct streamhandler {
const struct streamhandler_io *in;
const struct streamhandler_io *out;
};
struct intf_rr {
struct logical_intf hash_key;
mutex_t lock;
@ -79,7 +66,7 @@ struct packet_handler_ctx {
};
static void determine_handler(struct packet_stream *in, const struct packet_stream *out);
static void __determine_handler(struct packet_stream *in, const struct packet_stream *out);
static int __k_null(struct rtpengine_srtp *s, struct packet_stream *);
static int __k_srtp_encrypt(struct rtpengine_srtp *s, struct packet_stream *);
@ -100,6 +87,70 @@ static struct logical_intf *__get_logical_interface(const str *name, sockfamily_
/* ********** */
const struct transport_protocol transport_protocols[] = {
[PROTO_RTP_AVP] = {
.index = PROTO_RTP_AVP,
.name = "RTP/AVP",
.rtp = 1,
.srtp = 0,
.avpf = 0,
.tcp = 0,
},
[PROTO_RTP_SAVP] = {
.index = PROTO_RTP_SAVP,
.name = "RTP/SAVP",
.rtp = 1,
.srtp = 1,
.avpf = 0,
.tcp = 0,
},
[PROTO_RTP_AVPF] = {
.index = PROTO_RTP_AVPF,
.name = "RTP/AVPF",
.rtp = 1,
.srtp = 0,
.avpf = 1,
.tcp = 0,
},
[PROTO_RTP_SAVPF] = {
.index = PROTO_RTP_SAVPF,
.name = "RTP/SAVPF",
.rtp = 1,
.srtp = 1,
.avpf = 1,
.tcp = 0,
},
[PROTO_UDP_TLS_RTP_SAVP] = {
.index = PROTO_UDP_TLS_RTP_SAVP,
.name = "UDP/TLS/RTP/SAVP",
.rtp = 1,
.srtp = 1,
.avpf = 0,
.tcp = 0,
},
[PROTO_UDP_TLS_RTP_SAVPF] = {
.index = PROTO_UDP_TLS_RTP_SAVPF,
.name = "UDP/TLS/RTP/SAVPF",
.rtp = 1,
.srtp = 1,
.avpf = 1,
.tcp = 0,
},
[PROTO_UDPTL] = {
.index = PROTO_UDPTL,
.name = "udptl",
.rtp = 0,
.srtp = 0,
.avpf = 0,
.tcp = 0,
},
};
const int num_transport_protocols = G_N_ELEMENTS(transport_protocols);
/* ********** */
static const struct streamhandler_io __shio_noop = { // non-RTP protocols
.kernel = __k_null,
@ -994,7 +1045,7 @@ void kernelize(struct packet_stream *stream) {
goto no_kernel;
}
determine_handler(stream, sink);
__determine_handler(stream, sink);
if (is_addr_unspecified(&sink->advertised_endpoint.address)
|| !sink->advertised_endpoint.port)
@ -1124,41 +1175,58 @@ void unkernelize(struct packet_stream *ps) {
/* must be called with call->master_lock held in R, and in->in_lock held */
static void determine_handler(struct packet_stream *in, const struct packet_stream *out) {
const struct streamhandler *determine_handler(const struct transport_protocol *in_proto,
const struct transport_protocol *out_proto, int must_recrypt)
{
const struct streamhandler * const *sh_pp, *sh;
const struct streamhandler * const * const *matrix;
matrix = __sh_matrix;
if (must_recrypt)
matrix = __sh_matrix_recrypt;
sh_pp = matrix[in_proto->index];
if (!sh_pp)
goto err;
sh = sh_pp[out_proto->index];
if (!sh)
goto err;
return sh;
err:
ilog(LOG_WARNING, "Unknown transport protocol encountered");
return &__sh_noop;
}
/* must be called with call->master_lock held in R, and in->in_lock held */
static void __determine_handler(struct packet_stream *in, const struct packet_stream *out) {
const struct transport_protocol *in_proto, *out_proto;
int must_recrypt = 0;
if (in->handler)
return;
if (MEDIA_ISSET(in->media, PASSTHRU))
goto noop;
if (!in->media->protocol)
in_proto = in->media->protocol;
out_proto = out->media->protocol;
if (!in_proto)
goto err;
if (!out->media->protocol)
if (!out_proto)
goto err;
matrix = __sh_matrix;
if (MEDIA_ISSET(in->media, DTLS) || MEDIA_ISSET(out->media, DTLS))
matrix = __sh_matrix_recrypt;
must_recrypt = 1;
else if (in->call->recording)
matrix = __sh_matrix_recrypt;
else if (in->media->protocol->srtp && out->media->protocol->srtp
must_recrypt = 1;
else if (in_proto->srtp && out_proto->srtp
&& in->selected_sfd && out->selected_sfd
&& (crypto_params_cmp(&in->crypto.params, &out->selected_sfd->crypto.params)
|| crypto_params_cmp(&out->crypto.params, &in->selected_sfd->crypto.params)))
matrix = __sh_matrix_recrypt;
sh_pp = matrix[in->media->protocol->index];
if (!sh_pp)
goto err;
sh = sh_pp[out->media->protocol->index];
if (!sh)
goto err;
in->handler = sh;
must_recrypt = 1;
in->handler = determine_handler(in_proto, out_proto, must_recrypt);
return;
err:
@ -1362,7 +1430,7 @@ static void media_packet_rtp(struct packet_handler_ctx *phc)
static int media_packet_decrypt(struct packet_handler_ctx *phc)
{
mutex_lock(&phc->in_srtp->in_lock);
determine_handler(phc->in_srtp, phc->sink);
__determine_handler(phc->in_srtp, phc->sink);
// XXX use an array with index instead of if/else
if (G_LIKELY(!phc->rtcp)) {
@ -1395,28 +1463,35 @@ static int media_packet_decrypt(struct packet_handler_ctx *phc)
return ret;
}
static int media_packet_encrypt(struct packet_handler_ctx *phc) {
int ret = 0;
int media_packet_encrypt(rewrite_func encrypt_func, struct packet_stream *out, struct media_packet *mp) {
int ret = 0x00; // 0x01 = error, 0x02 = update
if (!phc->encrypt_func)
return 0;
if (!encrypt_func)
return 0x00;
mutex_lock(&phc->out_srtp->out_lock);
mutex_lock(&out->out_lock);
for (GList *l = phc->mp.packets_out.head; l; l = l->next) {
for (GList *l = mp->packets_out.head; l; l = l->next) {
struct codec_packet *p = l->data;
int encret = phc->encrypt_func(&p->s, phc->out_srtp, NULL, NULL, NULL, phc->mp.ssrc_out);
int encret = encrypt_func(&p->s, out, NULL, NULL, NULL, mp->ssrc_out);
if (encret == 1)
phc->update = 1;
ret |= 0x02;
else if (encret != 0)
ret = -1;
ret |= 0x01;
}
mutex_unlock(&phc->out_srtp->out_lock);
mutex_unlock(&out->out_lock);
return ret;
}
static int __media_packet_encrypt(struct packet_handler_ctx *phc) {
int ret = media_packet_encrypt(phc->encrypt_func, phc->out_srtp, &phc->mp);
if (ret & 0x02)
phc->update = 1;
return (ret & 0x01) ? -1 : 0;
}
// returns: 0 = OK, forward packet; -1 = drop packet
@ -1681,7 +1756,7 @@ static int stream_packet(struct packet_handler_ctx *phc) {
}
if (G_LIKELY(handler_ret >= 0))
handler_ret = media_packet_encrypt(phc);
handler_ret = __media_packet_encrypt(phc);
if (phc->unkernelize) // for RTCP packet index updates
unkernelize(phc->mp.stream);
@ -1846,3 +1921,21 @@ struct stream_fd *stream_fd_new(socket_t *fd, struct call *call, const struct lo
return sfd;
}
const struct transport_protocol *transport_protocol(const str *s) {
int i;
if (!s || !s->s)
goto out;
for (i = 0; i < num_transport_protocols; i++) {
if (strlen(transport_protocols[i].name) != s->len)
continue;
if (strncasecmp(transport_protocols[i].name, s->s, s->len))
continue;
return &transport_protocols[i];
}
out:
return NULL;
}

+ 1
- 24
include/call.h View File

@ -51,18 +51,6 @@ enum call_opmode {
OP_OTHER,
};
enum transport_protocol_index {
PROTO_RTP_AVP = 0,
PROTO_RTP_SAVP,
PROTO_RTP_AVPF,
PROTO_RTP_SAVPF,
PROTO_UDP_TLS_RTP_SAVP,
PROTO_UDP_TLS_RTP_SAVPF,
PROTO_UDPTL,
__PROTO_LAST,
};
enum call_stream_state {
CSS_UNKNOWN = 0,
CSS_SHUTDOWN,
@ -200,6 +188,7 @@ struct codec_handler;
struct rtp_payload_type;
struct media_player;
struct send_timer;
struct transport_protocol;
typedef bencode_buffer_t call_buffer_t;
@ -210,17 +199,6 @@ typedef bencode_buffer_t call_buffer_t;
struct transport_protocol {
enum transport_protocol_index index;
const char *name;
int rtp:1; /* also set to 1 for SRTP */
int srtp:1;
int avpf:1;
int tcp:1;
};
extern const struct transport_protocol transport_protocols[];
struct stream_params {
unsigned int index; /* starting with 1 */
str type;
@ -447,7 +425,6 @@ void __monologue_unkernelize(struct call_monologue *monologue);
int call_stream_address46(char *o, struct packet_stream *ps, enum stream_address_format format,
int *len, const struct local_intf *ifa, int keep_unspec);
const struct transport_protocol *transport_protocol(const str *s);
void add_total_calls_duration_in_interval(struct timeval *interval_tv);
void payload_type_free(struct rtp_payload_type *p);


+ 42
- 0
include/media_socket.h View File

@ -16,10 +16,48 @@
struct media_packet;
struct transport_protocol;
struct ssrc_ctx;
struct rtpengine_srtp;
typedef int rtcp_filter_func(struct media_packet *, GQueue *);
typedef int (*rewrite_func)(str *, struct packet_stream *, struct stream_fd *, const endpoint_t *,
const struct timeval *, struct ssrc_ctx *);
enum transport_protocol_index {
PROTO_RTP_AVP = 0,
PROTO_RTP_SAVP,
PROTO_RTP_AVPF,
PROTO_RTP_SAVPF,
PROTO_UDP_TLS_RTP_SAVP,
PROTO_UDP_TLS_RTP_SAVPF,
PROTO_UDPTL,
__PROTO_LAST,
};
struct transport_protocol {
enum transport_protocol_index index;
const char *name;
int rtp:1; /* also set to 1 for SRTP */
int srtp:1;
int avpf:1;
int tcp:1;
};
extern const struct transport_protocol transport_protocols[];
struct streamhandler_io {
rewrite_func rtp_crypt;
rewrite_func rtcp_crypt;
rtcp_filter_func *rtcp_filter;
int (*kernel)(struct rtpengine_srtp *, struct packet_stream *);
};
struct streamhandler {
const struct streamhandler_io *in;
const struct streamhandler_io *out;
};
struct logical_intf {
@ -131,6 +169,10 @@ void unkernelize(struct packet_stream *);
void __stream_unconfirm(struct packet_stream *);
int media_socket_dequeue(struct media_packet *mp, struct packet_stream *sink);
const struct streamhandler *determine_handler(const struct transport_protocol *in_proto,
const struct transport_protocol *out_proto, int must_recrypt);
int media_packet_encrypt(rewrite_func encrypt_func, struct packet_stream *out, struct media_packet *mp);
const struct transport_protocol *transport_protocol(const str *s);
/* XXX shouldn't be necessary */
/*


Loading…
Cancel
Save