summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2008-06-26 19:12:09 +0000
committerNanang Izzuddin <nanang@teluu.com>2008-06-26 19:12:09 +0000
commitc2bf0b1ca18b3ccc8ccf3d580840900a0518e049 (patch)
tree1f8b388e0ef44d360e6a31b61ca900635fe04ace
parent349f63c0e6559210b51e31a6ee01fa17ad34baeb (diff)
Ticket #544: Fixed SRTP on hold+reinvite scenario
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2064 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia/config.h2
-rw-r--r--pjmedia/include/pjmedia/transport_srtp.h12
-rw-r--r--pjmedia/src/pjmedia/transport_srtp.c27
-rw-r--r--pjsip/include/pjsua-lib/pjsua_internal.h1
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c1
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c29
6 files changed, 58 insertions, 14 deletions
diff --git a/pjmedia/include/pjmedia/config.h b/pjmedia/include/pjmedia/config.h
index 7deae256..f6bf3707 100644
--- a/pjmedia/include/pjmedia/config.h
+++ b/pjmedia/include/pjmedia/config.h
@@ -609,7 +609,7 @@
* Maximum size in bytes of storage buffer of a transport specific info.
*/
#ifndef PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE
-# define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE (12*sizeof(long))
+# define PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXSIZE (16*sizeof(long))
#endif
diff --git a/pjmedia/include/pjmedia/transport_srtp.h b/pjmedia/include/pjmedia/transport_srtp.h
index d622a0a7..d94d9a23 100644
--- a/pjmedia/include/pjmedia/transport_srtp.h
+++ b/pjmedia/include/pjmedia/transport_srtp.h
@@ -138,7 +138,7 @@ typedef struct pjmedia_srtp_setting
/**
* Specify the usage policy. Default is PJMEDIA_SRTP_OPTIONAL.
*/
- pjmedia_srtp_use use;
+ pjmedia_srtp_use use;
/**
* Specify whether the SRTP transport should close the member transport
@@ -180,6 +180,16 @@ typedef struct pjmedia_srtp_info
*/
pjmedia_srtp_crypto tx_policy;
+ /**
+ * Specify the usage policy.
+ */
+ pjmedia_srtp_use use;
+
+ /**
+ * Specify the peer's usage policy.
+ */
+ pjmedia_srtp_use peer_use;
+
} pjmedia_srtp_info;
diff --git a/pjmedia/src/pjmedia/transport_srtp.c b/pjmedia/src/pjmedia/transport_srtp.c
index ff18aedf..acb777f7 100644
--- a/pjmedia/src/pjmedia/transport_srtp.c
+++ b/pjmedia/src/pjmedia/transport_srtp.c
@@ -111,13 +111,12 @@ typedef struct transport_srtp
/* Transport information */
pjmedia_transport *member_tp; /**< Underlying transport. */
- /* When in SRTP optional mode, instead of always offering RTP/AVP,
- * we should create offer based on remote preference. At the first time,
- * remote preference is unknown, it is known after media_start() called.
- * So next time the same session need to create an offer, it will create
- * SDP with transport type based on remote preference.
+ /* SRTP usage policy of peer. This field is updated when media is starting.
+ * This is useful when SRTP is in optional mode and peer is using mandatory
+ * mode, so when local is about to reinvite/update, it should offer
+ * RTP/SAVP instead of offering RTP/AVP.
*/
- pj_bool_t remote_prefer_rtp_savp;
+ pjmedia_srtp_use peer_use;
} transport_srtp;
@@ -348,7 +347,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_create(
srtp->pool = pool;
srtp->session_inited = PJ_FALSE;
srtp->bypass_srtp = PJ_FALSE;
- srtp->remote_prefer_rtp_savp = PJ_FALSE;
+ srtp->peer_use = opt->use;
if (opt) {
srtp->setting = *opt;
@@ -586,6 +585,8 @@ static pj_status_t transport_get_info(pjmedia_transport *tp,
srtp_info.active = srtp->session_inited;
srtp_info.rx_policy = srtp->rx_policy;
srtp_info.tx_policy = srtp->tx_policy;
+ srtp_info.use = srtp->setting.use;
+ srtp_info.peer_use = srtp->peer_use;
spc_info_idx = info->specific_info_cnt++;
info->spc_info[spc_info_idx].type = PJMEDIA_TRANSPORT_TYPE_SRTP;
@@ -1076,8 +1077,9 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
case PJMEDIA_SRTP_DISABLED:
goto BYPASS_SRTP;
case PJMEDIA_SRTP_OPTIONAL:
- m_loc->desc.transport = srtp->remote_prefer_rtp_savp?
- ID_RTP_SAVP : ID_RTP_AVP;
+ m_loc->desc.transport =
+ (srtp->peer_use == PJMEDIA_SRTP_MANDATORY)?
+ ID_RTP_SAVP : ID_RTP_AVP;
break;
case PJMEDIA_SRTP_MANDATORY:
m_loc->desc.transport = ID_RTP_SAVP;
@@ -1283,8 +1285,10 @@ static pj_status_t transport_media_start(pjmedia_transport *tp,
m_rem = sdp_remote->media[media_index];
m_loc = sdp_local->media[media_index];
- srtp->remote_prefer_rtp_savp = (pj_stricmp(&m_rem->desc.transport,
- &ID_RTP_SAVP) == 0);
+ if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0)
+ srtp->peer_use = PJMEDIA_SRTP_MANDATORY;
+ else
+ srtp->peer_use = PJMEDIA_SRTP_OPTIONAL;
/* For answerer side, this function will just have to start SRTP */
@@ -1382,6 +1386,7 @@ static pj_status_t transport_media_start(pjmedia_transport *tp,
BYPASS_SRTP:
srtp->bypass_srtp = PJ_TRUE;
+ srtp->peer_use = PJMEDIA_SRTP_DISABLED;
PROPAGATE_MEDIA_START:
return pjmedia_transport_media_start(srtp->member_tp, pool,
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index 02ba5979..6865344d 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -74,6 +74,7 @@ typedef struct pjsua_call
pj_timer_entry refresh_tm;/**< Timer to send re-INVITE. */
pj_timer_entry hangup_tm; /**< Timer to hangup call. */
pj_stun_nat_type rem_nat_type; /**< NAT type of remote endpoint. */
+ pjmedia_srtp_use rem_srtp_use; /**< Remote's SRTP usage policy. */
char last_text_buf_[128]; /**< Buffer for last_text. */
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index b5482957..d12ea9d2 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -115,6 +115,7 @@ static void reset_call(pjsua_call_id id)
call->res_time.sec = 0;
call->res_time.msec = 0;
call->rem_nat_type = PJ_STUN_NAT_TYPE_UNKNOWN;
+ call->rem_srtp_use = PJMEDIA_SRTP_DISABLED;
}
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 7d2742f6..84b85101 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -888,7 +888,14 @@ pj_status_t pjsua_media_channel_init(pjsua_call_id call_id,
/* Always create SRTP adapter */
pjmedia_srtp_setting_default(&srtp_opt);
srtp_opt.close_member_tp = PJ_FALSE;
- srtp_opt.use = acc->cfg.use_srtp;
+ /* If media session has been ever established, let's use remote's
+ * preference in SRTP usage policy, especially when it is stricter.
+ */
+ if (call->rem_srtp_use > acc->cfg.use_srtp)
+ srtp_opt.use = call->rem_srtp_use;
+ else
+ srtp_opt.use = acc->cfg.use_srtp;
+
status = pjmedia_transport_srtp_create(pjsua_var.med_endpt,
call->med_tp,
&srtp_opt, &srtp);
@@ -1143,6 +1150,9 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
}
} else {
+ pjmedia_srtp_info srtp_info;
+ pjmedia_transport_info tp_info;
+
/* Start/restart media transport */
status = pjmedia_transport_media_start(call->med_tp,
call->inv->pool,
@@ -1152,6 +1162,23 @@ pj_status_t pjsua_media_channel_update(pjsua_call_id call_id,
call->med_tp_st = PJSUA_MED_TP_RUNNING;
+ /* Get remote SRTP usage policy */
+ pjmedia_transport_info_init(&tp_info);
+ pjmedia_transport_get_info(call->med_tp, &tp_info);
+ if (tp_info.specific_info_cnt > 0) {
+ int i;
+ for (i = 0; i < tp_info.specific_info_cnt; ++i) {
+ if (tp_info.spc_info[i].type == PJMEDIA_TRANSPORT_TYPE_SRTP)
+ {
+ pjmedia_srtp_info *srtp_info =
+ (pjmedia_srtp_info*) tp_info.spc_info[i].buffer;
+
+ call->rem_srtp_use = srtp_info->peer_use;
+ break;
+ }
+ }
+ }
+
/* Override ptime, if this option is specified. */
if (pjsua_var.media_cfg.ptime != 0) {
si->param->setting.frm_per_pkt = (pj_uint8_t)