diff options
author | Benny Prijono <bennylp@teluu.com> | 2009-05-29 13:04:03 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2009-05-29 13:04:03 +0000 |
commit | 08640cc9411ca092e6456304bcce41f81b3bd3ce (patch) | |
tree | 6d1ad4e6304b1fb8d95b00858648cfbcd829a2ea /pjsip | |
parent | ad8907b8ea9f5715c05b19b41ea7b85509591153 (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.h | 15 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_transport.h | 11 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 11 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_msg.c | 35 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transaction.c | 13 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 72 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_ua_layer.c | 2 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_util.c | 47 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_call.c | 2 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 6 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_media.c | 5 | ||||
-rw-r--r-- | pjsip/src/test/msg_test.c | 10 |
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; } |