From 47c951506dc0699277f3523b9952e64b6522c31b Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Tue, 3 Jun 2014 11:39:20 +0000 Subject: [PATCH] this patch improves handling of SDP protocol/transport change for established media sessions. Instead of aborting SDP decode with an error (ENOTSUP) if transport is not supported, this scenario is handled gracefully, and the media lines in question are disabled in the SDP answer, and disabled from the app's perspective (remote port set to 0). --- src/sdp/media.c | 1 + src/sdp/msg.c | 26 +++++++++++++++++++++----- src/sdp/sdp.h | 1 + 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/sdp/media.c b/src/sdp/media.c index 6c190b4..6566867 100644 --- a/src/sdp/media.c +++ b/src/sdp/media.c @@ -38,6 +38,7 @@ static void destructor(void *arg) list_unlink(&m->le); mem_deref(m->name); mem_deref(m->proto); + mem_deref(m->uproto); } diff --git a/src/sdp/msg.c b/src/sdp/msg.c index 170ed30..c1a8bbc 100644 --- a/src/sdp/msg.c +++ b/src/sdp/msg.c @@ -191,13 +191,21 @@ static int media_decode(struct sdp_media **mp, struct sdp_session *sess, list_unlink(&m->le); list_append(&sess->medial, &m->le, m); } + + m->uproto = mem_deref(m->uproto); } else { if (pl_strcmp(&name, m->name)) return offer ? ENOTSUP : EPROTO; - if (!sdp_media_proto_cmp(m, &proto, offer)) - return ENOTSUP; + m->uproto = mem_deref(m->uproto); + + if (!sdp_media_proto_cmp(m, &proto, offer)) { + + err = pl_strdup(&m->uproto, &proto); + if (err) + return err; + } } while (!re_regex(fmtv.p, fmtv.l, " [^ ]+", &fmt)) { @@ -210,7 +218,7 @@ static int media_decode(struct sdp_media **mp, struct sdp_session *sess, } m->raddr = sess->raddr; - sa_set_port(&m->raddr, pl_u32(&port)); + sa_set_port(&m->raddr, m->uproto ? 0 : pl_u32(&port)); m->rdir = sess->rdir; @@ -341,6 +349,7 @@ int sdp_decode(struct sdp_session *sess, struct mbuf *mb, bool offer) static int media_encode(const struct sdp_media *m, struct mbuf *mb, bool offer) { enum sdp_bandwidth i; + const char *proto; int err, supc = 0; bool disabled; struct le *le; @@ -354,16 +363,23 @@ static int media_encode(const struct sdp_media *m, struct mbuf *mb, bool offer) ++supc; } - if (m->disabled || supc == 0 || (!offer && !sa_port(&m->raddr))) { + if (m->uproto && !offer) { disabled = true; port = 0; + proto = m->uproto; + } + else if (m->disabled || supc == 0 || (!offer && !sa_port(&m->raddr))) { + disabled = true; + port = 0; + proto = m->proto; } else { disabled = false; port = sa_port(&m->laddr); + proto = m->proto; } - err = mbuf_printf(mb, "m=%s %u %s", m->name, port, m->proto); + err = mbuf_printf(mb, "m=%s %u %s", m->name, port, proto); if (disabled) { err |= mbuf_write_str(mb, " 0\r\n"); diff --git a/src/sdp/sdp.h b/src/sdp/sdp.h index eab7204..f0588d1 100644 --- a/src/sdp/sdp.h +++ b/src/sdp/sdp.h @@ -40,6 +40,7 @@ struct sdp_media { char *name; char *proto; char *protov[8]; + char *uproto; /* unsupported protocol */ sdp_media_enc_h *ench; void *arg; enum sdp_dir ldir;