Ignore:
Timestamp:
Oct 4, 2007 9:50:36 AM (17 years ago)
Author:
bennylp
Message:

Ticket #95: Keep-alive mechanism for TCP and TLS transports

File:
1 edited

Legend:

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

    r1405 r1473  
    167167    SSL                     *ssl; 
    168168    pj_bool_t                ssl_shutdown_called; 
     169 
     170    /* Keep alive */ 
     171    pj_timer_entry           ka_timer; 
     172    pj_time_val              last_activity; 
    169173 
    170174    /* TLS transport can only have  one rdata! 
     
    742746 
    743747/* Send outgoing data with SSL connection */ 
    744 static pj_status_t ssl_write(struct tls_transport *tls, 
    745                              pjsip_tx_data *tdata) 
    746 { 
    747     int size = tdata->buf.cur - tdata->buf.start; 
     748static pj_status_t ssl_write_bytes(struct tls_transport *tls, 
     749                                   const void *data, 
     750                                   int size, 
     751                                   const char *data_name) 
     752{ 
    748753    int sent = 0; 
    749754 
    750755    do { 
    751756        const int fragment_sent = SSL_write(tls->ssl, 
    752                                             tdata->buf.start + sent,  
     757                                            ((pj_uint8_t*)data) + sent,  
    753758                                            size - sent); 
    754759     
     
    799804            ssl_report_error(tls->base.obj_name, 4, PJ_SUCCESS, 
    800805                             "Error sending %s with SSL_write()", 
    801                              pjsip_tx_data_get_info(tdata)); 
     806                             data_name); 
    802807            return pj_get_netos_error() ? pj_get_netos_error()  
    803808                    : PJSIP_TLS_ESEND; 
     
    807812 
    808813    return PJ_SUCCESS; 
     814 
     815} 
     816 
     817/* Send outgoing tdata with SSL connection */ 
     818static pj_status_t ssl_write(struct tls_transport *tls, 
     819                             pjsip_tx_data *tdata) 
     820{ 
     821    return ssl_write_bytes(tls, tdata->buf.start,  
     822                           tdata->buf.cur - tdata->buf.start, 
     823                           pjsip_tx_data_get_info(tdata)); 
    809824} 
    810825 
     
    11621177                                pj_status_t status); 
    11631178 
     1179/* TLS keep-alive timer callback */ 
     1180static void tls_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e); 
    11641181 
    11651182/* 
     
    12041221 
    12051222    /* Initialize transport reference counter to 1 */ 
    1206     status = pj_atomic_create(pool, 1, &tls->base.ref_cnt); 
     1223    status = pj_atomic_create(pool, 0, &tls->base.ref_cnt); 
    12071224    if (status != PJ_SUCCESS) { 
    12081225        goto on_error; 
     
    12731290 
    12741291    tls->is_registered = PJ_TRUE; 
     1292 
     1293    /* Initialize keep-alive timer */ 
     1294    tls->ka_timer.user_data = (void*) tls; 
     1295    tls->ka_timer.cb = &tls_keep_alive_timer; 
     1296 
    12751297 
    12761298    /* Done setting up basic transport. */ 
     
    17241746                                 "Error creating incoming TLS transport"); 
    17251747                pjsip_transport_shutdown(&tls->base); 
     1748 
     1749            } else { 
     1750                /* Start keep-alive timer */ 
     1751                if (PJSIP_TLS_KEEP_ALIVE_INTERVAL) { 
     1752                    pj_time_val delay = {PJSIP_TLS_KEEP_ALIVE_INTERVAL, 0}; 
     1753                    pjsip_endpt_schedule_timer(listener->endpt,  
     1754                                               &tls->ka_timer,  
     1755                                               &delay); 
     1756                    tls->ka_timer.id = PJ_TRUE; 
     1757                    pj_gettimeofday(&tls->last_activity); 
     1758                } 
    17261759            } 
    17271760 
     
    17751808        if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 
    17761809        pjsip_transport_shutdown(&tls->base); 
     1810    } else { 
     1811        /* Mark last activity */ 
     1812        pj_gettimeofday(&tls->last_activity); 
    17771813    } 
    17781814 
     
    19191955    /* Shutdown SSL */ 
    19201956    if (!tls->ssl_shutdown_called) { 
    1921         /* Release our reference counter and shutdown SSL */ 
    1922         pjsip_transport_dec_ref(transport); 
     1957        /* shutdown SSL */ 
    19231958        SSL_shutdown(tls->ssl); 
    19241959        tls->ssl_shutdown_called = PJ_TRUE; 
     
    19692004             */ 
    19702005            pj_size_t size_eaten; 
     2006 
     2007            /* Mark last activity */ 
     2008            pj_gettimeofday(&tls->last_activity); 
    19712009 
    19722010            /* Init pkt_info part. */ 
     
    22172255    /* Flush all pending send operations */ 
    22182256    tls_flush_pending_tx(tls); 
     2257 
     2258    /* Start keep-alive timer */ 
     2259    if (PJSIP_TLS_KEEP_ALIVE_INTERVAL) { 
     2260        pj_time_val delay = { PJSIP_TLS_KEEP_ALIVE_INTERVAL, 0 }; 
     2261        pjsip_endpt_schedule_timer(tls->listener->endpt, &tls->ka_timer,  
     2262                                   &delay); 
     2263        tls->ka_timer.id = PJ_TRUE; 
     2264        pj_gettimeofday(&tls->last_activity); 
     2265    } 
     2266 
     2267} 
     2268 
     2269 
     2270/* Transport keep-alive timer callback */ 
     2271static void tls_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e) 
     2272{ 
     2273    struct tls_transport *tls = (struct tls_transport*) e->user_data; 
     2274    const pj_str_t ka_data = PJSIP_TLS_KEEP_ALIVE_DATA; 
     2275    pj_time_val delay; 
     2276    pj_time_val now; 
     2277    pj_status_t status; 
     2278 
     2279    PJ_UNUSED_ARG(th); 
     2280 
     2281    tls->ka_timer.id = PJ_TRUE; 
     2282 
     2283    pj_gettimeofday(&now); 
     2284    PJ_TIME_VAL_SUB(now, tls->last_activity); 
     2285 
     2286    if (now.sec > 0 && now.sec < PJSIP_TLS_KEEP_ALIVE_INTERVAL) { 
     2287        /* There has been activity, so don't send keep-alive */ 
     2288        delay.sec = PJSIP_TLS_KEEP_ALIVE_INTERVAL - now.sec; 
     2289        delay.msec = 0; 
     2290 
     2291        pjsip_endpt_schedule_timer(tls->listener->endpt, &tls->ka_timer,  
     2292                                   &delay); 
     2293        tls->ka_timer.id = PJ_TRUE; 
     2294        return; 
     2295    } 
     2296 
     2297    PJ_LOG(5,(tls->base.obj_name, "Sending %d byte(s) keep-alive to %.*s:%d",  
     2298              (int)ka_data.slen, (int)tls->base.remote_name.host.slen, 
     2299              tls->base.remote_name.host.ptr, 
     2300              tls->base.remote_name.port)); 
     2301 
     2302    /* Send the data */ 
     2303    status = ssl_write_bytes(tls, ka_data.ptr, (int)ka_data.slen,  
     2304                             "keep-alive"); 
     2305    if (status != PJ_SUCCESS &&  
     2306        status != PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) 
     2307    { 
     2308        ssl_report_error(tls->base.obj_name, 1, status, 
     2309                         "Error sending keep-alive packet"); 
     2310        return; 
     2311    } 
     2312 
     2313    /* Register next keep-alive */ 
     2314    delay.sec = PJSIP_TLS_KEEP_ALIVE_INTERVAL; 
     2315    delay.msec = 0; 
     2316 
     2317    pjsip_endpt_schedule_timer(tls->listener->endpt, &tls->ka_timer,  
     2318                               &delay); 
     2319    tls->ka_timer.id = PJ_TRUE; 
    22192320} 
    22202321 
Note: See TracChangeset for help on using the changeset viewer.