replace implicit bit fields with explicit ones

pull/6/head
Richard Fuchs 11 years ago
parent d025f4b69f
commit f638f36bb0

@ -16,6 +16,7 @@
#include <sys/resource.h> #include <sys/resource.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
@ -360,4 +361,34 @@ static inline int is_addr_unspecified(const struct in6_addr *a) {
return 0; return 0;
} }
/* checks if at least one of the flags is set */
static inline int bf_isset(const unsigned int *u, unsigned int f) {
if ((*u & f))
return -1;
return 0;
}
static inline void bf_set(unsigned int *u, unsigned int f) {
*u |= f;
}
static inline void bf_clear(unsigned int *u, unsigned int f) {
*u &= ~f;
}
static inline void bf_xset(unsigned int *u, unsigned int f, int cond) {
bf_clear(u, f);
bf_set(u, cond ? f : 0);
}
/* works only for single flags */
static inline void bf_copy(unsigned int *u, unsigned int f, const unsigned int *s, unsigned int g) {
/* a good compiler will optimize out the calls to log2() */
*u &= ~f;
if (f >= g)
*u |= (*s & g) << (int) (log2(f) - log2(g));
else
*u |= (*s & g) >> (int) (log2(g) - log2(f));
}
/* works for multiple flags */
static inline void bf_copy_same(unsigned int *u, const unsigned int *s, unsigned int g) {
bf_copy(u, g, s, g);
}
#endif #endif

