diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2008-06-26 19:12:09 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2008-06-26 19:12:09 +0000 |
commit | c2bf0b1ca18b3ccc8ccf3d580840900a0518e049 (patch) | |
tree | 1f8b388e0ef44d360e6a31b61ca900635fe04ace | |
parent | 349f63c0e6559210b51e31a6ee01fa17ad34baeb (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.h | 2 | ||||
-rw-r--r-- | pjmedia/include/pjmedia/transport_srtp.h | 12 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/transport_srtp.c | 27 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua_internal.h | 1 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_call.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 29 |
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) |