summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/baresip.h1
-rw-r--r--src/call.c28
-rw-r--r--src/ua.c23
-rw-r--r--test/call.c35
-rw-r--r--test/main.c1
-rw-r--r--test/test.h1
6 files changed, 87 insertions, 2 deletions
diff --git a/include/baresip.h b/include/baresip.h
index 7f49e36..2f91d6d 100644
--- a/include/baresip.h
+++ b/include/baresip.h
@@ -535,6 +535,7 @@ struct account *ua_prm(const struct ua *ua);
struct list *ua_calls(const struct ua *ua);
enum presence_status ua_presence_status(const struct ua *ua);
void ua_presence_status_set(struct ua *ua, const enum presence_status status);
+void ua_set_media_af(struct ua *ua, int af_media);
/* One instance */
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;
+}
diff --git a/test/call.c b/test/call.c
index cad90a6..7c96100 100644
--- a/test/call.c
+++ b/test/call.c
@@ -234,3 +234,38 @@ int test_call_reject(void)
return err;
}
+
+
+int test_call_af_mismatch(void)
+{
+ struct fixture fix, *f = &fix;
+ int err = 0;
+
+ fixture_init(f);
+
+ ua_set_media_af(f->a.ua, AF_INET6);
+ ua_set_media_af(f->b.ua, AF_INET);
+
+ /* Make a call from A to B */
+ err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
+ TEST_ERR(err);
+
+ /* run main-loop with timeout, wait for events */
+ err = re_main_timeout(5);
+ TEST_ERR(err);
+ TEST_ERR(fix.err);
+
+ ASSERT_EQ(0, fix.a.n_incoming);
+ ASSERT_EQ(0, fix.a.n_established);
+ ASSERT_EQ(1, fix.a.n_closed);
+ ASSERT_EQ(488, fix.a.close_scode);
+
+ ASSERT_EQ(0, fix.b.n_incoming);
+ ASSERT_EQ(0, fix.b.n_established);
+ ASSERT_EQ(1, fix.b.n_closed);
+
+ out:
+ fixture_close(f);
+
+ return err;
+}
diff --git a/test/main.c b/test/main.c
index a959a5e..8215ed4 100644
--- a/test/main.c
+++ b/test/main.c
@@ -25,6 +25,7 @@ static const struct test tests[] = {
TEST(test_cplusplus),
TEST(test_call_answer),
TEST(test_call_reject),
+ TEST(test_call_af_mismatch),
};
diff --git a/test/test.h b/test/test.h
index 2600bd6..8aedc00 100644
--- a/test/test.h
+++ b/test/test.h
@@ -81,6 +81,7 @@ int test_ua_register(void);
int test_call_answer(void);
int test_call_reject(void);
+int test_call_af_mismatch(void);
#ifdef __cplusplus