@ -299,11 +299,11 @@ void kernelize(struct packet_stream *stream) {
struct callmaster *cm = call->callmaster; struct callmaster *cm = call->callmaster;
struct packet_stream *sink = NULL; struct packet_stream *sink = NULL;
if (stream->kernelized) if (PS_ISSET(stream, KERNELIZED))
return; return;
if (cm->conf.kernelfd < 0 || cm->conf.kernelid == -1) if (cm->conf.kernelfd < 0 || cm->conf.kernelid == -1)
goto no_kernel; goto no_kernel;
if (!stream->rtp) if (!PS_ISSET(stream, RTP))
goto no_kernel; goto no_kernel;
if (!stream->sfd) if (!stream->sfd)
goto no_kernel; goto no_kernel;
@ -334,8 +334,8 @@ void kernelize(struct packet_stream *stream) {
mpt.tos = cm->conf.tos; mpt.tos = cm->conf.tos;
mpt.src_addr.port = sink->sfd->fd.localport; mpt.src_addr.port = sink->sfd->fd.localport;
mpt.dst_addr.port = sink->endpoint.port; mpt.dst_addr.port = sink->endpoint.port;
mpt.rtcp_mux = stream->media->rtcp_mux; mpt.rtcp_mux = MEDIA_ISSET(stream->media, RTCP_MUX);
mpt.dtls = stream->media->dtls; mpt.dtls = MEDIA_ISSET(stream->media, DTLS);
if (IN6_IS_ADDR_V4MAPPED(&sink->endpoint.ip46)) { if (IN6_IS_ADDR_V4MAPPED(&sink->endpoint.ip46)) {
mpt.src_addr.family = AF_INET; mpt.src_addr.family = AF_INET;
@ -363,13 +363,13 @@ void kernelize(struct packet_stream *stream) {
ZERO(stream->kernel_stats); ZERO(stream->kernel_stats);
kernel_add_stream(cm->conf.kernelfd, &mpt, 0); kernel_add_stream(cm->conf.kernelfd, &mpt, 0);
stream->kernelized = 1; PS_SET(stream, KERNELIZED);
return; return;
no_kernel: no_kernel:
stream->kernelized = 1; PS_SET(stream, KERNELIZED);
stream->no_kernel_support = 1; PS_SET(stream, NO_KERNEL_SUPPORT);
} }
@ -377,7 +377,7 @@ no_kernel:
/* returns: 0 = not a muxed stream, 1 = muxed, RTP, 2 = muxed, RTCP */ /* returns: 0 = not a muxed stream, 1 = muxed, RTP, 2 = muxed, RTCP */
static int rtcp_demux(str *s, struct call_media *media) { static int rtcp_demux(str *s, struct call_media *media) {
if (!media->rtcp_mux) if (!MEDIA_ISSET(media, RTCP_MUX))
return 0; return 0;
return rtcp_demux_is_rtcp(s) ? 2 : 1; return rtcp_demux_is_rtcp(s) ? 2 : 1;
} }
@ -439,7 +439,7 @@ static void determine_handler(struct packet_stream *in, const struct packet_stre
const struct streamhandler **sh_pp, *sh; const struct streamhandler **sh_pp, *sh;
const struct streamhandler ***matrix; const struct streamhandler ***matrix;
if (in->has_handler) if (PS_ISSET(in, HAS_HANDLER))
return; return;
if (!in->media->protocol) if (!in->media->protocol)
@ -448,7 +448,7 @@ static void determine_handler(struct packet_stream *in, const struct packet_stre
goto err; goto err;
matrix = __sh_matrix; matrix = __sh_matrix;
if (in->media->dtls && out->media->dtls) if (MEDIA_ISSET(in->media, DTLS) && MEDIA_ISSET(out->media, DTLS))
matrix = __sh_matrix_dtls; matrix = __sh_matrix_dtls;
sh_pp = matrix[in->media->protocol->index]; sh_pp = matrix[in->media->protocol->index];
@ -460,7 +460,7 @@ static void determine_handler(struct packet_stream *in, const struct packet_stre
in->handler = sh; in->handler = sh;
done: done:
in->has_handler = 1; PS_SET(in, HAS_HANDLER);
return; return;
err: err:
@ -534,13 +534,13 @@ static int stream_packet(struct stream_fd *sfd, str *s, struct sockaddr_in6 *fsi
if (!stream->sfd) if (!stream->sfd)
goto done; goto done;
if (media->dtls && is_dtls(s)) { if (MEDIA_ISSET(media, DTLS) && is_dtls(s)) {
ret = dtls(stream, s, fsin); ret = dtls(stream, s, fsin);
if (!ret) if (!ret)
goto done; goto done;
} }
if (stream->stun && is_stun(s)) { if (PS_ISSET(stream, STUN) && is_stun(s)) {
stun_ret = stun(s, stream, fsin); stun_ret = stun(s, stream, fsin);
if (!stun_ret) if (!stun_ret)
goto done; goto done;
@ -554,7 +554,7 @@ static int stream_packet(struct stream_fd *sfd, str *s, struct sockaddr_in6 *fsi
in_srtp = stream; in_srtp = stream;
sink = stream->rtp_sink; sink = stream->rtp_sink;
if (!sink && stream->rtcp) { if (!sink && PS_ISSET(stream, RTCP)) {
sink = stream->rtcp_sink; sink = stream->rtcp_sink;
rtcp = 1; rtcp = 1;
} }
@ -612,13 +612,13 @@ static int stream_packet(struct stream_fd *sfd, str *s, struct sockaddr_in6 *fsi
mutex_lock(&stream->in_lock); mutex_lock(&stream->in_lock);
use_cand: use_cand:
if (!stream->filled) if (!PS_ISSET(stream, FILLED))
goto forward; goto forward;
if (media->asymmetric) if (MEDIA_ISSET(media, ASYMMETRIC))
stream->confirmed = 1; PS_SET(stream, CONFIRMED);
if (stream->confirmed) if (PS_ISSET(stream, CONFIRMED))
goto kernel_check; goto kernel_check;
if (!call->last_signal || poller_now <= call->last_signal + 3) if (!call->last_signal || poller_now <= call->last_signal + 3)
@ -627,7 +627,7 @@ use_cand:
ilog(LOG_DEBUG, "Confirmed peer information for port %u - %s", ilog(LOG_DEBUG, "Confirmed peer information for port %u - %s",
sfd->fd.localport, addr); sfd->fd.localport, addr);
stream->confirmed = 1; PS_SET(stream, CONFIRMED);
update = 1; update = 1;
peerinfo: peerinfo:
@ -651,10 +651,10 @@ peerinfo:
mutex_unlock(&stream->out_lock); mutex_unlock(&stream->out_lock);
kernel_check: kernel_check:
if (stream->no_kernel_support) if (PS_ISSET(stream, NO_KERNEL_SUPPORT))
goto forward; goto forward;
if (stream->confirmed && sink && sink->confirmed && sink->filled) if (PS_ISSET(stream, CONFIRMED) && sink && PS_ISSET(sink, CONFIRMED) && PS_ISSET(sink, FILLED))
kernelize(stream); kernelize(stream);
forward: forward:
@ -820,7 +820,7 @@ static void call_timer_iterator(void *key, void *val, void *ptr) {
if (!sfd || !ps->media) if (!sfd || !ps->media)
goto next; goto next;
if (ps->media->dtls && sfd->dtls.init && !sfd->dtls.connected) if (MEDIA_ISSET(ps->media, DTLS) && sfd->dtls.init && !sfd->dtls.connected)
dtls(ps, NULL, NULL); dtls(ps, NULL, NULL);
if (hlp->ports[sfd->fd.localport]) if (hlp->ports[sfd->fd.localport])
@ -832,7 +832,7 @@ static void call_timer_iterator(void *key, void *val, void *ptr) {
goto next; goto next;
check = cm->conf.timeout; check = cm->conf.timeout;
if (!ps->media->recv || !ps->sfd) if (!MEDIA_ISSET(ps->media, RECV) || !ps->sfd)
check = cm->conf.silent_timeout; check = cm->conf.silent_timeout;
if (poller_now - ps->last_packet < check) if (poller_now - ps->last_packet < check)
@ -1441,7 +1441,7 @@ static void __fill_stream(struct packet_stream *ps, const struct endpoint *ep, u
if (memcmp(&ps->advertised_endpoint, &ps->endpoint, sizeof(ps->endpoint))) if (memcmp(&ps->advertised_endpoint, &ps->endpoint, sizeof(ps->endpoint)))
crypto_reset(&ps->crypto); crypto_reset(&ps->crypto);
ps->advertised_endpoint = ps->endpoint; ps->advertised_endpoint = ps->endpoint;
ps->filled = 1; PS_SET(ps, FILLED);
} }
static int __init_stream(struct packet_stream *ps) { static int __init_stream(struct packet_stream *ps) {
@ -1450,21 +1450,23 @@ static int __init_stream(struct packet_stream *ps) {
int active; int active;
if (ps->sfd) { if (ps->sfd) {
if (media->sdes) if (MEDIA_ISSET(media, SDES))
crypto_init(&ps->sfd->crypto, &media->sdes_in.params); crypto_init(&ps->sfd->crypto, &media->sdes_in.params);
if (media->dtls && !ps->fallback_rtcp) { if (MEDIA_ISSET(media, DTLS) && !PS_ISSET(ps, FALLBACK_RTCP)) {
active = (ps->filled && media->setup_active); active = (PS_ISSET(ps, FILLED) && MEDIA_ISSET(media, SETUP_ACTIVE));
dtls_connection_init(ps, active, call->dtls_cert); dtls_connection_init(ps, active, call->dtls_cert);
if (!ps->fingerprint_verified && media->fingerprint.hash_func && ps->dtls_cert) { if (!PS_ISSET(ps, FINGERPRINT_VERIFIED) && media->fingerprint.hash_func
&& ps->dtls_cert)
{
if (dtls_verify_cert(ps)) if (dtls_verify_cert(ps))
return -1; return -1;
} }
} }
} }
if (media->sdes) if (MEDIA_ISSET(media, SDES))
crypto_init(&ps->crypto, &media->sdes_out.params); crypto_init(&ps->crypto, &media->sdes_out.params);
return 0; return 0;
@ -1485,7 +1487,7 @@ static int __init_streams(struct call_media *A, struct call_media *B, const stru
/* RTP */ /* RTP */
a->rtp_sink = b; a->rtp_sink = b;
a->rtp = 1; PS_SET(a, RTP);
if (sp) if (sp)
__fill_stream(a, &sp->rtp_endpoint, port_off); __fill_stream(a, &sp->rtp_endpoint, port_off);
@ -1493,20 +1495,20 @@ static int __init_streams(struct call_media *A, struct call_media *B, const stru
return -1; return -1;
/* RTCP */ /* RTCP */
if (!B->rtcp_mux) { if (!MEDIA_ISSET(B, RTCP_MUX)) {
lb = lb->next; lb = lb->next;
assert(lb != NULL); assert(lb != NULL);
b = lb->data; b = lb->data;
} }
if (!A->rtcp_mux) { if (!MEDIA_ISSET(A, RTCP_MUX)) {
a->rtcp_sink = NULL; a->rtcp_sink = NULL;
a->rtcp = 0; PS_CLEAR(a, RTCP);
} }
else { else {
a->rtcp_sink = b; a->rtcp_sink = b;
a->rtcp = 1; PS_SET(a, RTCP);
a->implicit_rtcp = 0; PS_CLEAR(a, IMPLICIT_RTCP);
} }
ax = a; ax = a;
@ -1519,21 +1521,21 @@ static int __init_streams(struct call_media *A, struct call_media *B, const stru
a->rtp_sink = NULL; a->rtp_sink = NULL;
a->rtcp_sink = b; a->rtcp_sink = b;
a->rtp = 0; PS_CLEAR(a, RTP);
a->rtcp = 1; PS_SET(a, RTCP);
a->rtcp_sibling = NULL; a->rtcp_sibling = NULL;
a->fallback_rtcp = ax->rtcp; bf_copy(&a->ps_flags, PS_FLAG_FALLBACK_RTCP, &ax->ps_flags, PS_FLAG_RTCP);
ax->rtcp_sibling = a; ax->rtcp_sibling = a;
if (sp) { if (sp) {
if (!sp->implicit_rtcp) { if (!SP_ISSET(sp, IMPLICIT_RTCP)) {
__fill_stream(a, &sp->rtcp_endpoint, port_off); __fill_stream(a, &sp->rtcp_endpoint, port_off);
a->implicit_rtcp = 0; PS_CLEAR(a, IMPLICIT_RTCP);
} }
else { else {
__fill_stream(a, &sp->rtp_endpoint, port_off + 1); __fill_stream(a, &sp->rtp_endpoint, port_off + 1);
a->implicit_rtcp = 1; PS_SET(a, IMPLICIT_RTCP);
} }
} }
if (__init_stream(a)) if (__init_stream(a))
@ -1560,31 +1562,31 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi
if (!this->protocol || !this->protocol->srtp) { if (!this->protocol || !this->protocol->srtp) {
cp->crypto_suite = NULL; cp->crypto_suite = NULL;
this->dtls = 0; MEDIA_CLEAR(this, DTLS);
this->sdes = 0; MEDIA_CLEAR(this, SDES);
this->setup_passive = 0; MEDIA_CLEAR(this, SETUP_PASSIVE);
this->setup_active = 0; MEDIA_CLEAR(this, SETUP_ACTIVE);
return; return;
} }
if (flags->opmode == OP_OFFER) { if (flags->opmode == OP_OFFER) {
/* we use this to remember the peer's preference DTLS vs SDES */ /* we use this to remember the peer's preference DTLS vs SDES */
if (!this->initialized) { if (!MEDIA_ISSET(this, INITIALIZED)) {
this->dtls = 1; MEDIA_SET(this, DTLS);
this->sdes = 1; MEDIA_SET(this, SDES);
} }
/* we always offer actpass */ /* we always offer actpass */
this->setup_passive = 1; MEDIA_SET(this, SETUP_PASSIVE);
this->setup_active = 1; MEDIA_SET(this, SETUP_ACTIVE);
} }
else { else {
/* if we can be active, we will, otherwise we'll be passive */ /* if we can be active, we will, otherwise we'll be passive */
if (this->setup_active) if (MEDIA_ISSET(this, SETUP_ACTIVE))
this->setup_passive = 0; MEDIA_CLEAR(this, SETUP_PASSIVE);
/* if we're answering and doing DTLS, then skip the SDES stuff */ /* if we're answering and doing DTLS, then skip the SDES stuff */
if (this->dtls) { if (MEDIA_ISSET(this, DTLS)) {
this->sdes = 0; MEDIA_CLEAR(this, SDES);
goto skip_sdes; goto skip_sdes;
} }
} }
@ -1636,8 +1638,8 @@ static void __rtcp_mux_logic(const struct sdp_ng_flags *flags, struct call_media
if (flags->opmode == OP_ANSWER) { if (flags->opmode == OP_ANSWER) {
/* default is to go with the client's choice, unless we were instructed not /* default is to go with the client's choice, unless we were instructed not
* to do that in the offer (see below) */ * to do that in the offer (see below) */
if (!media->rtcp_mux_override) if (!MEDIA_ISSET(media, RTCP_MUX_OVERRIDE))
media->rtcp_mux = other_media->rtcp_mux; bf_copy_same(&media->media_flags, &other_media->media_flags, MEDIA_FLAG_RTCP_MUX);
return; return;
} }
@ -1648,27 +1650,27 @@ static void __rtcp_mux_logic(const struct sdp_ng_flags *flags, struct call_media
/* default is to pass through the client's choice, unless our peer is already /* default is to pass through the client's choice, unless our peer is already
* talking rtcp-mux, then we stick to that */ * talking rtcp-mux, then we stick to that */
if (!media->rtcp_mux) if (!MEDIA_ISSET(media, RTCP_MUX))
media->rtcp_mux = other_media->rtcp_mux; bf_copy_same(&media->media_flags, &other_media->media_flags, MEDIA_FLAG_RTCP_MUX);
/* in our offer, we can override the client's choice */ /* in our offer, we can override the client's choice */
if (flags->rtcp_mux_offer) if (flags->rtcp_mux_offer)
media->rtcp_mux = 1; MEDIA_SET(media, RTCP_MUX);
else if (flags->rtcp_mux_demux) else if (flags->rtcp_mux_demux)
media->rtcp_mux = 0; MEDIA_CLEAR(media, RTCP_MUX);
/* we can also control what's going to happen in the answer. it /* we can also control what's going to happen in the answer. it
* depends on what was offered, but by default we go with the other * depends on what was offered, but by default we go with the other
* client's choice */ * client's choice */
other_media->rtcp_mux_override = 0; MEDIA_CLEAR(other_media, RTCP_MUX_OVERRIDE);
if (other_media->rtcp_mux) { if (MEDIA_ISSET(other_media, RTCP_MUX)) {
if (!media->rtcp_mux) { if (!MEDIA_ISSET(media, RTCP_MUX)) {
/* rtcp-mux was offered, but we don't offer it ourselves. /* rtcp-mux was offered, but we don't offer it ourselves.
* the answer will not accept rtcp-mux (wasn't offered). * the answer will not accept rtcp-mux (wasn't offered).
* the default is to accept the offer, unless we want to * the default is to accept the offer, unless we want to
* explicitly reject it. */ * explicitly reject it. */
other_media->rtcp_mux_override = 1; MEDIA_SET(other_media, RTCP_MUX_OVERRIDE);
if (flags->rtcp_mux_reject) if (flags->rtcp_mux_reject)
other_media->rtcp_mux = 0; MEDIA_CLEAR(other_media, RTCP_MUX);
} }
else { else {
/* rtcp-mux was offered and we offer it too. default is /* rtcp-mux was offered and we offer it too. default is
@ -1676,17 +1678,17 @@ static void __rtcp_mux_logic(const struct sdp_ng_flags *flags, struct call_media
* either explicitly accept it (possibly demux) or reject * either explicitly accept it (possibly demux) or reject
* it (possible reverse demux). */ * it (possible reverse demux). */
if (flags->rtcp_mux_accept) if (flags->rtcp_mux_accept)
other_media->rtcp_mux_override = 1; MEDIA_SET(other_media, RTCP_MUX_OVERRIDE);
else if (flags->rtcp_mux_reject) { else if (flags->rtcp_mux_reject) {
other_media->rtcp_mux_override = 1; MEDIA_SET(other_media, RTCP_MUX_OVERRIDE);
other_media->rtcp_mux = 0; MEDIA_CLEAR(other_media, RTCP_MUX);
} }
} }
} }
else { else {
/* rtcp-mux was not offered. we may offer it, but since it wasn't /* rtcp-mux was not offered. we may offer it, but since it wasn't
* offered to us, we must not accept it. */ * offered to us, we must not accept it. */
other_media->rtcp_mux_override = 1; MEDIA_SET(other_media, RTCP_MUX_OVERRIDE);
} }
} }
@ -1696,7 +1698,7 @@ static void __unverify_fingerprint(struct call_media *m) {
for (l = m->streams.head; l; l = l->next) { for (l = m->streams.head; l; l = l->next) {
ps = l->data; ps = l->data;
ps->fingerprint_verified = 0; PS_CLEAR(ps, FINGERPRINT_VERIFIED);
} }
} }
@ -1745,24 +1747,28 @@ int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams,
media->protocol = other_media->protocol; media->protocol = other_media->protocol;
/* copy parameters advertised by the sender of this message */ /* copy parameters advertised by the sender of this message */
other_media->rtcp_mux = sp->rtcp_mux; bf_copy_same(&other_media->media_flags, &sp->sp_flags,
SP_FLAG_RTCP_MUX | SP_FLAG_ASYMMETRIC);
crypto_params_copy(&other_media->sdes_in.params, &sp->crypto); crypto_params_copy(&other_media->sdes_in.params, &sp->crypto);
other_media->sdes_in.tag = sp->sdes_tag; other_media->sdes_in.tag = sp->sdes_tag;
other_media->asymmetric = sp->asymmetric;
other_media->recv = media->send = sp->send; bf_copy_same(&media->media_flags, &sp->sp_flags,
other_media->send = media->recv = sp->recv; SP_FLAG_SEND | SP_FLAG_RECV);
bf_copy(&other_media->media_flags, MEDIA_FLAG_RECV, &sp->sp_flags, SP_FLAG_SEND);
bf_copy(&other_media->media_flags, MEDIA_FLAG_SEND, &sp->sp_flags, SP_FLAG_RECV);
other_media->setup_passive = sp->setup_active; bf_copy(&other_media->media_flags, MEDIA_FLAG_SETUP_PASSIVE,
other_media->setup_active = sp->setup_passive; &sp->sp_flags, SP_FLAG_SETUP_ACTIVE);
bf_copy(&other_media->media_flags, MEDIA_FLAG_SETUP_ACTIVE,
&sp->sp_flags, SP_FLAG_SETUP_PASSIVE);
if (memcmp(&other_media->fingerprint, &sp->fingerprint, sizeof(sp->fingerprint))) { if (memcmp(&other_media->fingerprint, &sp->fingerprint, sizeof(sp->fingerprint))) {
__unverify_fingerprint(other_media); __unverify_fingerprint(other_media);
other_media->fingerprint = sp->fingerprint; other_media->fingerprint = sp->fingerprint;
} }
other_media->dtls = 0; MEDIA_CLEAR(other_media, DTLS);
if ((other_media->setup_passive || other_media->setup_active) if ((MEDIA_ISSET(other_media, SETUP_PASSIVE) || MEDIA_ISSET(other_media, SETUP_ACTIVE))
&& other_media->fingerprint.hash_func) && other_media->fingerprint.hash_func)
other_media->dtls = 1; MEDIA_SET(other_media, DTLS);
/* control rtcp-mux */ /* control rtcp-mux */
__rtcp_mux_logic(flags, media, other_media); __rtcp_mux_logic(flags, media, other_media);
@ -1784,7 +1790,7 @@ int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams,
/* mark initial offer/answer as done */ /* mark initial offer/answer as done */
media->initialized = 1; MEDIA_SET(media, INITIALIZED);
/* determine number of consecutive ports needed locally. /* determine number of consecutive ports needed locally.
@ -1837,14 +1843,14 @@ error:
/* must be called with in_lock held or call->master_lock held in W */ /* must be called with in_lock held or call->master_lock held in W */
static void unkernelize(struct packet_stream *p) { static void unkernelize(struct packet_stream *p) {
if (!p->kernelized) if (!PS_ISSET(p, KERNELIZED))
return; return;
if (p->no_kernel_support) if (PS_ISSET(p, NO_KERNEL_SUPPORT))
return; return;
kernel_del_stream(p->call->callmaster->conf.kernelfd, p->sfd->fd.localport); kernel_del_stream(p->call->callmaster->conf.kernelfd, p->sfd->fd.localport);
p->kernelized = 0; PS_CLEAR(p, KERNELIZED);
} }
/* called lock-free, but must hold a reference to the call */ /* called lock-free, but must hold a reference to the call */
@ -1892,7 +1898,7 @@ static void call_destroy(struct call *c) {
for (o = md->streams.head; o; o = o->next) { for (o = md->streams.head; o; o = o->next) {
ps = o->data; ps = o->data;
if (ps->fallback_rtcp) if (PS_ISSET(ps, FALLBACK_RTCP))
continue; continue;
smart_ntop_p(buf, &ps->endpoint.ip46, sizeof(buf)); smart_ntop_p(buf, &ps->endpoint.ip46, sizeof(buf));
@ -1901,7 +1907,7 @@ static void call_destroy(struct call *c) {
md->index, md->index,
(unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0), (unsigned int) (ps->sfd ? ps->sfd->fd.localport : 0),
buf, ps->endpoint.port, buf, ps->endpoint.port,
(!ps->rtp && ps->rtcp) ? " (RTCP)" : "", (!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) ? " (RTCP)" : "",
ps->stats.packets, ps->stats.packets,
ps->stats.bytes, ps->stats.bytes,
ps->stats.errors); ps->stats.errors);
@ -2184,8 +2190,8 @@ static void __monologue_tag(struct call_monologue *ml, const str *tag) {
static void __stream_unkernelize(struct packet_stream *ps) { static void __stream_unkernelize(struct packet_stream *ps) {
unkernelize(ps); unkernelize(ps);
ps->confirmed = 0; PS_CLEAR(ps, CONFIRMED);
ps->has_handler = 0; PS_CLEAR(ps, HAS_HANDLER);
} }
/* must be called with call->master_lock held in W */ /* must be called with call->master_lock held in W */

@ -67,6 +67,55 @@ struct call_monologue;
/* struct stream_params */
#define SP_FLAG_NO_RTCP 0x00000001
#define SP_FLAG_IMPLICIT_RTCP 0x00000002
#define SP_FLAG_RTCP_MUX 0x00000004
#define SP_FLAG_SEND 0x00000008
#define SP_FLAG_RECV 0x00000010
#define SP_FLAG_ASYMMETRIC 0x00000020
#define SP_FLAG_SETUP_ACTIVE 0x00000040
#define SP_FLAG_SETUP_PASSIVE 0x00000080
/* struct packet_stream */
#define PS_FLAG_RTP 0x00000100
#define PS_FLAG_RTCP 0x00000200
#define PS_FLAG_IMPLICIT_RTCP SP_FLAG_IMPLICIT_RTCP
#define PS_FLAG_FALLBACK_RTCP 0x00000400
#define PS_FLAG_STUN 0x00000800
#define PS_FLAG_FILLED 0x00001000
#define PS_FLAG_CONFIRMED 0x00002000
#define PS_FLAG_KERNELIZED 0x00004000
#define PS_FLAG_NO_KERNEL_SUPPORT 0x00008000
#define PS_FLAG_HAS_HANDLER 0x00010000
#define PS_FLAG_FINGERPRINT_VERIFIED 0x00020000
/* struct call_media */
#define MEDIA_FLAG_INITIALIZED 0x00040000
#define MEDIA_FLAG_ASYMMETRIC SP_FLAG_ASYMMETRIC
#define MEDIA_FLAG_SEND SP_FLAG_SEND
#define MEDIA_FLAG_RECV SP_FLAG_RECV
#define MEDIA_FLAG_RTCP_MUX SP_FLAG_RTCP_MUX
#define MEDIA_FLAG_RTCP_MUX_OVERRIDE 0x00080000
#define MEDIA_FLAG_DTLS 0x00100000
#define MEDIA_FLAG_SDES 0x00200000
#define MEDIA_FLAG_SETUP_ACTIVE SP_FLAG_SETUP_ACTIVE
#define MEDIA_FLAG_SETUP_PASSIVE SP_FLAG_SETUP_PASSIVE
/* access macros */
#define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f)
#define SP_SET(p, f) bf_set(&(p)->sp_flags, SP_FLAG_ ## f)
#define SP_CLEAR(p, f) bf_clear(&(p)->sp_flags, SP_FLAG_ ## f)
#define PS_ISSET(p, f) bf_isset(&(p)->ps_flags, PS_FLAG_ ## f)
#define PS_SET(p, f) bf_set(&(p)->ps_flags, PS_FLAG_ ## f)
#define PS_CLEAR(p, f) bf_clear(&(p)->ps_flags, PS_FLAG_ ## f)
#define MEDIA_ISSET(p, f) bf_isset(&(p)->media_flags, MEDIA_FLAG_ ## f)
#define MEDIA_SET(p, f) bf_set(&(p)->media_flags, MEDIA_FLAG_ ## f)
#define MEDIA_CLEAR(p, f) bf_clear(&(p)->media_flags, MEDIA_FLAG_ ## f)
struct poller; struct poller;
struct control_stream; struct control_stream;
struct call; struct call;
@ -122,15 +171,7 @@ struct stream_params {
enum stream_direction direction[2]; enum stream_direction direction[2];
int desired_family; int desired_family;
struct dtls_fingerprint fingerprint; struct dtls_fingerprint fingerprint;
unsigned int sp_flags;
int no_rtcp:1;
int implicit_rtcp:1;
int rtcp_mux:1;
int send:1;
int recv:1;
int asymmetric:1;
int setup_active:1;
int setup_passive:1;
}; };
struct stream_fd { struct stream_fd {
@ -175,17 +216,7 @@ struct packet_stream {
/* in_lock must be held for SETTING these: */ /* in_lock must be held for SETTING these: */
/* (XXX replace with atomic ops where appropriate) */ /* (XXX replace with atomic ops where appropriate) */
int rtp:1; unsigned int ps_flags;
int rtcp:1;
int implicit_rtcp:1;
int fallback_rtcp:1;
int stun:1;
int filled:1;
int confirmed:1;
int kernelized:1;
int no_kernel_support:1;
int has_handler:1;
int fingerprint_verified:1;
}; };
/* protected by call->master_lock, except the RO elements */ /* protected by call->master_lock, except the RO elements */
@ -211,16 +242,7 @@ struct call_media {
GQueue streams; /* normally RTP + RTCP */ GQueue streams; /* normally RTP + RTCP */
GSList *endpoint_maps; GSList *endpoint_maps;
int initialized:1; unsigned int media_flags;
int asymmetric:1;
int send:1;
int recv:1;
int rtcp_mux:1;
int rtcp_mux_override:1;
int dtls:1;
int sdes:1;
int setup_active:1;
int setup_passive:1;
}; };
/* half a dialogue */ /* half a dialogue */

@ -337,7 +337,7 @@ static int verify_callback(int ok, X509_STORE_CTX *store) {
ps = sfd->stream; ps = sfd->stream;
if (!ps) if (!ps)
return 0; return 0;
if (ps->fingerprint_verified) if (PS_ISSET(ps, FINGERPRINT_VERIFIED))
return 1; return 1;
media = ps->media; media = ps->media;
if (!media) if (!media)
@ -377,7 +377,7 @@ int dtls_verify_cert(struct packet_stream *ps) {
return -1; return -1;
} }
ps->fingerprint_verified = 1; PS_SET(ps, FINGERPRINT_VERIFIED);
ilog(LOG_INFO, "DTLS: Peer certificate accepted"); ilog(LOG_INFO, "DTLS: Peer certificate accepted");
return 0; return 0;
@ -594,7 +594,7 @@ int dtls(struct packet_stream *ps, const str *s, struct sockaddr_in6 *fsin) {
if (s) { if (s) {
BIO_write(d->r_bio, s->s, s->len); BIO_write(d->r_bio, s->s, s->len);
/* we understand this as preference of DTLS over SDES */ /* we understand this as preference of DTLS over SDES */
ps->media->sdes = 0; MEDIA_CLEAR(ps->media, SDES);
} }
ret = try_connect(d); ret = try_connect(d);
@ -610,7 +610,9 @@ int dtls(struct packet_stream *ps, const str *s, struct sockaddr_in6 *fsin) {
/* connected! */ /* connected! */
if (dtls_setup_crypto(ps, d)) if (dtls_setup_crypto(ps, d))
/* XXX ?? */ ; /* XXX ?? */ ;
if (ps->rtp && ps->rtcp && ps->rtcp_sibling && ps->media->rtcp_mux) { if (PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP) && ps->rtcp_sibling
&& MEDIA_ISSET(ps->media, RTCP_MUX))
{
if (dtls_setup_crypto(ps->rtcp_sibling, d)) if (dtls_setup_crypto(ps->rtcp_sibling, d))
/* XXX ?? */ ; /* XXX ?? */ ;
} }

@ -978,7 +978,7 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *fl
sp->type = media->media_type; sp->type = media->media_type;
memcpy(sp->direction, flags->directions, sizeof(sp->direction)); memcpy(sp->direction, flags->directions, sizeof(sp->direction));
sp->desired_family = flags->address_family; sp->desired_family = flags->address_family;
sp->asymmetric = flags->asymmetric; bf_xset(&sp->sp_flags, SP_FLAG_ASYMMETRIC, flags->asymmetric);
/* a=crypto */ /* a=crypto */
attr = attr_get_by_id(&media->attributes, ATTR_CRYPTO); attr = attr_get_by_id(&media->attributes, ATTR_CRYPTO);
@ -999,16 +999,16 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *fl
} }
/* a=sendrecv/sendonly/recvonly/inactive */ /* a=sendrecv/sendonly/recvonly/inactive */
sp->send = 1; SP_SET(sp, SEND);
sp->recv = 1; SP_SET(sp, RECV);
if (attr_get_by_id_m_s(media, ATTR_RECVONLY)) if (attr_get_by_id_m_s(media, ATTR_RECVONLY))
sp->send = 0; SP_CLEAR(sp, SEND);
else if (attr_get_by_id_m_s(media, ATTR_SENDONLY)) else if (attr_get_by_id_m_s(media, ATTR_SENDONLY))
sp->recv = 0; SP_CLEAR(sp, RECV);
else if (attr_get_by_id_m_s(media, ATTR_INACTIVE)) else if (attr_get_by_id_m_s(media, ATTR_INACTIVE))
{ {
sp->recv = 0; SP_CLEAR(sp, RECV);
sp->send = 0; SP_CLEAR(sp, SEND);
} }
/* a=setup */ /* a=setup */
@ -1016,10 +1016,10 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *fl
if (attr) { if (attr) {
if (attr->u.setup.value == SETUP_ACTPASS if (attr->u.setup.value == SETUP_ACTPASS
|| attr->u.setup.value == SETUP_ACTIVE) || attr->u.setup.value == SETUP_ACTIVE)
sp->setup_active = 1; SP_SET(sp, SETUP_ACTIVE);
if (attr->u.setup.value == SETUP_ACTPASS if (attr->u.setup.value == SETUP_ACTPASS
|| attr->u.setup.value == SETUP_PASSIVE) || attr->u.setup.value == SETUP_PASSIVE)
sp->setup_passive = 1; SP_SET(sp, SETUP_PASSIVE);
} }
/* a=fingerprint */ /* a=fingerprint */
@ -1033,7 +1033,7 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *fl
/* determine RTCP endpoint */ /* determine RTCP endpoint */
if (attr_get_by_id(&media->attributes, ATTR_RTCP_MUX)) { if (attr_get_by_id(&media->attributes, ATTR_RTCP_MUX)) {
sp->rtcp_mux = 1; SP_SET(sp, RTCP_MUX);
goto next; goto next;
} }
@ -1042,11 +1042,11 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *fl
attr = attr_get_by_id(&media->attributes, ATTR_RTCP); attr = attr_get_by_id(&media->attributes, ATTR_RTCP);
if (!attr) { if (!attr) {
sp->implicit_rtcp = 1; SP_SET(sp, IMPLICIT_RTCP);
goto next; goto next;
} }
if (attr->u.rtcp.port_num == sp->rtp_endpoint.port) { if (attr->u.rtcp.port_num == sp->rtp_endpoint.port) {
sp->rtcp_mux = 1; SP_SET(sp, RTCP_MUX);
goto next; goto next;
} }
errstr = "Invalid RTCP attribute"; errstr = "Invalid RTCP attribute";
@ -1498,7 +1498,7 @@ static void insert_dtls(struct call_media *media, struct sdp_chopper *chop) {
const char *actpass; const char *actpass;
struct call *call = media->call; struct call *call = media->call;
if (!call->dtls_cert || !media->dtls) if (!call->dtls_cert || !MEDIA_ISSET(media, DTLS))
return; return;
hf = call->dtls_cert->fingerprint.hash_func; hf = call->dtls_cert->fingerprint.hash_func;
@ -1512,13 +1512,13 @@ static void insert_dtls(struct call_media *media, struct sdp_chopper *chop) {
*(--o) = '\0'; *(--o) = '\0';
actpass = "holdconn"; actpass = "holdconn";
if (media->setup_passive) { if (MEDIA_ISSET(media, SETUP_PASSIVE)) {
if (media->setup_active) if (MEDIA_ISSET(media, SETUP_ACTIVE))
actpass = "actpass"; actpass = "actpass";
else else
actpass = "passive"; actpass = "passive";
} }
else if (media->setup_active) else if (MEDIA_ISSET(media, SETUP_ACTIVE))
actpass = "active"; actpass = "active";
chopper_append_c(chop, "a=setup:"); chopper_append_c(chop, "a=setup:");
@ -1537,7 +1537,7 @@ static void insert_crypto(struct call_media *media, struct sdp_chopper *chop) {
struct crypto_params *cp = &media->sdes_out.params; struct crypto_params *cp = &media->sdes_out.params;
unsigned long long ull; unsigned long long ull;
if (!cp->crypto_suite || !media->sdes) if (!cp->crypto_suite || !MEDIA_ISSET(media, SDES))
return; return;
p = b64_buf; p = b64_buf;
@ -1668,16 +1668,16 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu
goto next; goto next;
} }
if (call_media->send && call_media->recv) if (MEDIA_ISSET(call_media, SEND) && MEDIA_ISSET(call_media, RECV))
chopper_append_c(chop, "a=sendrecv\r\n"); chopper_append_c(chop, "a=sendrecv\r\n");
else if (call_media->send && !call_media->recv) else if (MEDIA_ISSET(call_media, SEND) && !MEDIA_ISSET(call_media, RECV))
chopper_append_c(chop, "a=sendonly\r\n"); chopper_append_c(chop, "a=sendonly\r\n");
else if (!call_media->send && call_media->recv) else if (!MEDIA_ISSET(call_media, SEND) && MEDIA_ISSET(call_media, RECV))
chopper_append_c(chop, "a=recvonly\r\n"); chopper_append_c(chop, "a=recvonly\r\n");
else else
chopper_append_c(chop, "a=inactive\r\n"); chopper_append_c(chop, "a=inactive\r\n");
if (call_media->rtcp_mux && flags->opmode == OP_ANSWER) { if (MEDIA_ISSET(call_media, RTCP_MUX) && flags->opmode == OP_ANSWER) {
chopper_append_c(chop, "a=rtcp:"); chopper_append_c(chop, "a=rtcp:");
chopper_append_printf(chop, "%hu", ps->sfd->fd.localport); chopper_append_printf(chop, "%hu", ps->sfd->fd.localport);
chopper_append_c(chop, "\r\na=rtcp-mux\r\n"); chopper_append_c(chop, "\r\na=rtcp-mux\r\n");
@ -1686,7 +1686,7 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu
else if (ps_rtcp) { else if (ps_rtcp) {
chopper_append_c(chop, "a=rtcp:"); chopper_append_c(chop, "a=rtcp:");
chopper_append_printf(chop, "%hu", ps_rtcp->sfd->fd.localport); chopper_append_printf(chop, "%hu", ps_rtcp->sfd->fd.localport);
if (!call_media->rtcp_mux) if (!MEDIA_ISSET(call_media, RTCP_MUX))
chopper_append_c(chop, "\r\n"); chopper_append_c(chop, "\r\n");
else else
chopper_append_c(chop, "\r\na=rtcp-mux\r\n"); chopper_append_c(chop, "\r\na=rtcp-mux\r\n");
@ -1700,9 +1700,9 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu
create_random_ice_string(call, &call_media->ice_ufrag, 8); create_random_ice_string(call, &call_media->ice_ufrag, 8);
create_random_ice_string(call, &call_media->ice_pwd, 28); create_random_ice_string(call, &call_media->ice_pwd, 28);
} }
ps->stun = 1; PS_SET(ps, STUN);
if (ps_rtcp) if (ps_rtcp)
ps_rtcp->stun = 1; PS_SET(ps_rtcp, STUN);
chopper_append_c(chop, "a=ice-ufrag:"); chopper_append_c(chop, "a=ice-ufrag:");
chopper_append_str(chop, &call_media->ice_ufrag); chopper_append_str(chop, &call_media->ice_ufrag);

Loading…
Cancel
Save