diff --git a/daemon/call.c b/daemon/call.c index ab32bce71..bcf36360c 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1353,7 +1353,7 @@ static void steal_peer(struct peer *dest, struct peer *src) { src->confirmed = 0; unkernelize(src); - dest->filled = 1; + dest->filled = src->filled; dest->tag = src->tag; src->tag = STR_NULL; dest->desired_family = src->desired_family; @@ -1376,8 +1376,8 @@ static void steal_peer(struct peer *dest, struct peer *src) { sr->peer_advertised = srs->peer_advertised; sr->stun = srs->stun; sr->rtcp = srs->rtcp; - sr->crypto = srs->crypto; - crypto_context_pair_uninit(&srs->crypto); + crypto_context_move(&sr->crypto.in, &srs->crypto.in); + crypto_context_move(&sr->other->crypto.out, &srs->other->crypto.out); srs->fd.fd = -1; @@ -2556,16 +2556,12 @@ out: return PROTO_UNKNOWN; } -static void call_ng_process_flags(struct sdp_ng_flags *out, GQueue *streams, bencode_item_t *input) { +static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *input) { bencode_item_t *list, *it; - struct stream_input *si; int diridx; - enum stream_direction dirs[2]; - GList *gl; str s; ZERO(*out); - ZERO(dirs); if ((list = bencode_dictionary_get_expect(input, "flags", BENCODE_LIST))) { for (it = list->child; it; it = it->sibling) { @@ -2592,15 +2588,9 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, GQueue *streams, ben if ((list = bencode_dictionary_get_expect(input, "direction", BENCODE_LIST))) { for (it = list->child; it && diridx < 2; it = it->sibling) { if (!bencode_strcmp(it, "internal")) - dirs[diridx++] = DIR_INTERNAL; + out->directions[diridx++] = DIR_INTERNAL; else if (!bencode_strcmp(it, "external")) - dirs[diridx++] = DIR_EXTERNAL; - } - - for (gl = streams->head; gl; gl = gl->next) { - si = gl->data; - si->direction[0] = dirs[0]; - si->direction[1] = dirs[1]; + out->directions[diridx++] = DIR_EXTERNAL; } } @@ -2664,7 +2654,7 @@ static const char *call_offer_answer_ng(bencode_item_t *input, struct callmaster if (sdp_parse(&sdp, &parsed)) return "Failed to parse SDP"; - call_ng_process_flags(&flags, &streams, input); + call_ng_process_flags(&flags, input); streamhash = g_hash_table_new((GHashFunc) stream_hash, (GEqualFunc) stream_equal); errstr = "Incomplete SDP specification"; diff --git a/daemon/crypto.h b/daemon/crypto.h index 7baec7205..247d4dc59 100644 --- a/daemon/crypto.h +++ b/daemon/crypto.h @@ -4,6 +4,7 @@ #include +#include #include "str.h" @@ -121,6 +122,16 @@ static inline void crypto_context_pair_uninit(struct crypto_context_pair *p) { p->out.session_key_ctx[0] = NULL; p->out.session_key_ctx[1] = NULL; } +static inline void crypto_context_move(struct crypto_context *dst, struct crypto_context *src) { + int i; + + if (src == dst) + return; + crypto_cleanup(dst); + *dst = *src; + for (i = 0; i < G_N_ELEMENTS(dst->session_key_ctx); i++) + src->session_key_ctx[i] = NULL; +} diff --git a/daemon/obj.h b/daemon/obj.h index f2717e11b..dc9990914 100644 --- a/daemon/obj.h +++ b/daemon/obj.h @@ -14,7 +14,7 @@ -#ifdef __DEBUG +#if 0 && defined(__DEBUG) #define OBJ_DEBUG 1 #else #define OBJ_DEBUG 0 diff --git a/daemon/sdp.c b/daemon/sdp.c index d95c051a4..f6889d4ef 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -813,6 +813,7 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, GHashTable *streamhash, si->consecutive_num = (i == 0) ? media->port_count : 1; si->stream.protocol = tp; si->crypto = cctx; + memcpy(&si->direction, &flags->directions, sizeof(si->direction)); g_hash_table_insert(streamhash, si, si); g_queue_push_tail(streams, si); @@ -836,6 +837,7 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, GHashTable *streamhash, si->is_rtcp = 1; si->stream.protocol = tp; si->crypto = cctx; + memcpy(&si->direction, &flags->directions, sizeof(si->direction)); g_hash_table_insert(streamhash, si, si); g_queue_push_tail(streams, si); diff --git a/daemon/sdp.h b/daemon/sdp.h index 2ace50be3..e65cfc9c5 100644 --- a/daemon/sdp.h +++ b/daemon/sdp.h @@ -13,6 +13,7 @@ struct sdp_ng_flags { str transport_protocol_str; enum transport_protocol transport_protocol; struct in6_addr parsed_address; + enum stream_direction directions[2]; int asymmetric:1, symmetric:1, trust_address:1, diff --git a/tests/simulator-ng.pl b/tests/simulator-ng.pl index 9baf1f676..c6b77efd0 100755 --- a/tests/simulator-ng.pl +++ b/tests/simulator-ng.pl @@ -42,6 +42,7 @@ $SIG{ALRM} = sub { print "alarm!\n"; }; setrlimit(RLIMIT_NOFILE, 8000, 8000); $PROTOS and $PROTOS = [split(/\s*[,;:]+\s*/, $PROTOS)]; +$PROTOS && @$PROTOS == 1 and $$PROTOS[1] = $$PROTOS[0]; $DEST and $DEST = [split(/:/, $DEST)]; $$DEST[0] or $$DEST[0] = '127.0.0.1'; $$DEST[1] or $$DEST[1] = 2223; @@ -467,6 +468,8 @@ sub savp_crypto { ($$ctx{in}{rtp_master_key}, $$ctx{in}{rtp_master_salt}) = unpack('a16a14', $ks); $$ctx{in}{rtp_mki} = $a[4]; $$ctx{in}{rtp_mki_len} = $a[5]; + undef($$ctx{in}{rtp_session_key}); + undef($$ctx{in}{rtcp_session_key}); } sub hexdump { @@ -681,7 +684,7 @@ a=rtcp:$cp my @rp_ports = $$o{sdp} =~ /m=audio (\d+) \Q$$tr_o{name}\E /gs or die; $rp_af ne $$pr_o{reply} and die "incorrect address family reply code"; my $rpl_a = $$c{outputs} || ($$c{outputs} = []); - my $rpl_t = $$rpl_a[$i] || ($$rpl_a[$i] = []); + my $rpl_t = $$rpl_a[$i] = []; for my $rpl (@rp_ports) { $rpl == 0 and die "mediaproxy ran out of ports"; push(@$rpl_t, [$rpl,$rp_add]); @@ -705,6 +708,7 @@ my $rtptime = Time::HiRes::gettimeofday(); my $rtcptime = $rtptime; my $countstart = $rtptime; my $countstop = $countstart + $STATS_INTERVAL; +my $last_reinv = 0; while (time() < $end) { my $now = Time::HiRes::gettimeofday(); $now <= $rtptime and Time::HiRes::sleep($rtptime - $now); @@ -731,7 +735,8 @@ while (time() < $end) { @calls = sort {rand() < .5} grep(defined, @calls); - if ($REINVITES && int($now) % 5 == 0) { + if ($REINVITES && $now >= $last_reinv + 5) { + $last_reinv = $now; my $c = $calls[rand(@calls)]; print("simulating re-invite on $$c{callid_viabranch}[0]"); for my $i (0,1) {