Ignore:
Timestamp:
Mar 2, 2007 7:06:05 PM (17 years ago)
Author:
bennylp
Message:

Finishing up client-side STUN authentication, a simple STUN client, and simple STUN server

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c

    r1030 r1034  
    3838 
    3939    pj_stun_tx_data      pending_request_list; 
     40    pj_stun_tx_data      cached_response_list; 
    4041}; 
    4142 
     
    104105    tdata = sess->pending_request_list.next; 
    105106    while (tdata != &sess->pending_request_list) { 
    106         pj_assert(sizeof(tdata->client_key)==sizeof(msg->hdr.tsx_id)); 
    107         if (pj_memcmp(tdata->client_key, msg->hdr.tsx_id,  
     107        pj_assert(sizeof(tdata->msg_key)==sizeof(msg->hdr.tsx_id)); 
     108        if (tdata->msg_magic == msg->hdr.magic && 
     109            pj_memcmp(tdata->msg_key, msg->hdr.tsx_id,  
    108110                      sizeof(msg->hdr.tsx_id))==0) 
    109111        { 
     
    159161 
    160162    /* copy the request's transaction ID as the transaction key. */ 
    161     pj_assert(sizeof(tdata->client_key)==sizeof(tdata->msg->hdr.tsx_id)); 
    162     pj_memcpy(tdata->client_key, tdata->msg->hdr.tsx_id, 
     163    pj_assert(sizeof(tdata->msg_key)==sizeof(tdata->msg->hdr.tsx_id)); 
     164    tdata->msg_magic = tdata->msg->hdr.magic; 
     165    pj_memcpy(tdata->msg_key, tdata->msg->hdr.tsx_id, 
    163166              sizeof(tdata->msg->hdr.tsx_id)); 
    164167 
     
    175178        tdata->client_tsx = NULL; 
    176179    } 
    177  
     180    if (tdata->res_timer.id != PJ_FALSE) { 
     181        pj_timer_heap_cancel(tdata->sess->endpt->timer_heap,  
     182                             &tdata->res_timer); 
     183        tdata->res_timer.id = PJ_FALSE; 
     184    } 
    178185    pj_pool_release(tdata->pool); 
    179186} 
     
    187194    PJ_UNUSED_ARG(sess); 
    188195    destroy_tdata(tdata); 
     196} 
     197 
     198 
     199/* Timer callback to be called when it's time to destroy response cache */ 
     200static void on_cache_timeout(pj_timer_heap_t *timer_heap, 
     201                             struct pj_timer_entry *entry) 
     202{ 
     203    pj_stun_tx_data *tdata; 
     204 
     205    PJ_UNUSED_ARG(timer_heap); 
     206 
     207    entry->id = PJ_FALSE; 
     208    tdata = (pj_stun_tx_data*) entry->user_data; 
     209 
     210    PJ_LOG(5,(SNAME(tdata->sess), "Response cache deleted")); 
     211 
     212    pj_list_erase(tdata); 
     213    pj_stun_msg_destroy_tdata(tdata->sess, tdata); 
    189214} 
    190215 
     
    329354 
    330355    pj_list_init(&sess->pending_request_list); 
     356    pj_list_init(&sess->cached_response_list); 
    331357 
    332358    status = pj_mutex_create_recursive(pool, name, &sess->mutex); 
     
    500526 
    501527    /* copy the request's transaction ID as the transaction key. */ 
    502     pj_assert(sizeof(tdata->client_key)==sizeof(req->hdr.tsx_id)); 
    503     pj_memcpy(tdata->client_key, req->hdr.tsx_id, sizeof(req->hdr.tsx_id)); 
     528    pj_assert(sizeof(tdata->msg_key)==sizeof(req->hdr.tsx_id)); 
     529    tdata->msg_magic = req->hdr.magic; 
     530    pj_memcpy(tdata->msg_key, req->hdr.tsx_id, sizeof(req->hdr.tsx_id)); 
    504531 
    505532    *p_tdata = tdata; 
     
    553580    PJ_ASSERT_RETURN(sess && addr_len && server && tdata, PJ_EINVAL); 
    554581 
     582    tdata->options = options; 
     583 
    555584    /* Allocate packet */ 
    556585    tdata->max_len = PJ_STUN_MAX_PKT_LEN; 
     
    612641 
    613642    } else { 
     643        if ((options & PJ_STUN_CACHE_RESPONSE) &&  
     644            (PJ_STUN_IS_RESPONSE(tdata->msg->hdr.type) || 
     645             PJ_STUN_IS_ERROR_RESPONSE(tdata->msg->hdr.type)))  
     646        { 
     647            /* Requested to keep the response in the cache */ 
     648            pj_time_val timeout; 
     649             
     650            pj_memset(&tdata->res_timer, 0, sizeof(tdata->res_timer)); 
     651            pj_timer_entry_init(&tdata->res_timer, PJ_TRUE, tdata,  
     652                                &on_cache_timeout); 
     653 
     654            timeout.sec = sess->endpt->res_cache_msec / 1000; 
     655            timeout.msec = sess->endpt->res_cache_msec % 1000; 
     656 
     657            status = pj_timer_heap_schedule(sess->endpt->timer_heap,  
     658                                            &tdata->res_timer, 
     659                                            &timeout); 
     660            if (status != PJ_SUCCESS) { 
     661                pj_stun_msg_destroy_tdata(sess, tdata); 
     662                pj_mutex_unlock(sess->mutex); 
     663                LOG_ERR_(sess, "Error scheduling response timer", status); 
     664                return status; 
     665            } 
     666 
     667            pj_list_push_back(&sess->cached_response_list, tdata); 
     668        } 
     669     
    614670        /* Otherwise for non-request message, send directly to transport. */ 
    615671        status = sess->cb.on_send_msg(sess, tdata->pkt, tdata->pkt_size, 
     
    620676        } 
    621677 
    622         /* Destroy */ 
    623         pj_stun_msg_destroy_tdata(sess, tdata); 
     678        /* Destroy only when response is not cached*/ 
     679        if (tdata->res_timer.id == 0) { 
     680            pj_stun_msg_destroy_tdata(sess, tdata); 
     681        } 
    624682    } 
    625683 
     
    640698    tdata = tsx_lookup(sess, msg); 
    641699    if (tdata == NULL) { 
    642         LOG_ERR_(sess, "STUN error finding transaction", PJ_ENOTFOUND); 
    643         return PJ_ENOTFOUND; 
     700        PJ_LOG(4,(SNAME(sess),  
     701                  "Transaction not found, response silently discarded")); 
     702        return PJ_SUCCESS; 
    644703    } 
    645704 
     
    708767                                       unsigned src_addr_len) 
    709768{ 
     769    pj_stun_tx_data *t; 
    710770    pj_status_t status; 
     771 
     772    /* First lookup response in response cache */ 
     773    t = sess->cached_response_list.next; 
     774    while (t != &sess->cached_response_list) { 
     775        if (t->msg_magic == msg->hdr.magic && 
     776            pj_memcmp(t->msg_key, msg->hdr.tsx_id,  
     777                      sizeof(msg->hdr.tsx_id))==0) 
     778        { 
     779            break; 
     780        } 
     781        t = t->next; 
     782    } 
     783 
     784    if (t != &sess->cached_response_list) { 
     785        /* Found response in the cache */ 
     786        unsigned options; 
     787 
     788        PJ_LOG(5,(SNAME(sess),  
     789                 "Request retransmission, sending cached response")); 
     790 
     791        options = t->options; 
     792        options &= ~PJ_STUN_CACHE_RESPONSE; 
     793        pj_stun_session_send_msg(sess, options, src_addr, src_addr_len, t); 
     794        return PJ_SUCCESS; 
     795    } 
    711796 
    712797    /* Distribute to handler, or respond with Bad Request */ 
     
    726811    } 
    727812 
    728     return status;     
     813    return status; 
    729814} 
    730815 
Note: See TracChangeset for help on using the changeset viewer.