Ignore:
Timestamp:
Oct 9, 2009 12:11:07 PM (13 years ago)
Author:
bennylp
Message:

Fixed ticket #917, #936, and #967:

  • #917: CANCEL may be sent to different servers than the INVITE when DNS SRV is used (thanks Alexei Kuznetsov for the report)
  • #936: CANCEL must be sent with TCP if the INVITE was sent with TCP because of 1300 bytes message size/MTU limit (thanks Johan Lantz for the report)
  • #967: Wrong Route header generation in CANCEL request with strict route

Save the server address(es) found by resolution process to tx_data, which is copied to CANCEL request. CANCEL request then uses this address rather than starting a fresh server resolution.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_util.c

    r2855 r2932  
    755755    } 
    756756 
     757    /* Must also copy the saved strict route header, otherwise CANCEL will be 
     758     * sent with swapped Route and request URI! 
     759     */ 
     760    if (req_tdata->saved_strict_route) { 
     761        cancel_tdata->saved_strict_route = (pjsip_route_hdr*) 
     762            pjsip_hdr_clone(cancel_tdata->pool, req_tdata->saved_strict_route); 
     763    } 
     764 
     765    /* Finally copy the destination info from the original request */ 
     766    pj_memcpy(&cancel_tdata->dest_info, &req_tdata->dest_info, 
     767              sizeof(req_tdata->dest_info)); 
     768 
    757769    /* Done. 
    758770     * Return the transmit buffer containing the CANCEL request. 
     
    10581070             */ 
    10591071            cont = (sent > 0) ? PJ_FALSE : 
    1060                    (stateless_data->cur_addr<stateless_data->addr.count-1); 
     1072                   (tdata->dest_info.cur_addr<tdata->dest_info.addr.count-1); 
    10611073            if (stateless_data->app_cb) { 
    10621074                (*stateless_data->app_cb)(stateless_data, sent, &cont); 
     
    10851097         */ 
    10861098        if (sent != -PJ_EPENDING) { 
    1087             stateless_data->cur_addr++; 
     1099            tdata->dest_info.cur_addr++; 
    10881100        } 
    10891101 
    10901102        /* Have next address? */ 
    1091         if (stateless_data->cur_addr >= stateless_data->addr.count) { 
     1103        if (tdata->dest_info.cur_addr >= tdata->dest_info.addr.count) { 
    10921104            /* This only happens when a rather buggy application has 
    10931105             * sent 'cont' to PJ_TRUE when the initial value was PJ_FALSE. 
     
    11011113 
    11021114        /* Keep current server address information handy. */ 
    1103         cur_addr = &stateless_data->addr.entry[stateless_data->cur_addr].addr; 
    1104         cur_addr_type = stateless_data->addr.entry[stateless_data->cur_addr].type; 
    1105         cur_addr_len = stateless_data->addr.entry[stateless_data->cur_addr].addr_len; 
     1115        cur_addr = &tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr; 
     1116        cur_addr_type = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].type; 
     1117        cur_addr_len = tdata->dest_info.addr.entry[tdata->dest_info.cur_addr].addr_len; 
    11061118 
    11071119        /* Acquire transport. */ 
     
    11791191{ 
    11801192    pjsip_send_state *stateless_data = (pjsip_send_state*) token; 
     1193    pjsip_tx_data *tdata = stateless_data->tdata; 
    11811194 
    11821195    /* Fail on server resolution. */ 
     
    11861199            (*stateless_data->app_cb)(stateless_data, -status, &cont); 
    11871200        } 
    1188         pjsip_tx_data_dec_ref(stateless_data->tdata); 
     1201        pjsip_tx_data_dec_ref(tdata); 
    11891202        return; 
    11901203    } 
    11911204 
    11921205    /* Copy server addresses */ 
    1193     pj_memcpy( &stateless_data->addr, addr, sizeof(pjsip_server_addresses)); 
     1206    if (addr && addr != &tdata->dest_info.addr) { 
     1207        pj_memcpy( &tdata->dest_info.addr, addr,  
     1208                   sizeof(pjsip_server_addresses)); 
     1209    } 
     1210    pj_assert(tdata->dest_info.addr.count != 0); 
    11941211 
    11951212#if !defined(PJSIP_DONT_SWITCH_TO_TCP) || PJSIP_DONT_SWITCH_TO_TCP==0 
     
    12001217     * as TCP. 
    12011218     */ 
    1202     if (stateless_data->tdata->msg->type == PJSIP_REQUEST_MSG && 
    1203         addr->count > 0 &&  
    1204         addr->entry[0].type == PJSIP_TRANSPORT_UDP) 
     1219    if (tdata->msg->type == PJSIP_REQUEST_MSG && 
     1220        tdata->dest_info.addr.count > 0 &&  
     1221        tdata->dest_info.addr.entry[0].type == PJSIP_TRANSPORT_UDP) 
    12051222    { 
    12061223        int len; 
    12071224 
    12081225        /* Encode the request */ 
    1209         status = pjsip_tx_data_encode(stateless_data->tdata); 
     1226        status = pjsip_tx_data_encode(tdata); 
    12101227        if (status != PJ_SUCCESS) { 
    12111228            if (stateless_data->app_cb) { 
     
    12131230                (*stateless_data->app_cb)(stateless_data, -status, &cont); 
    12141231            } 
    1215             pjsip_tx_data_dec_ref(stateless_data->tdata); 
     1232            pjsip_tx_data_dec_ref(tdata); 
    12161233            return; 
    12171234        } 
    12181235 
    12191236        /* Check if request message is larger than 1300 bytes. */ 
    1220         len = stateless_data->tdata->buf.cur -  
    1221                 stateless_data->tdata->buf.start; 
     1237        len = tdata->buf.cur - tdata->buf.start; 
    12221238        if (len >= PJSIP_UDP_SIZE_THRESHOLD) { 
    12231239            int i; 
    1224             int count = stateless_data->addr.count; 
     1240            int count = tdata->dest_info.addr.count; 
     1241 
     1242            PJ_LOG(5,(THIS_FILE, "%s exceeds UDP size threshold (%u), " 
     1243                                 "sending with TCP", 
     1244                                 pjsip_tx_data_get_info(tdata), 
     1245                                 PJSIP_UDP_SIZE_THRESHOLD)); 
    12251246 
    12261247            /* Insert "TCP version" of resolved UDP addresses at the 
     
    12301251                count = PJSIP_MAX_RESOLVED_ADDRESSES / 2; 
    12311252            for (i = 0; i < count; ++i) { 
    1232                 pj_memcpy(&stateless_data->addr.entry[i+count], 
    1233                           &stateless_data->addr.entry[i], 
    1234                           sizeof(stateless_data->addr.entry[0])); 
    1235                 stateless_data->addr.entry[i].type = PJSIP_TRANSPORT_TCP; 
     1253                pj_memcpy(&tdata->dest_info.addr.entry[i+count], 
     1254                          &tdata->dest_info.addr.entry[i], 
     1255                          sizeof(tdata->dest_info.addr.entry[0])); 
     1256                tdata->dest_info.addr.entry[i].type = PJSIP_TRANSPORT_TCP; 
    12361257            } 
    1237             stateless_data->addr.count = count * 2; 
     1258            tdata->dest_info.addr.count = count * 2; 
    12381259        } 
    12391260    } 
     
    12411262 
    12421263    /* Process the addresses. */ 
    1243     stateless_send_transport_cb( stateless_data, stateless_data->tdata, 
    1244                                  -PJ_EPENDING); 
     1264    stateless_send_transport_cb( stateless_data, tdata, -PJ_EPENDING); 
    12451265} 
    12461266 
     
    12761296    stateless_data->app_cb = cb; 
    12771297 
    1278     /* Resolve destination host. 
    1279      * The processing then resumed when the resolving callback is called. 
    1280      */ 
    1281     pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data, 
    1282                          &stateless_send_resolver_callback); 
     1298    /* If destination info has not been initialized (this applies for most 
     1299     * all requests except CANCEL), resolve destination host. The processing 
     1300     * then resumed when the resolving callback is called. For CANCEL, the 
     1301     * destination info must have been copied from the original INVITE so 
     1302     * proceed to sending the request directly. 
     1303     */ 
     1304    if (tdata->dest_info.addr.count == 0) { 
     1305        pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data, 
     1306                             &stateless_send_resolver_callback); 
     1307    } else { 
     1308        PJ_LOG(5,(THIS_FILE, "%s: skipping target resolution because " 
     1309                             "address is already set", 
     1310                             pjsip_tx_data_get_info(tdata))); 
     1311        stateless_send_resolver_callback(PJ_SUCCESS, stateless_data, 
     1312                                         &tdata->dest_info.addr); 
     1313    } 
    12831314    return PJ_SUCCESS; 
    12841315} 
     
    15911622 
    15921623    /* Update address in send_state. */ 
    1593     send_state->addr = *addr; 
     1624    pj_memcpy(&send_state->tdata->dest_info.addr, addr, sizeof(*addr)); 
    15941625 
    15951626    /* Send response using the transoprt. */ 
Note: See TracChangeset for help on using the changeset viewer.