summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-05-29 13:04:03 +0000
committerBenny Prijono <bennylp@teluu.com>2009-05-29 13:04:03 +0000
commit08640cc9411ca092e6456304bcce41f81b3bd3ce (patch)
tree6d1ad4e6304b1fb8d95b00858648cfbcd829a2ea /pjsip
parentad8907b8ea9f5715c05b19b41ea7b85509591153 (diff)
Integration of Sipit24 branch, many tickets involved:
- #793: AMR encoder should regard 'mode-set' param specified by remote decoder. - #831: Automatically switch to TCP transport when sending large request - #832: Support for outbound proxy setting without using Route header - #849: Modify conference audio switch behavior in connecting ports. - #850: Remove 'Require=replaces' param in 'Refer-To' header (in call transfer with replaces). - #851: Support for regular nomination in ICE - #852: --ip-addr support for IPv6 for media transport in pjsua - #854: Adding SOFTWARE attribute in all outgoing requests may cause compatibility problem with older STUN server (thanks Alexei Kuznetsov for the report) - #855: Bug in digit map frequencies for DTMF digits (thanks FCCH for the report) - #856: Put back the ICE candidate priority values according to the default values in the draft-mmusic-ice - #857: Support for ICE keep-alive with Binding indication - #858: Do not authenticate STUN 438 response - #859: AMR-WB format param in the SDP is not negotiated correctly. - #867: Return error instead of asserting when PJSUA-LIB fails to open log file git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2724 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsip/sip_config.h15
-rw-r--r--pjsip/include/pjsip/sip_transport.h11
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h11
-rw-r--r--pjsip/src/pjsip/sip_msg.c35
-rw-r--r--pjsip/src/pjsip/sip_transaction.c13
-rw-r--r--pjsip/src/pjsip/sip_transport.c72
-rw-r--r--pjsip/src/pjsip/sip_ua_layer.c2
-rw-r--r--pjsip/src/pjsip/sip_util.c47
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c2
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c6
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c5
-rw-r--r--pjsip/src/test/msg_test.c10
12 files changed, 179 insertions, 50 deletions
diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
index 1db144c0..a171a096 100644
--- a/pjsip/include/pjsip/sip_config.h
+++ b/pjsip/include/pjsip/sip_config.h
@@ -227,6 +227,21 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
/**
+ * RFC 3261 section 18.1.1:
+ * If a request is within 200 bytes of the path MTU, or if it is larger
+ * than 1300 bytes and the path MTU is unknown, the request MUST be sent
+ * using an RFC 2914 [43] congestion controlled transport protocol, such
+ * as TCP.
+ *
+ * This setting controls the threshold of the UDP packet, which if it's
+ * larger than this value the request will be sent with TCP. Default is
+ * 1300 bytes.
+ */
+#ifndef PJSIP_UDP_SIZE_THRESHOLD
+# define PJSIP_UDP_SIZE_THRESHOLD 1300
+#endif
+
+/**
* Encode SIP headers in their short forms to reduce size. By default,
* SIP headers in outgoing messages will be encoded in their full names.
* If this option is enabled, then SIP headers for outgoing messages
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h
index 502a0b04..275196bf 100644
--- a/pjsip/include/pjsip/sip_transport.h
+++ b/pjsip/include/pjsip/sip_transport.h
@@ -580,6 +580,17 @@ PJ_DECL(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata );
PJ_DECL(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata );
/**
+ * Print the SIP message to transmit data buffer's internal buffer. This
+ * may allocate memory for the buffer, if the buffer has not been allocated
+ * yet, and encode the SIP message to that buffer.
+ *
+ * @param tdata The transmit buffer.
+ *
+ * @return PJ_SUCCESS on success of the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsip_tx_data_encode(pjsip_tx_data *tdata);
+
+/**
* Check if transmit data buffer contains a valid message.
*
* @param tdata The transmit buffer.
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index cb21ea07..95f5bf41 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -4260,9 +4260,16 @@ struct pjsua_media_config
pj_bool_t enable_ice;
/**
- * Disable ICE host candidates.
+ * Set the maximum number of host candidates.
+ *
+ * Default: -1 (maximum not set)
+ */
+ int ice_max_host_cands;
+
+ /**
+ * ICE session options.
*/
- pj_bool_t ice_no_host_cands;
+ pj_ice_sess_options ice_opt;
/**
* Disable RTCP component.
diff --git a/pjsip/src/pjsip/sip_msg.c b/pjsip/src/pjsip/sip_msg.c
index 53146b22..7ef55746 100644
--- a/pjsip/src/pjsip/sip_msg.c
+++ b/pjsip/src/pjsip/sip_msg.c
@@ -456,16 +456,18 @@ PJ_DEF(pj_ssize_t) pjsip_msg_print( const pjsip_msg *msg,
/* Print each of the headers. */
for (hdr=msg->hdr.next; hdr!=&msg->hdr; hdr=hdr->next) {
- len = (*hdr->vptr->print_on)(hdr, p, end-p);
- if (len < 1)
+ len = pjsip_hdr_print_on(hdr, p, end-p);
+ if (len < 0)
return -1;
- p += len;
- if (p+3 >= end)
- return -1;
+ if (len > 0) {
+ p += len;
+ if (p+3 >= end)
+ return -1;
- *p++ = '\r';
- *p++ = '\n';
+ *p++ = '\r';
+ *p++ = '\n';
+ }
}
/* Process message body. */
@@ -1601,6 +1603,25 @@ static int pjsip_routing_hdr_print( pjsip_routing_hdr *hdr,
char *startbuf = buf;
char *endbuf = buf + size;
const pjsip_parser_const_t *pc = pjsip_parser_const();
+ pjsip_sip_uri *sip_uri;
+ pjsip_param *p;
+
+ /* Check the proprietary param 'hide', don't print this header
+ * if it exists in the route URI.
+ */
+ sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(hdr->name_addr.uri);
+ p = sip_uri->other_param.next;
+ while (p != &sip_uri->other_param) {
+ const pj_str_t st_hide = {"hide", 4};
+
+ if (pj_stricmp(&p->name, &st_hide) == 0) {
+ /* Check if param 'hide' is specified without 'lr'. */
+ pj_assert(sip_uri->lr_param != 0);
+ return 0;
+ }
+ p = p->next;
+ }
+
/* Route and Record-Route don't compact forms */
copy_advance(buf, hdr->name);
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 525f9e37..d10906db 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -1725,6 +1725,19 @@ static void send_msg_callback( pjsip_send_state *send_state,
"will try next server. Err=%d (%s)",
pjsip_tx_data_get_info(send_state->tdata), -sent,
pj_strerror(-sent, errmsg, sizeof(errmsg)).ptr));
+
+ /* Reset retransmission count */
+ tsx->retransmit_count = 0;
+
+ /* And reset timeout timer */
+ if (tsx->timeout_timer.id) {
+ pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
+ tsx->timeout_timer.id = TIMER_INACTIVE;
+
+ tsx->timeout_timer.id = TIMER_ACTIVE;
+ pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
+ &timeout_timer_val);
+ }
}
}
diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
index 84b45a67..f34699be 100644
--- a/pjsip/src/pjsip/sip_transport.c
+++ b/pjsip/src/pjsip/sip_transport.c
@@ -434,6 +434,45 @@ PJ_DEF(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata )
tdata->info = NULL;
}
+/*
+ * Print the SIP message to transmit data buffer's internal buffer.
+ */
+PJ_DEF(pj_status_t) pjsip_tx_data_encode(pjsip_tx_data *tdata)
+{
+ /* Allocate buffer if necessary. */
+ if (tdata->buf.start == NULL) {
+ PJ_USE_EXCEPTION;
+
+ PJ_TRY {
+ tdata->buf.start = (char*)
+ pj_pool_alloc(tdata->pool, PJSIP_MAX_PKT_LEN);
+ }
+ PJ_CATCH_ANY {
+ return PJ_ENOMEM;
+ }
+ PJ_END
+
+ tdata->buf.cur = tdata->buf.start;
+ tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN;
+ }
+
+ /* Do we need to reprint? */
+ if (!pjsip_tx_data_is_valid(tdata)) {
+ pj_ssize_t size;
+
+ size = pjsip_msg_print( tdata->msg, tdata->buf.start,
+ tdata->buf.end - tdata->buf.start);
+ if (size < 0) {
+ return PJSIP_EMSGTOOLONG;
+ }
+ pj_assert(size != 0);
+ tdata->buf.cur[size] = '\0';
+ tdata->buf.cur += size;
+ }
+
+ return PJ_SUCCESS;
+}
+
PJ_DEF(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata )
{
return tdata->buf.cur != tdata->buf.start;
@@ -567,38 +606,7 @@ static void transport_send_callback(pjsip_transport *transport,
*/
static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata)
{
- /* Allocate buffer if necessary. */
- if (tdata->buf.start == NULL) {
- PJ_USE_EXCEPTION;
-
- PJ_TRY {
- tdata->buf.start = (char*)
- pj_pool_alloc(tdata->pool, PJSIP_MAX_PKT_LEN);
- }
- PJ_CATCH_ANY {
- return PJ_ENOMEM;
- }
- PJ_END
-
- tdata->buf.cur = tdata->buf.start;
- tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN;
- }
-
- /* Do we need to reprint? */
- if (!pjsip_tx_data_is_valid(tdata)) {
- pj_ssize_t size;
-
- size = pjsip_msg_print( tdata->msg, tdata->buf.start,
- tdata->buf.end - tdata->buf.start);
- if (size < 0) {
- return PJSIP_EMSGTOOLONG;
- }
- pj_assert(size != 0);
- tdata->buf.cur[size] = '\0';
- tdata->buf.cur += size;
- }
-
- return PJ_SUCCESS;
+ return pjsip_tx_data_encode(tdata);
}
/*
diff --git a/pjsip/src/pjsip/sip_ua_layer.c b/pjsip/src/pjsip/sip_ua_layer.c
index 7a7e2d53..5145142b 100644
--- a/pjsip/src/pjsip/sip_ua_layer.c
+++ b/pjsip/src/pjsip/sip_ua_layer.c
@@ -907,7 +907,7 @@ static void print_dialog( const char *title,
char userinfo[128];
len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));
- if (len < 1)
+ if (len < 0)
pj_ansi_strcpy(userinfo, "<--uri too long-->");
else
userinfo[len] = '\0';
diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c
index 381ccade..faf8bdb6 100644
--- a/pjsip/src/pjsip/sip_util.c
+++ b/pjsip/src/pjsip/sip_util.c
@@ -1135,6 +1135,8 @@ static void stateless_send_transport_cb( void *token,
via->sent_by = stateless_data->cur_transport->local_name;
via->rport_param = 0;
+ pjsip_tx_data_invalidate_msg(tdata);
+
/* Send message using this transport. */
status = pjsip_transport_send( stateless_data->cur_transport,
tdata,
@@ -1181,6 +1183,51 @@ stateless_send_resolver_callback( pj_status_t status,
/* Copy server addresses */
pj_memcpy( &stateless_data->addr, addr, sizeof(pjsip_server_addresses));
+ /* RFC 3261 section 18.1.1:
+ * If a request is within 200 bytes of the path MTU, or if it is larger
+ * than 1300 bytes and the path MTU is unknown, the request MUST be sent
+ * using an RFC 2914 [43] congestion controlled transport protocol, such
+ * as TCP.
+ */
+ if (stateless_data->tdata->msg->type == PJSIP_REQUEST_MSG &&
+ addr->count > 0 &&
+ addr->entry[0].type == PJSIP_TRANSPORT_UDP)
+ {
+ int len;
+
+ /* Encode the request */
+ status = pjsip_tx_data_encode(stateless_data->tdata);
+ if (status != PJ_SUCCESS) {
+ if (stateless_data->app_cb) {
+ pj_bool_t cont = PJ_FALSE;
+ (*stateless_data->app_cb)(stateless_data, -status, &cont);
+ }
+ pjsip_tx_data_dec_ref(stateless_data->tdata);
+ return;
+ }
+
+ /* Check if request message is larger than 1300 bytes. */
+ len = stateless_data->tdata->buf.cur -
+ stateless_data->tdata->buf.start;
+ if (len >= PJSIP_UDP_SIZE_THRESHOLD) {
+ int i;
+ int count = stateless_data->addr.count;
+
+ /* Insert "TCP version" of resolved UDP addresses at the
+ * beginning.
+ */
+ if (count * 2 > PJSIP_MAX_RESOLVED_ADDRESSES)
+ count = PJSIP_MAX_RESOLVED_ADDRESSES / 2;
+ for (i = 0; i < count; ++i) {
+ pj_memcpy(&stateless_data->addr.entry[i+count],
+ &stateless_data->addr.entry[i],
+ sizeof(stateless_data->addr.entry[0]));
+ stateless_data->addr.entry[i].type = PJSIP_TRANSPORT_TCP;
+ }
+ stateless_data->addr.count = count * 2;
+ }
+ }
+
/* Process the addresses. */
stateless_send_transport_cb( stateless_data, stateless_data->tdata,
-PJ_EPENDING);
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 5a34d0ea..6e9a9395 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -2694,7 +2694,7 @@ void print_call(const char *title,
/* Dump invite sesion info. */
len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));
- if (len < 1)
+ if (len < 0)
pj_ansi_strcpy(userinfo, "<--uri too long-->");
else
userinfo[len] = '\0';
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index b57b81e3..4cf8cd0e 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -182,6 +182,9 @@ PJ_DEF(void) pjsua_media_config_default(pjsua_media_config *cfg)
cfg->jb_init = cfg->jb_min_pre = cfg->jb_max_pre = cfg->jb_max = -1;
cfg->snd_auto_close_time = 1;
+ cfg->ice_max_host_cands = -1;
+ pj_ice_sess_options_default(&cfg->ice_opt);
+
cfg->turn_conn_type = PJ_TURN_TP_UDP;
}
@@ -647,7 +650,8 @@ PJ_DEF(pj_status_t) pjsua_init( const pjsua_config *ua_cfg,
/* Initialize logging first so that info/errors can be captured */
if (log_cfg) {
status = pjsua_reconfigure_logging(log_cfg);
- PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+ if (status != PJ_SUCCESS)
+ return status;
}
/* If nameserver is configured, create DNS resolver instance and
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 8d9643b3..b4d7f0dd 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -804,13 +804,16 @@ static pj_status_t create_ice_media_transports(void)
ice_cfg.af = pj_AF_INET();
ice_cfg.resolver = pjsua_var.resolver;
+ ice_cfg.opt = pjsua_var.media_cfg.ice_opt;
+
/* Configure STUN settings */
if (pj_sockaddr_has_addr(&pjsua_var.stun_srv)) {
pj_sockaddr_print(&pjsua_var.stun_srv, stunip, sizeof(stunip), 0);
ice_cfg.stun.server = pj_str(stunip);
ice_cfg.stun.port = pj_sockaddr_get_port(&pjsua_var.stun_srv);
}
- ice_cfg.stun.no_host_cands = pjsua_var.media_cfg.ice_no_host_cands;
+ if (pjsua_var.media_cfg.ice_max_host_cands >= 0)
+ ice_cfg.stun.max_host_cands = pjsua_var.media_cfg.ice_max_host_cands;
/* Configure TURN settings */
if (pjsua_var.media_cfg.enable_turn) {
diff --git a/pjsip/src/test/msg_test.c b/pjsip/src/test/msg_test.c
index d4a7f14b..3bb58f69 100644
--- a/pjsip/src/test/msg_test.c
+++ b/pjsip/src/test/msg_test.c
@@ -365,16 +365,16 @@ parse_msg:
hdr2 = ref_msg->hdr.next;
while (hdr1 != &parsed_msg->hdr && hdr2 != &ref_msg->hdr) {
- len = hdr1->vptr->print_on(hdr1, str1.ptr, BUFLEN);
- if (len < 1) {
+ len = pjsip_hdr_print_on(hdr1, str1.ptr, BUFLEN);
+ if (len < 0) {
status = -40;
goto on_return;
}
str1.ptr[len] = '\0';
str1.slen = len;
- len = hdr2->vptr->print_on(hdr2, str2.ptr, BUFLEN);
- if (len < 1) {
+ len = pjsip_hdr_print_on(hdr2, str2.ptr, BUFLEN);
+ if (len < 0) {
status = -50;
goto on_return;
}
@@ -1944,7 +1944,7 @@ static int hdr_test(void)
/* Print the parsed header*/
output = (char*) pj_pool_alloc(pool, 1024);
len = pjsip_hdr_print_on(parsed_hdr1, output, 1024);
- if (len < 1 || len >= 1024) {
+ if (len < 0 || len >= 1024) {
PJ_LOG(3,(THIS_FILE, " header too long: %s: %s", test->hname, test->hcontent));
return -530;
}