Ignore:
Timestamp:
Feb 3, 2007 8:31:33 PM (15 years ago)
Author:
bennylp
Message:

ICE branch: initial server prototype

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/iceproject/pjlib-util/src/pjlib-util/stun_transaction.c

    r913 r929  
    1 /* $Id */ 
     1/* $Id$ */ 
    22/*  
    33 * Copyright (C) 2003-2005 Benny Prijono <benny@prijono.org> 
     
    3939    pj_uint32_t          tsx_id[4]; 
    4040 
     41    pj_bool_t            require_retransmit; 
    4142    pj_timer_entry       timer; 
    4243    unsigned             transmit_count; 
     
    109110 
    110111/* 
    111  * . 
     112 * Set user data. 
    112113 */ 
    113114PJ_DEF(pj_status_t) pj_stun_client_tsx_set_data(pj_stun_client_tsx *tsx, 
     
    121122 
    122123/* 
    123  * . 
     124 * Get the user data 
    124125 */ 
    125126PJ_DEF(void*) pj_stun_client_tsx_get_data(pj_stun_client_tsx *tsx) 
     
    139140    PJ_ASSERT_RETURN(tsx->timer.id == 0, PJ_EBUSY); 
    140141 
    141     /* Calculate retransmit/timeout delay */ 
    142     if (tsx->transmit_count == 0) { 
    143         tsx->retransmit_time.sec = 0; 
    144         tsx->retransmit_time.msec = tsx->endpt->rto_msec; 
    145  
    146     } else if (tsx->transmit_count < PJ_STUN_MAX_RETRANSMIT_COUNT) { 
    147         unsigned msec; 
    148  
    149         msec = PJ_TIME_VAL_MSEC(tsx->retransmit_time); 
    150         msec = (msec >> 1) + 100; 
    151         tsx->retransmit_time.sec = msec / 1000; 
    152         tsx->retransmit_time.msec = msec % 100; 
    153  
    154     } else { 
    155         tsx->retransmit_time.sec = PJ_STUN_TIMEOUT_VALUE / 1000; 
    156         tsx->retransmit_time.msec = PJ_STUN_TIMEOUT_VALUE % 1000; 
    157     } 
    158  
    159     /* Schedule timer first because when send_msg() failed we can 
    160      * cancel it (as opposed to when schedule_timer() failed we cannot 
    161      * cancel transmission). 
    162      */ 
    163     status = pj_timer_heap_schedule(tsx->endpt->timer_heap, &tsx->timer, 
    164                                     &tsx->retransmit_time); 
    165     if (status != PJ_SUCCESS) { 
    166         tsx->timer.id = 0; 
    167         return status; 
     142    if (tsx->require_retransmit) { 
     143        /* Calculate retransmit/timeout delay */ 
     144        if (tsx->transmit_count == 0) { 
     145            tsx->retransmit_time.sec = 0; 
     146            tsx->retransmit_time.msec = tsx->endpt->rto_msec; 
     147 
     148        } else if (tsx->transmit_count < PJ_STUN_MAX_RETRANSMIT_COUNT) { 
     149            unsigned msec; 
     150 
     151            msec = PJ_TIME_VAL_MSEC(tsx->retransmit_time); 
     152            msec = (msec >> 1) + 100; 
     153            tsx->retransmit_time.sec = msec / 1000; 
     154            tsx->retransmit_time.msec = msec % 100; 
     155 
     156        } else { 
     157            tsx->retransmit_time.sec = PJ_STUN_TIMEOUT_VALUE / 1000; 
     158            tsx->retransmit_time.msec = PJ_STUN_TIMEOUT_VALUE % 1000; 
     159        } 
     160 
     161        /* Schedule timer first because when send_msg() failed we can 
     162         * cancel it (as opposed to when schedule_timer() failed we cannot 
     163         * cancel transmission). 
     164         */ 
     165        status = pj_timer_heap_schedule(tsx->endpt->timer_heap, &tsx->timer, 
     166                                        &tsx->retransmit_time); 
     167        if (status != PJ_SUCCESS) { 
     168            tsx->timer.id = 0; 
     169            return status; 
     170        } 
    168171    } 
    169172 
     
    172175    status = tsx->cb.on_send_msg(tsx, tsx->last_pkt, tsx->last_pkt_size); 
    173176    if (status != PJ_SUCCESS) { 
    174         pj_timer_heap_cancel(tsx->endpt->timer_heap, &tsx->timer); 
    175         tsx->timer.id = 0; 
     177        if (tsx->timer.id != 0) { 
     178            pj_timer_heap_cancel(tsx->endpt->timer_heap, &tsx->timer); 
     179            tsx->timer.id = 0; 
     180        } 
    176181        stun_perror(tsx, "STUN error sending message", status); 
    177182        return status; 
     
    185190} 
    186191 
    187 /* 
    188  * . 
     192 
     193/* 
     194 * Send outgoing message and start STUN transaction. 
    189195 */ 
    190196PJ_DEF(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx, 
     197                                                pj_bool_t retransmit, 
    191198                                                const pj_stun_msg *msg) 
    192199{ 
     
    208215    pj_memcpy(&tsx->tsx_id[1], msg->hdr.tsx_id, 12); 
    209216 
     217    /* Update STUN retransmit flag */ 
     218    tsx->require_retransmit = retransmit; 
     219 
     220    /* Send the message */ 
    210221    return tsx_transmit_msg(tsx); 
    211222} 
     
    243254 
    244255/* 
    245  *  
     256 * Notify the STUN transaction about the arrival of STUN response. 
    246257 */ 
    247258PJ_DEF(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx, 
     
    292303    err_attr = (pj_stun_error_code_attr*)  
    293304                pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ERROR_CODE, 0); 
    294     if (err_attr->err_class == 1) { 
     305 
     306    if (err_attr && err_attr->err_class <= 2) { 
     307        /* draft-ietf-behave-rfc3489bis-05.txt Section 8.3.2: 
     308         * Any response between 100 and 299 MUST result in the cessation 
     309         * of request retransmissions, but otherwise is discarded. 
     310         */ 
    295311        PJ_LOG(4,(tsx->obj_name,  
    296312                  "STUN rx_msg() error: received provisional %d code (%.*s)", 
     
    301317    } 
    302318 
    303     if (err_attr==NULL || err_attr->err_class == 2) { 
     319    if (err_attr == NULL) { 
    304320        status = PJ_SUCCESS; 
    305321    } else { 
Note: See TracChangeset for help on using the changeset viewer.