Ignore:
Timestamp:
Apr 15, 2009 5:32:09 PM (15 years ago)
Author:
bennylp
Message:

More ticket #780: work on CreatePermission? refresh timer in the TURN session

File:
1 edited

Legend:

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

    r2590 r2602  
    3636#define PJ_TURN_CHANNEL_HTABLE_SIZE 8 
    3737#define PJ_TURN_PERM_HTABLE_SIZE    8 
    38 #define PJ_TURN_RENEWAL_BEFORE      10  /* seconds before renewals */ 
    3938 
    4039static const char *state_names[] =  
     
    17501749    if (ch && update) { 
    17511750        pj_gettimeofday(&ch->expiry); 
    1752         ch->expiry.sec += PJ_TURN_PERM_TIMEOUT - PJ_TURN_RENEWAL_BEFORE; 
     1751        ch->expiry.sec += PJ_TURN_PERM_TIMEOUT - sess->ka_interval - 1; 
    17531752 
    17541753        if (bind_channel) { 
     
    17641763        } 
    17651764    } 
     1765 
     1766    /* Also create/update permission for this destination. Ideally we 
     1767     * should update this when we receive the successful response, 
     1768     * but that would cause duplicate CreatePermission to be sent 
     1769     * during refreshing. 
     1770     */ 
     1771    lookup_perm(sess, &ch->addr, pj_sockaddr_get_len(&ch->addr), PJ_TRUE); 
    17661772 
    17671773    return ch; 
     
    18131819    if (perm && update) { 
    18141820        pj_gettimeofday(&perm->expiry); 
    1815         perm->expiry.sec += PJ_TURN_PERM_TIMEOUT - PJ_TURN_RENEWAL_BEFORE; 
     1821        perm->expiry.sec += PJ_TURN_PERM_TIMEOUT - sess->ka_interval - 1; 
    18161822 
    18171823    } 
     
    18281834    pj_hash_set(NULL, sess->perm_table, &perm->addr, 
    18291835                pj_sockaddr_get_len(&perm->addr), perm->hval, NULL); 
     1836} 
     1837 
     1838/* 
     1839 * Scan permission's hash table to refresh the permission. 
     1840 */ 
     1841static unsigned refresh_permissions(pj_turn_session *sess,  
     1842                                    const pj_time_val *now) 
     1843{ 
     1844    pj_stun_tx_data *tdata = NULL; 
     1845    unsigned count = 0; 
     1846    void *req_token = NULL; 
     1847    pj_hash_iterator_t *it, itbuf; 
     1848    pj_status_t status; 
     1849 
     1850    it = pj_hash_first(sess->perm_table, &itbuf); 
     1851    while (it) { 
     1852        struct perm_t *perm = (struct perm_t*) 
     1853                              pj_hash_this(sess->perm_table, it); 
     1854 
     1855        it = pj_hash_next(sess->perm_table, it); 
     1856 
     1857        if (perm->expiry.sec-1 <= now->sec) { 
     1858            if (perm->renew) { 
     1859                /* Renew this permission */ 
     1860                if (tdata == NULL) { 
     1861                    /* Create a bare CreatePermission request */ 
     1862                    status = pj_stun_session_create_req( 
     1863                                        sess->stun,  
     1864                                        PJ_STUN_CREATE_PERM_REQUEST, 
     1865                                        PJ_STUN_MAGIC, NULL, &tdata); 
     1866                    if (status != PJ_SUCCESS) { 
     1867                        PJ_LOG(1,(sess->obj_name,  
     1868                                 "Error creating CreatePermission request: %d", 
     1869                                 status)); 
     1870                        return 0; 
     1871                    } 
     1872 
     1873                    /* Create request token to map the request to the perm 
     1874                     * structures which the request belongs. 
     1875                     */ 
     1876                    req_token = (void*)(long)pj_rand(); 
     1877                } 
     1878 
     1879                status = pj_stun_msg_add_sockaddr_attr( 
     1880                                        tdata->pool,  
     1881                                        tdata->msg, 
     1882                                        PJ_STUN_ATTR_XOR_PEER_ADDR, 
     1883                                        PJ_TRUE, 
     1884                                        &perm->addr, 
     1885                                        sizeof(perm->addr)); 
     1886                if (status != PJ_SUCCESS) { 
     1887                    pj_stun_msg_destroy_tdata(sess->stun, tdata); 
     1888                    return 0; 
     1889                } 
     1890 
     1891                perm->expiry = *now; 
     1892                perm->expiry.sec += PJ_TURN_PERM_TIMEOUT-sess->ka_interval-1; 
     1893                perm->req_token = req_token; 
     1894                ++count; 
     1895 
     1896            } else { 
     1897                /* This permission has expired and app doesn't want 
     1898                 * us to renew, so delete it from the hash table. 
     1899                 */ 
     1900                invalidate_perm(sess, perm); 
     1901            } 
     1902        } 
     1903    } 
     1904 
     1905    if (tdata) { 
     1906        status = pj_stun_session_send_msg(sess->stun, req_token, PJ_FALSE,  
     1907                                          (sess->conn_type==PJ_TURN_TP_UDP), 
     1908                                          sess->srv_addr, 
     1909                                          pj_sockaddr_get_len(sess->srv_addr),  
     1910                                          tdata); 
     1911        if (status != PJ_SUCCESS) { 
     1912            PJ_LOG(1,(sess->obj_name,  
     1913                      "Error sending CreatePermission request: %d", 
     1914                      status)); 
     1915            count = 0; 
     1916        } 
     1917 
     1918    } 
     1919 
     1920    return count; 
    18301921} 
    18311922 
     
    18831974        } 
    18841975 
     1976        /* Scan permission table to refresh permissions */ 
     1977        if (refresh_permissions(sess, &now)) 
     1978            pkt_sent = PJ_TRUE; 
     1979 
    18851980        /* If no packet is sent, send a blank Send indication to 
    18861981         * refresh local NAT. 
Note: See TracChangeset for help on using the changeset viewer.