summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2015-10-29 20:12:41 +0100
committerAlfred E. Heggestad <aeh@db.org>2015-10-29 20:12:41 +0100
commit136f8543e65e29fea1538fa7cd9a4dbdd533a6eb (patch)
treece8156399160eb04da2fac020d2ae2ae23afaacc /src
parentf828b6600d2c21c5b4948e945e0c68523e136039 (diff)
call: check address-family of incoming SDP offer
this fixes #79
Diffstat (limited to 'src')
-rw-r--r--src/call.c28
-rw-r--r--src/ua.c23
2 files changed, 49 insertions, 2 deletions
diff --git a/src/call.c b/src/call.c
index 144e25b..a8d1cd7 100644
--- a/src/call.c
+++ b/src/call.c
@@ -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
*/
diff --git a/src/ua.c b/src/ua.c
index 7aeabd5..424a2a1 100644
--- a/src/ua.c
+++ b/src/ua.c
@@ -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;
+}