Ignore:
Timestamp:
Mar 20, 2008 4:32:06 PM (16 years ago)
Author:
bennylp
Message:

More ticket #485: client and server self tested

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/src/pjnath/turn_udp.c

    r1869 r1879  
    2020#include <pj/assert.h> 
    2121#include <pj/errno.h> 
     22#include <pj/lock.h> 
    2223#include <pj/log.h> 
    2324#include <pj/pool.h> 
    2425#include <pj/ioqueue.h> 
     26 
     27enum 
     28{ 
     29    TIMER_NONE, 
     30    TIMER_DESTROY 
     31}; 
    2532 
    2633struct pj_turn_udp 
     
    3037    pj_turn_udp_cb       cb; 
    3138    void                *user_data; 
     39 
     40    pj_lock_t           *lock; 
     41 
     42    pj_bool_t            destroy_request; 
     43    pj_timer_heap_t     *timer_heap; 
     44    pj_timer_entry       timer; 
    3245 
    3346    pj_sock_t            sock; 
     
    6578 
    6679 
     80static void destroy(pj_turn_udp *udp_rel); 
     81static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e); 
     82 
     83 
    6784/* 
    6885 * Create. 
     
    92109    if (cb) { 
    93110        pj_memcpy(&udp_rel->cb, cb, sizeof(*cb)); 
     111    } 
     112 
     113    /* Create lock */ 
     114    status = pj_lock_create_recursive_mutex(pool, pool->obj_name,  
     115                                            &udp_rel->lock); 
     116    if (status != PJ_SUCCESS) { 
     117        destroy(udp_rel); 
     118        return status; 
     119    } 
     120 
     121    /* Init timer */ 
     122    udp_rel->timer_heap = cfg->timer_heap; 
     123    pj_timer_entry_init(&udp_rel->timer, TIMER_NONE, udp_rel, &timer_cb); 
     124 
     125    /* Init socket */ 
     126    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &udp_rel->sock); 
     127    if (status != PJ_SUCCESS) { 
     128        destroy(udp_rel); 
     129        return status; 
     130    } 
     131 
     132    /* Bind to any */ 
     133    pj_sockaddr_init(af, &udp_rel->src_addr, NULL, 0); 
     134    status = pj_sock_bind(udp_rel->sock, &udp_rel->src_addr,  
     135                          pj_sockaddr_get_len(&udp_rel->src_addr)); 
     136    if (status != PJ_SUCCESS) { 
     137        destroy(udp_rel); 
     138        return status; 
     139    } 
     140 
     141    /* Register to ioqeuue */ 
     142    pj_bzero(&ioq_cb, sizeof(ioq_cb)); 
     143    ioq_cb.on_read_complete = &on_read_complete; 
     144    status = pj_ioqueue_register_sock(udp_rel->pool, cfg->ioqueue,  
     145                                      udp_rel->sock, udp_rel,  
     146                                      &ioq_cb, &udp_rel->key); 
     147    if (status != PJ_SUCCESS) { 
     148        destroy(udp_rel); 
     149        return status; 
    94150    } 
    95151 
     
    103159                                    &sess_cb, udp_rel, 0, &udp_rel->sess); 
    104160    if (status != PJ_SUCCESS) { 
    105         pj_turn_udp_destroy(udp_rel); 
    106         return status; 
    107     } 
    108  
    109     /* Init socket */ 
    110     status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &udp_rel->sock); 
    111     if (status != PJ_SUCCESS) { 
    112         pj_turn_udp_destroy(udp_rel); 
    113         return status; 
    114     } 
    115  
    116     /* Bind to any */ 
    117     pj_sockaddr_init(af, &udp_rel->src_addr, NULL, 0); 
    118     status = pj_sock_bind(udp_rel->sock, &udp_rel->src_addr,  
    119                           pj_sockaddr_get_len(&udp_rel->src_addr)); 
    120     if (status != PJ_SUCCESS) { 
    121         pj_turn_udp_destroy(udp_rel); 
    122         return status; 
    123     } 
    124  
    125     /* Register to ioqeuue */ 
    126     pj_bzero(&ioq_cb, sizeof(ioq_cb)); 
    127     ioq_cb.on_read_complete = &on_read_complete; 
    128     status = pj_ioqueue_register_sock(udp_rel->pool, cfg->ioqueue,  
    129                                       udp_rel->sock, udp_rel,  
    130                                       &ioq_cb, &udp_rel->key); 
    131     if (status != PJ_SUCCESS) { 
    132         pj_turn_udp_destroy(udp_rel); 
     161        destroy(udp_rel); 
    133162        return status; 
    134163    } 
     
    145174 * Destroy. 
    146175 */ 
    147 PJ_DEF(void) pj_turn_udp_destroy(pj_turn_udp *udp_rel) 
    148 { 
     176static void destroy(pj_turn_udp *udp_rel) 
     177{ 
     178    if (udp_rel->lock) { 
     179        pj_lock_acquire(udp_rel->lock); 
     180    } 
     181 
    149182    if (udp_rel->sess) { 
     183        pj_turn_session_set_user_data(udp_rel->sess, NULL); 
    150184        pj_turn_session_destroy(udp_rel->sess); 
    151185        udp_rel->sess = NULL; 
     186    } 
     187 
     188    if (udp_rel->key) { 
     189        pj_ioqueue_unregister(udp_rel->key); 
     190        udp_rel->key = NULL; 
     191        udp_rel->sock = 0; 
     192    } else if (udp_rel->sock) { 
     193        pj_sock_close(udp_rel->sock); 
     194        udp_rel->sock = 0; 
     195    } 
     196 
     197    if (udp_rel->lock) { 
     198        pj_lock_release(udp_rel->lock); 
     199        pj_lock_destroy(udp_rel->lock); 
     200        udp_rel->lock = NULL; 
    152201    } 
    153202 
     
    158207    } 
    159208} 
     209 
     210PJ_DEF(void) pj_turn_udp_destroy(pj_turn_udp *udp_rel) 
     211{ 
     212    pj_lock_acquire(udp_rel->lock); 
     213    udp_rel->destroy_request = PJ_TRUE; 
     214 
     215    if (udp_rel->sess) { 
     216        pj_turn_session_destroy(udp_rel->sess); 
     217        /* This will ultimately call our state callback, and when 
     218         * session state is DESTROYING we will schedule a timer to 
     219         * destroy ourselves. 
     220         */ 
     221        pj_lock_release(udp_rel->lock); 
     222    } else { 
     223        pj_lock_release(udp_rel->lock); 
     224        destroy(udp_rel); 
     225    } 
     226 
     227} 
     228 
     229/* Timer callback */ 
     230static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e) 
     231{ 
     232    pj_turn_udp *udp_rel = (pj_turn_udp*)e->user_data; 
     233    int eid = e->id; 
     234 
     235    PJ_UNUSED_ARG(th); 
     236 
     237    e->id = TIMER_NONE; 
     238 
     239    switch (eid) { 
     240    case TIMER_DESTROY: 
     241        destroy(udp_rel); 
     242        break; 
     243    default: 
     244        pj_assert(!"Invalid timer id"); 
     245        break; 
     246    } 
     247} 
     248 
    160249 
    161250/* 
     
    272361 
    273362    udp_rel = (pj_turn_udp*) pj_ioqueue_get_user_data(key); 
     363    pj_lock_acquire(udp_rel->lock); 
    274364 
    275365    do { 
     
    301391             ++retry < MAX_RETRY); 
    302392 
     393    pj_lock_release(udp_rel->lock); 
    303394} 
    304395 
     
    317408    pj_ssize_t len = pkt_len; 
    318409 
     410    if (udp_rel == NULL) { 
     411        /* We've been destroyed */ 
     412        pj_assert(!"We should shutdown gracefully"); 
     413        return PJ_EINVALIDOP; 
     414    } 
     415 
    319416    return pj_sock_sendto(udp_rel->sock, pkt, &len, 0, 
    320417                          dst_addr, dst_addr_len); 
     
    348445    pj_turn_udp *udp_rel = (pj_turn_udp*)  
    349446                           pj_turn_session_get_user_data(sess); 
     447    if (udp_rel == NULL) { 
     448        /* We've been destroyed */ 
     449        return; 
     450    } 
     451 
    350452    if (udp_rel->cb.on_rx_data) { 
    351453        (*udp_rel->cb.on_rx_data)(udp_rel, pkt, pkt_len,  
     
    364466    pj_turn_udp *udp_rel = (pj_turn_udp*)  
    365467                           pj_turn_session_get_user_data(sess); 
     468    if (udp_rel == NULL) { 
     469        /* We've been destroyed */ 
     470        return; 
     471    } 
     472 
    366473    if (udp_rel->cb.on_state) { 
    367474        (*udp_rel->cb.on_state)(udp_rel, old_state, new_state); 
    368475    } 
    369476 
    370     if (new_state > PJ_TURN_STATE_READY) { 
    371         udp_rel->sess = NULL; 
    372     } 
    373 } 
    374  
    375  
     477    if (new_state >= PJ_TURN_STATE_DESTROYING && udp_rel->sess) { 
     478        if (udp_rel->destroy_request) { 
     479            pj_time_val delay = {0, 0}; 
     480 
     481            pj_turn_session_set_user_data(udp_rel->sess, NULL); 
     482 
     483            udp_rel->timer.id = TIMER_DESTROY; 
     484            pj_timer_heap_schedule(udp_rel->timer_heap, &udp_rel->timer,  
     485                                   &delay); 
     486        } else { 
     487            udp_rel->sess = NULL; 
     488        } 
     489    } 
     490} 
     491 
     492 
Note: See TracChangeset for help on using the changeset viewer.