summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-03-23 19:09:54 +0000
committerBenny Prijono <bennylp@teluu.com>2007-03-23 19:09:54 +0000
commit57921286f7577dd670b905f85a4ef0271cfb2028 (patch)
tree2d14cbbee45fc7df5d2dba49c3195cf06d595be9
parente3fd604ea862f68ad3ece248ca7d853899cbf48f (diff)
ICE (work in progress): implemented server reflexive candidate
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1099 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/src/pjmedia/transport_ice.c86
-rw-r--r--pjnath/include/pjnath/errno.h5
-rw-r--r--pjnath/include/pjnath/ice_stream_transport.h26
-rw-r--r--pjnath/src/pjnath/ice.c13
-rw-r--r--pjnath/src/pjnath/ice_stream_transport.c215
-rw-r--r--pjnath/src/pjnath/stun_session.c16
-rw-r--r--pjsip/src/pjsua-lib/pjsua_acc.c12
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c7
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c6
9 files changed, 295 insertions, 91 deletions
diff --git a/pjmedia/src/pjmedia/transport_ice.c b/pjmedia/src/pjmedia/transport_ice.c
index 2023a1dc..7bb14b88 100644
--- a/pjmedia/src/pjmedia/transport_ice.c
+++ b/pjmedia/src/pjmedia/transport_ice.c
@@ -19,19 +19,25 @@
#include <pjmedia/transport_ice.h>
#include <pjnath/errno.h>
#include <pj/assert.h>
+#include <pj/log.h>
struct transport_ice
{
pjmedia_transport base;
pj_ice_st *ice_st;
- void *stream;
- void (*rtp_cb)(void*,
- const void*,
- pj_ssize_t);
- void (*rtcp_cb)(void*,
- const void*,
- pj_ssize_t);
+ pj_time_val start_ice;
+
+ void *stream;
+ pj_sockaddr_in remote_rtp;
+ pj_sockaddr_in remote_rtcp;
+
+ void (*rtp_cb)(void*,
+ const void*,
+ pj_ssize_t);
+ void (*rtcp_cb)(void*,
+ const void*,
+ pj_ssize_t);
};
@@ -68,12 +74,6 @@ static void ice_on_rx_data(pj_ice_st *ice_st,
void *pkt, pj_size_t size,
const pj_sockaddr_t *src_addr,
unsigned src_addr_len);
-static void ice_on_stun_srv_resolved(pj_ice_st *ice_st,
- pj_status_t status);
-static void ice_on_interface_status(pj_ice_st *ice_st,
- void *notify_data,
- pj_status_t status,
- int itf_id);
static void ice_on_ice_complete(pj_ice_st *ice_st,
pj_status_t status);
@@ -107,9 +107,7 @@ PJ_DEF(pj_status_t) pjmedia_ice_create(pjmedia_endpt *endpt,
/* Configure ICE callbacks */
pj_bzero(&ice_st_cb, sizeof(ice_st_cb));
ice_st_cb.on_ice_complete = &ice_on_ice_complete;
- ice_st_cb.on_interface_status = &ice_on_interface_status;
ice_st_cb.on_rx_data = &ice_on_rx_data;
- ice_st_cb.on_stun_srv_resolved = &ice_on_stun_srv_resolved;
/* Create ICE */
status = pj_ice_st_create(stun_cfg, name, NULL, &ice_st_cb, &ice_st);
@@ -387,6 +385,9 @@ PJ_DEF(pj_status_t) pjmedia_ice_start_ice(pjmedia_transport *tp,
cand_cnt++;
}
+ /* Mark start time */
+ pj_gettimeofday(&tp_ice->start_ice);
+
/* Start ICE */
return pj_ice_st_start_ice(tp_ice->ice_st, &uname, &pass, cand_cnt, cand);
}
@@ -454,9 +455,8 @@ static pj_status_t tp_attach( pjmedia_transport *tp,
tp_ice->rtp_cb = rtp_cb;
tp_ice->rtcp_cb = rtcp_cb;
- PJ_UNUSED_ARG(rem_addr);
- PJ_UNUSED_ARG(rem_rtcp);
- PJ_UNUSED_ARG(addr_len);
+ pj_memcpy(&tp_ice->remote_rtp, rem_addr, addr_len);
+ pj_memcpy(&tp_ice->remote_rtcp, rem_rtcp, addr_len);
return PJ_SUCCESS;
}
@@ -480,7 +480,13 @@ static pj_status_t tp_send_rtp(pjmedia_transport *tp,
pj_size_t size)
{
struct transport_ice *tp_ice = (struct transport_ice*)tp;
- return pj_ice_st_send_data(tp_ice->ice_st, 1, pkt, size);
+ if (tp_ice->ice_st->ice) {
+ return pj_ice_st_send_data(tp_ice->ice_st, 1, pkt, size);
+ } else {
+ return pj_ice_st_sendto(tp_ice->ice_st, 1, 0,
+ pkt, size, &tp_ice->remote_rtp,
+ sizeof(pj_sockaddr_in));
+ }
}
@@ -520,26 +526,40 @@ static void ice_on_rx_data(pj_ice_st *ice_st,
}
-static void ice_on_stun_srv_resolved(pj_ice_st *ice_st,
- pj_status_t status)
+static void ice_on_ice_complete(pj_ice_st *ice_st,
+ pj_status_t status)
{
struct transport_ice *tp_ice = (struct transport_ice*) ice_st->user_data;
-}
+ pj_time_val end_ice;
+ pj_ice_cand *lcand, *rcand;
+ pj_ice_check *check;
+ char src_addr[32];
+ char dst_addr[32];
+
+ if (status != PJ_SUCCESS) {
+ char errmsg[PJ_ERR_MSG_SIZE];
+ pj_strerror(status, errmsg, sizeof(errmsg));
+ PJ_LOG(1,(ice_st->obj_name, "ICE negotiation failed: %s", errmsg));
+ return;
+ }
+ pj_gettimeofday(&end_ice);
+ PJ_TIME_VAL_SUB(end_ice, tp_ice->start_ice);
-static void ice_on_interface_status(pj_ice_st *ice_st,
- void *notify_data,
- pj_status_t status,
- int itf_id)
-{
- struct transport_ice *tp_ice = (struct transport_ice*) ice_st->user_data;
-}
+ check = &ice_st->ice->clist.checks[ice_st->ice->valid_list[0]];
+
+ lcand = check->lcand;
+ rcand = check->rcand;
+ pj_ansi_strcpy(src_addr, pj_inet_ntoa(lcand->addr.ipv4.sin_addr));
+ pj_ansi_strcpy(dst_addr, pj_inet_ntoa(rcand->addr.ipv4.sin_addr));
-static void ice_on_ice_complete(pj_ice_st *ice_st,
- pj_status_t status)
-{
- struct transport_ice *tp_ice = (struct transport_ice*) ice_st->user_data;
+ PJ_LOG(3,(ice_st->obj_name,
+ "ICE negotiation completed in %d.%03ds. Sending from "
+ "%s:%d to %s:%d",
+ (int)end_ice.sec, (int)end_ice.msec,
+ src_addr, pj_ntohs(lcand->addr.ipv4.sin_port),
+ dst_addr, pj_ntohs(rcand->addr.ipv4.sin_port)));
}
diff --git a/pjnath/include/pjnath/errno.h b/pjnath/include/pjnath/errno.h
index 9f45bc86..7fbd9837 100644
--- a/pjnath/include/pjnath/errno.h
+++ b/pjnath/include/pjnath/errno.h
@@ -133,6 +133,11 @@
* STUN transaction terminates with failure.
*/
#define PJNATH_ESTUNTSXFAILED (PJNATH_ERRNO_START+126)/* 370126 */
+/**
+ * @hideinitializer
+ * STUN mapped address attribute not found
+ */
+#define PJNATH_ESTUNNOMAPPEDADDR (PJNATH_ERRNO_START+127)/* 370127 */
//#define PJ_STATUS_FROM_STUN_CODE(code) (PJNATH_ERRNO_START+code)
diff --git a/pjnath/include/pjnath/ice_stream_transport.h b/pjnath/include/pjnath/ice_stream_transport.h
index 37ff5686..59207324 100644
--- a/pjnath/include/pjnath/ice_stream_transport.h
+++ b/pjnath/include/pjnath/ice_stream_transport.h
@@ -48,13 +48,6 @@ typedef struct pj_ice_st_cb
void *pkt, pj_size_t size,
const pj_sockaddr_t *src_addr,
unsigned src_addr_len);
-
- void (*on_stun_srv_resolved)(pj_ice_st *ice_st,
- pj_status_t status);
- void (*on_interface_status)(pj_ice_st *ice_st,
- void *notify_data,
- pj_status_t status,
- int itf_id);
void (*on_ice_complete)(pj_ice_st *ice_st,
pj_status_t status);
@@ -85,6 +78,7 @@ typedef struct pj_ice_st_interface
pj_ioqueue_op_key_t write_op;
pj_sockaddr src_addr;
int src_addr_len;
+ pj_stun_session *stun_sess;
} pj_ice_st_interface;
@@ -133,19 +127,14 @@ PJ_DECL(pj_status_t) pj_ice_st_add_host_interface(pj_ice_st *ice_st,
unsigned comp_id,
pj_uint16_t local_pref,
const pj_sockaddr_in *addr,
- unsigned *p_itf_id,
- pj_bool_t notify,
- void *notify_data);
+ unsigned *p_itf_id);
PJ_DECL(pj_status_t) pj_ice_st_add_all_host_interfaces(pj_ice_st *ice_st,
unsigned comp_id,
- unsigned port,
- pj_bool_t notify,
- void *notify_data);
+ unsigned port);
PJ_DECL(pj_status_t) pj_ice_st_add_stun_interface(pj_ice_st *ice_st,
unsigned comp_id,
unsigned local_port,
- pj_bool_t notify,
- void *notify_data);
+ unsigned *p_itf_id);
PJ_DECL(pj_status_t) pj_ice_st_add_relay_interface(pj_ice_st *ice_st,
unsigned comp_id,
unsigned local_port,
@@ -171,6 +160,13 @@ PJ_DECL(pj_status_t) pj_ice_st_send_data(pj_ice_st *ice_st,
unsigned comp_id,
const void *data,
pj_size_t data_len);
+PJ_DECL(pj_status_t) pj_ice_st_sendto(pj_ice_st *ice_st,
+ unsigned comp_id,
+ unsigned itf_id,
+ const void *data,
+ pj_size_t data_len,
+ const pj_sockaddr_t *dst_addr,
+ int dst_addr_len);
/**
diff --git a/pjnath/src/pjnath/ice.c b/pjnath/src/pjnath/ice.c
index d2d2474d..9ab50262 100644
--- a/pjnath/src/pjnath/ice.c
+++ b/pjnath/src/pjnath/ice.c
@@ -56,11 +56,6 @@ static const char *clist_state_name[] =
"Completed"
};
-const pj_str_t host_foundation = {"host", 4};
-const pj_str_t mapped_foundation = {"srfx", 4};
-const pj_str_t relayed_foundation = {"rlyd", 4};
-const pj_str_t peer_mapped_foundation = {"peer", 4};
-
#define CHECK_NAME_LEN 128
#define LOG(expr) PJ_LOG(4,expr)
#define GET_LCAND_ID(cand) (cand - ice->lcand)
@@ -1431,11 +1426,17 @@ static void on_stun_request_complete(pj_stun_session *stun_sess,
if (i == ice->lcand_cnt) {
unsigned cand_id;
+ char buf[32];
+ pj_str_t foundation;
+
+ pj_ansi_snprintf(buf, sizeof(buf), "P%x",
+ lcand->base_addr.ipv4.sin_addr.s_addr);
+ foundation = pj_str(buf);
/* Add new peer reflexive candidate */
status = pj_ice_add_cand(ice, lcand->comp_id,
PJ_ICE_CAND_TYPE_PRFLX,
- 65535, &peer_mapped_foundation,
+ 65535, &foundation,
&xaddr->sockaddr, &lcand->base_addr, NULL,
sizeof(pj_sockaddr_in), &cand_id);
if (status != PJ_SUCCESS) {
diff --git a/pjnath/src/pjnath/ice_stream_transport.c b/pjnath/src/pjnath/ice_stream_transport.c
index e654fcf7..1462ff25 100644
--- a/pjnath/src/pjnath/ice_stream_transport.c
+++ b/pjnath/src/pjnath/ice_stream_transport.c
@@ -47,6 +47,18 @@ static void on_read_complete(pj_ioqueue_key_t *key,
static void destroy_ice_interface(pj_ice_st_interface *is);
static void destroy_ice_st(pj_ice_st *ice_st, pj_status_t reason);
+/* STUN session callback */
+static pj_status_t stun_on_send_msg(pj_stun_session *sess,
+ const void *pkt,
+ pj_size_t pkt_size,
+ const pj_sockaddr_t *dst_addr,
+ unsigned addr_len);
+static void stun_on_request_complete(pj_stun_session *sess,
+ pj_status_t status,
+ pj_stun_tx_data *tdata,
+ const pj_stun_msg *response);
+
+/* Utility: print error */
static void ice_st_perror(pj_ice_st *ice_st, const char *title,
pj_status_t status)
{
@@ -160,6 +172,7 @@ static void on_read_complete(pj_ioqueue_key_t *key,
{
pj_ice_st_interface *is = (pj_ice_st_interface*)
pj_ioqueue_get_user_data(key);
+ pj_ice_st *ice_st = is->ice_st;
pj_ssize_t pkt_size;
pj_status_t status;
@@ -168,11 +181,29 @@ static void on_read_complete(pj_ioqueue_key_t *key,
/* If we have an active ICE session, hand over all incoming
* packets to the ICE session. Otherwise just drop the packet.
*/
- if (is->ice_st->ice) {
- status = pj_ice_on_rx_pkt(is->ice_st->ice,
+ if (ice_st->ice) {
+ status = pj_ice_on_rx_pkt(ice_st->ice,
is->comp_id, is->cand_id,
is->pkt, bytes_read,
&is->src_addr, is->src_addr_len);
+ } else if (is->stun_sess) {
+ status = pj_stun_msg_check(is->pkt, bytes_read, PJ_STUN_IS_DATAGRAM);
+ if (status == PJ_SUCCESS) {
+ status = pj_stun_session_on_rx_pkt(is->stun_sess, is->pkt,
+ bytes_read,
+ PJ_STUN_IS_DATAGRAM, NULL,
+ &is->src_addr,
+ is->src_addr_len);
+ } else {
+ (*ice_st->cb.on_rx_data)(ice_st, is->comp_id, is->cand_id,
+ is->pkt, bytes_read,
+ &is->src_addr, is->src_addr_len);
+
+ }
+ } else {
+ (*ice_st->cb.on_rx_data)(ice_st, is->comp_id, is->cand_id,
+ is->pkt, bytes_read,
+ &is->src_addr, is->src_addr_len);
}
} else if (bytes_read < 0) {
@@ -195,6 +226,11 @@ static void on_read_complete(pj_ioqueue_key_t *key,
*/
static void destroy_ice_interface(pj_ice_st_interface *is)
{
+ if (is->stun_sess) {
+ pj_stun_session_destroy(is->stun_sess);
+ is->stun_sess = NULL;
+ }
+
if (is->key) {
pj_ioqueue_unregister(is->key);
is->key = NULL;
@@ -344,8 +380,7 @@ PJ_DEF(pj_status_t) pj_ice_st_add_comp(pj_ice_st *ice_st,
/* Add interface */
static void add_interface(pj_ice_st *ice_st, pj_ice_st_interface *is,
- unsigned *p_itf_id, pj_bool_t notify,
- void *notify_data)
+ unsigned *p_itf_id)
{
unsigned itf_id;
@@ -354,11 +389,6 @@ static void add_interface(pj_ice_st *ice_st, pj_ice_st_interface *is,
if (p_itf_id)
*p_itf_id = itf_id;
-
- if (notify && ice_st->cb.on_interface_status) {
- (*ice_st->cb.on_interface_status)(ice_st, notify_data,
- PJ_SUCCESS, itf_id);
- }
}
/*
@@ -368,9 +398,7 @@ PJ_DEF(pj_status_t) pj_ice_st_add_host_interface(pj_ice_st *ice_st,
unsigned comp_id,
pj_uint16_t local_pref,
const pj_sockaddr_in *addr,
- unsigned *p_itf_id,
- pj_bool_t notify,
- void *notify_data)
+ unsigned *p_itf_id)
{
pj_ice_st_interface *is;
pj_status_t status;
@@ -394,7 +422,7 @@ PJ_DEF(pj_status_t) pj_ice_st_add_host_interface(pj_ice_st *ice_st,
pj_memcpy(&is->addr, &is->base_addr, sizeof(is->addr));
/* Store this interface */
- add_interface(ice_st, is, p_itf_id, notify, notify_data);
+ add_interface(ice_st, is, p_itf_id);
/* Set interface status to SUCCESS */
is->status = PJ_SUCCESS;
@@ -407,9 +435,7 @@ PJ_DEF(pj_status_t) pj_ice_st_add_host_interface(pj_ice_st *ice_st,
*/
PJ_DEF(pj_status_t) pj_ice_st_add_all_host_interfaces(pj_ice_st *ice_st,
unsigned comp_id,
- unsigned port,
- pj_bool_t notify,
- void *notify_data)
+ unsigned port)
{
pj_sockaddr_in addr;
pj_status_t status;
@@ -423,8 +449,7 @@ PJ_DEF(pj_status_t) pj_ice_st_add_all_host_interfaces(pj_ice_st *ice_st,
if (status != PJ_SUCCESS)
return status;
- return pj_ice_st_add_host_interface(ice_st, comp_id, 65535, &addr,
- NULL, notify, notify_data);
+ return pj_ice_st_add_host_interface(ice_st, comp_id, 65535, &addr, NULL);
}
/*
@@ -433,16 +458,61 @@ PJ_DEF(pj_status_t) pj_ice_st_add_all_host_interfaces(pj_ice_st *ice_st,
PJ_DEF(pj_status_t) pj_ice_st_add_stun_interface(pj_ice_st *ice_st,
unsigned comp_id,
unsigned local_port,
- pj_bool_t notify,
- void *notify_data)
+ unsigned *p_itf_id)
{
- /* Yeah, TODO */
- PJ_UNUSED_ARG(ice_st);
- PJ_UNUSED_ARG(comp_id);
- PJ_UNUSED_ARG(local_port);
- PJ_UNUSED_ARG(notify);
- PJ_UNUSED_ARG(notify_data);
- return -1;
+ pj_ice_st_interface *is;
+ pj_sockaddr_in local_addr;
+ pj_stun_session_cb sess_cb;
+ pj_stun_tx_data *tdata;
+ pj_status_t status;
+
+ PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL);
+
+ /* STUN server must have been configured */
+ PJ_ASSERT_RETURN(ice_st->stun_srv.sin_family != 0, PJ_EINVALIDOP);
+
+
+ /* Create interface */
+ pj_sockaddr_in_init(&local_addr, NULL, (pj_uint16_t)local_port);
+ status = create_ice_interface(ice_st, PJ_ICE_CAND_TYPE_SRFLX, comp_id,
+ 65535, &local_addr, &is);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Create STUN session */
+ pj_bzero(&sess_cb, sizeof(sess_cb));
+ sess_cb.on_request_complete = &stun_on_request_complete;
+ sess_cb.on_send_msg = &stun_on_send_msg;
+ status = pj_stun_session_create(&ice_st->stun_cfg, ice_st->obj_name,
+ &sess_cb, PJ_FALSE, &is->stun_sess);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Associate interface with STUN session */
+ pj_stun_session_set_user_data(is->stun_sess, (void*)is);
+
+ /* Create and send STUN binding request */
+ status = pj_stun_session_create_req(is->stun_sess,
+ PJ_STUN_BINDING_REQUEST, &tdata);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ status = pj_stun_session_send_msg(is->stun_sess, PJ_FALSE,
+ &ice_st->stun_srv,
+ sizeof(pj_sockaddr_in), tdata);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+ /* Mark interface as pending */
+ is->status = PJ_EPENDING;
+
+ add_interface(ice_st, is, p_itf_id);
+
+ return PJ_SUCCESS;
+
+on_error:
+ destroy_ice_interface(is);
+ return status;
}
/*
@@ -624,6 +694,29 @@ PJ_DEF(pj_status_t) pj_ice_st_send_data( pj_ice_st *ice_st,
}
/*
+ * Send packet using non-ICE means (e.g. when ICE was not negotiated).
+ */
+PJ_DEF(pj_status_t) pj_ice_st_sendto( pj_ice_st *ice_st,
+ unsigned comp_id,
+ unsigned itf_id,
+ const void *data,
+ pj_size_t data_len,
+ const pj_sockaddr_t *dst_addr,
+ int dst_addr_len)
+{
+ pj_ssize_t pkt_size;
+ pj_ice_st_interface *is = ice_st->itfs[itf_id];
+ pj_status_t status;
+
+ pkt_size = data_len;
+ status = pj_ioqueue_sendto(is->key, &is->write_op,
+ data, &pkt_size, 0,
+ dst_addr, dst_addr_len);
+
+ return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status;
+}
+
+/*
* Callback called by ICE session when ICE processing is complete, either
* successfully or with failure.
*/
@@ -687,4 +780,72 @@ static void on_rx_data(pj_ice *ice,
}
}
+/*
+ * Callback called by STUN session to send outgoing packet.
+ */
+static pj_status_t stun_on_send_msg(pj_stun_session *sess,
+ const void *pkt,
+ pj_size_t size,
+ const pj_sockaddr_t *dst_addr,
+ unsigned dst_addr_len)
+{
+ pj_ice_st_interface *is;
+ pj_ssize_t pkt_size;
+ pj_status_t status;
+
+ is = (pj_ice_st_interface*) pj_stun_session_get_user_data(sess);
+ pkt_size = size;
+ status = pj_ioqueue_sendto(is->key, &is->write_op,
+ pkt, &pkt_size, 0,
+ dst_addr, dst_addr_len);
+
+ return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status;
+}
+
+/*
+ * Callback sent by STUN session when outgoing STUN request has
+ * completed.
+ */
+static void stun_on_request_complete(pj_stun_session *sess,
+ pj_status_t status,
+ pj_stun_tx_data *tdata,
+ const pj_stun_msg *response)
+{
+ pj_ice_st_interface *is;
+ pj_stun_xor_mapped_addr_attr *xa;
+ pj_stun_mapped_addr_attr *ma;
+ pj_sockaddr *mapped_addr;
+
+ PJ_UNUSED_ARG(tdata);
+
+ is = (pj_ice_st_interface*) pj_stun_session_get_user_data(sess);
+ if (status != PJ_SUCCESS) {
+ is->status = status;
+ ice_st_perror(is->ice_st, "STUN Binding request failed", is->status);
+ return;
+ }
+
+ xa = (pj_stun_xor_mapped_addr_attr*)
+ pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 0);
+ ma = (pj_stun_mapped_addr_attr*)
+ pj_stun_msg_find_attr(response, PJ_STUN_ATTR_MAPPED_ADDR, 0);
+
+ if (xa)
+ mapped_addr = &xa->sockaddr;
+ else if (ma)
+ mapped_addr = &ma->sockaddr;
+ else {
+ is->status = PJNATH_ESTUNNOMAPPEDADDR;
+ ice_st_perror(is->ice_st, "STUN Binding request failed", is->status);
+ return;
+ }
+
+ PJ_LOG(4,(is->ice_st->obj_name,
+ "STUN mapped address: %s:%d",
+ pj_inet_ntoa(mapped_addr->ipv4.sin_addr),
+ (int)pj_ntohs(mapped_addr->ipv4.sin_port)));
+ pj_memcpy(&is->addr, mapped_addr, sizeof(pj_sockaddr_in));
+ is->status = PJ_SUCCESS;
+
+}
diff --git a/pjnath/src/pjnath/stun_session.c b/pjnath/src/pjnath/stun_session.c
index 44493120..1a048f2c 100644
--- a/pjnath/src/pjnath/stun_session.c
+++ b/pjnath/src/pjnath/stun_session.c
@@ -280,10 +280,12 @@ static pj_status_t apply_msg_options(pj_stun_session *sess,
/* Create and add USERNAME attribute */
- status = pj_stun_msg_add_string_attr(pool, msg,
- PJ_STUN_ATTR_USERNAME,
- &username);
- PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+ if (username.slen) {
+ status = pj_stun_msg_add_string_attr(pool, msg,
+ PJ_STUN_ATTR_USERNAME,
+ &username);
+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+ }
/* Add REALM only when long term credential is used */
if (realm.slen) {
@@ -301,8 +303,10 @@ static pj_status_t apply_msg_options(pj_stun_session *sess,
}
/* Add MESSAGE-INTEGRITY attribute */
- status = pj_stun_msg_add_msgint_attr(pool, msg);
- PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+ if (username.slen) {
+ status = pj_stun_msg_add_msgint_attr(pool, msg);
+ PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
+ }
/* Add FINGERPRINT attribute if necessary */
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index b168c9ad..3e39b15f 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -943,6 +943,12 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool,
PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL);
acc = &pjsua_var.acc[acc_id];
+ /* If force_contact is configured, then use use it */
+ if (acc->cfg.force_contact.slen) {
+ *contact = acc->cfg.force_contact;
+ return PJ_SUCCESS;
+ }
+
/* If route-set is configured for the account, then URI is the
* first entry of the route-set.
*/
@@ -1037,6 +1043,12 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool,
PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL);
acc = &pjsua_var.acc[acc_id];
+ /* If force_contact is configured, then use use it */
+ if (acc->cfg.force_contact.slen) {
+ *contact = acc->cfg.force_contact;
+ return PJ_SUCCESS;
+ }
+
/* If Record-Route is present, then URI is the top Record-Route. */
if (rdata->msg_info.record_route) {
sip_uri = (pjsip_sip_uri*)
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 116a51f5..8c6e3506 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -675,6 +675,13 @@ pj_status_t pjsua_resolve_stun_server(pj_bool_t wait)
pj_sockaddr_in_init(&pjsua_var.stun_srv.ipv4, NULL, 0);
pjsua_var.stun_srv.ipv4.sin_addr = *(pj_in_addr*)he.h_addr;
pjsua_var.stun_srv.ipv4.sin_port = pj_htons((pj_uint16_t)3478);
+
+ PJ_LOG(4,(THIS_FILE,
+ "STUN server %.*s resolved, address is %s:%d",
+ (int)pjsua_var.ua_cfg.stun_srv.slen,
+ pjsua_var.ua_cfg.stun_srv.ptr,
+ pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr),
+ (int)pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port)));
}
}
return pjsua_var.stun_status;
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 6c81583d..b8b0f33f 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -571,8 +571,7 @@ static pj_status_t create_ice_media_transports(pjsua_transport_config *cfg)
ice_st = pjmedia_ice_get_ice_st(pjsua_var.calls[i].med_tp);
/* Add host candidates for RTP */
- status = pj_ice_st_add_all_host_interfaces(ice_st, 1, 0,
- PJ_FALSE, NULL);
+ status = pj_ice_st_add_all_host_interfaces(ice_st, 1, 0);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error adding ICE host candidates",
status);
@@ -592,8 +591,7 @@ static pj_status_t create_ice_media_transports(pjsua_transport_config *cfg)
}
/* Add STUN server reflexive candidate for RTP */
- status = pj_ice_st_add_stun_interface(ice_st, 1, 0,
- PJ_FALSE, NULL);
+ status = pj_ice_st_add_stun_interface(ice_st, 1, 0, NULL);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error adding ICE address",
status);