diff options
author | Alfred E. Heggestad <aeh@db.org> | 2015-10-29 20:12:41 +0100 |
---|---|---|
committer | Alfred E. Heggestad <aeh@db.org> | 2015-10-29 20:12:41 +0100 |
commit | 136f8543e65e29fea1538fa7cd9a4dbdd533a6eb (patch) | |
tree | ce8156399160eb04da2fac020d2ae2ae23afaacc /src | |
parent | f828b6600d2c21c5b4948e945e0c68523e136039 (diff) |
call: check address-family of incoming SDP offer
this fixes #79
Diffstat (limited to 'src')
-rw-r--r-- | src/call.c | 28 | ||||
-rw-r--r-- | src/ua.c | 23 |
2 files changed, 49 insertions, 2 deletions
@@ -1217,7 +1217,7 @@ static bool have_common_audio_codecs(const struct call *call) if (!sc) return false; - ac = sc->data; + ac = sc->data; /* note: this will exclude telephone-event */ return ac != NULL; } @@ -1247,6 +1247,8 @@ int call_accept(struct call *call, struct sipsess_sock *sess_sock, } if (got_offer) { + struct sdp_media *m; + const struct sa *raddr; err = sdp_decode(call->sdp, msg->mb, true); if (err) @@ -1254,6 +1256,30 @@ int call_accept(struct call *call, struct sipsess_sock *sess_sock, call->got_offer = true; + /* + * Each media description in the SDP answer MUST + * use the same network type as the corresponding + * media description in the offer. + * + * See RFC 6157 + */ + m = stream_sdpmedia(audio_strm(call->audio)); + raddr = sdp_media_raddr(m); + + if (sa_af(raddr) != call->af) { + info("call: incompatible address-family" + " (local=%s, remote=%s)\n", + net_af2name(call->af), + net_af2name(sa_af(raddr))); + + sip_treply(NULL, uag_sip(), msg, + 488, "Not Acceptable Here"); + + call_event_handler(call, CALL_EVENT_CLOSED, + "Wrong address family"); + return 0; + } + /* Check if we have any common audio codecs, after * the SDP offer has been parsed */ @@ -34,6 +34,7 @@ struct ua { char *cuser; /**< SIP Contact username */ char *pub_gruu; /**< SIP Public GRUU */ int af; /**< Preferred Address Family */ + int af_media; enum presence_status my_status; /**< Presence Status */ }; @@ -428,6 +429,7 @@ static int ua_call_alloc(struct call **callp, struct ua *ua, struct call *xcall, const char *local_uri) { struct call_prm cprm; + int af = AF_UNSPEC; int err; if (*callp) { @@ -435,8 +437,18 @@ static int ua_call_alloc(struct call **callp, struct ua *ua, return EALREADY; } + /* 1. if AF_MEDIA is set, we prefer it + * 2. otherwise fall back to SIP AF + */ + if (ua->af_media) { + af = ua->af_media; + } + else if (ua->af) { + af = ua->af; + } + cprm.vidmode = vidmode; - cprm.af = ua->af; + cprm.af = af; err = call_alloc(callp, conf_config(), &ua->calls, ua->acc->dispname, @@ -1842,3 +1854,12 @@ struct ua *uag_current(void) return uag.ua_cur; } + + +void ua_set_media_af(struct ua *ua, int af_media) +{ + if (!ua) + return; + + ua->af_media = af_media; +} |