diff options
Diffstat (limited to 'pjsip/src/pjsip/sip_util.c')
-rw-r--r-- | pjsip/src/pjsip/sip_util.c | 47 |
1 files changed, 47 insertions, 0 deletions
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); |