Skip to content

Commit

Permalink
Modification based on comments
Browse files Browse the repository at this point in the history
  • Loading branch information
trengginas committed Oct 25, 2023
1 parent 455c4a5 commit cc50c8d
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 61 deletions.
26 changes: 16 additions & 10 deletions pjsip/include/pjsip/sip_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -677,16 +677,17 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)


/**
* Initial timeout interval to be applied to incoming transports (i.e. server
* side) when no data received after a successful connection for TLS.
* Value is in seconds. Disable the timeout by setting it to 0.
* Initial timeout interval to be applied to incoming TCP/TLS transports
* (i.e. server side) when no valid data received after a successful
* connection. Value is in seconds. Disable the timeout by setting it to 0.
*
* For TCP, refer to a\ PJSIP_TCP_INITIAL_TIMEOUT
*
* Note that even when this is disable, the connection might still get closed
* when it is idle or not referred anymore. Have a look at \a
* PJSIP_TRANSPORT_SERVER_IDLE_TIME
* PJSIP_TRANSPORT_SERVER_IDLE_TIME.
*
* Notes:
* - keep-alive packet is not considered as a valid message.
*
* Default: 0
*/
#ifndef PJSIP_TRANSPORT_SERVER_IDLE_TIME_FIRST
Expand Down Expand Up @@ -803,14 +804,19 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)


/**
* Initial timeout interval to be applied to incoming transports (i.e. server
* side) when no data received after a successful connection. Value is in
* seconds. Disable the timeout by setting it to 0.
* Initial timeout interval to be applied to incoming TCP transports
* (i.e. server side) when no valid data received after a successful
* connection. Value is in seconds. Disable the timeout by setting it to 0.
*
* Note that even when this is disable, the connection might still get closed
* when it is idle or not referred anymore. Have a look at \a
* PJSIP_TRANSPORT_SERVER_IDLE_TIME
* PJSIP_TRANSPORT_SERVER_IDLE_TIME.
*
* Notes:
* - keep-alive packet is not considered as a valid message.
* - This macro is exclusive to TCP usage. It will be prioritize over
* a\ PJSIP_TRANSPORT_SERVER_IDLE_TIME_FIRST if both are set.
*
* Default: 0 (disabled)
*/
#ifndef PJSIP_TCP_INITIAL_TIMEOUT
Expand Down
5 changes: 5 additions & 0 deletions pjsip/include/pjsip/sip_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,11 @@ struct pjsip_transport
pj_size_t last_recv_len; /**< Last received data length. */

void *data; /**< Internal transport data. */
unsigned initial_timeout;/**< Initial timeout interval
to be applied to incoming
TCP/TLS transports when no
valid data received after
a successful connection. */

/**
* Function to be called by transport manager to send SIP message.
Expand Down
3 changes: 2 additions & 1 deletion pjsip/include/pjsip/sip_transport_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ typedef struct pjsip_tcp_transport_cfg

/**
* Intial timeout interval to be applied to incoming transports
* (i.e. server side) when no data received after a successful connection.
* (i.e. server side) when no valid data received after a successful
* connection.
*
* Default: PJSIP_TCP_INITIAL_TIMEOUT
*/
Expand Down
10 changes: 10 additions & 0 deletions pjsip/include/pjsip/sip_transport_tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,15 @@ typedef struct pjsip_tls_setting
*/
pj_time_val timeout;

/**
* Intial timeout interval to be applied to incoming transports
* (i.e. server side) when no valid data received after a successful
* connection.
*
* Default: PJSIP_TRANSPORT_SERVER_IDLE_TIME_FIRST
*/
unsigned initial_timeout;

/**
* Should SO_REUSEADDR be used for the listener socket.
* Default value is PJSIP_TLS_TRANSPORT_REUSEADDR.
Expand Down Expand Up @@ -437,6 +446,7 @@ PJ_INLINE(void) pjsip_tls_setting_default(pjsip_tls_setting *tls_opt)
tls_opt->sockopt_ignore_error = PJ_TRUE;
tls_opt->proto = PJSIP_SSL_DEFAULT_PROTO;
tls_opt->enable_renegotiation = PJ_TRUE;
tls_opt->initial_timeout = PJSIP_TRANSPORT_SERVER_IDLE_TIME_FIRST;
}


Expand Down
51 changes: 44 additions & 7 deletions pjsip/src/pjsip/sip_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ static const char* print_tpsel_info(const pjsip_tpselector *sel)
# define PJSIP_TRANSPORT_ENTRY_ALLOC_CNT 16
#endif

/* Enum for id idle_timer. */
enum timer_id {
IDLE_TIMER_ID = 1,
INITIAL_IDLE_TIMER_ID
};

/* Prototype. */
static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata);

Expand Down Expand Up @@ -1066,6 +1072,8 @@ static void transport_idle_callback(pj_timer_heap_t *timer_heap,
struct pj_timer_entry *entry)
{
pjsip_transport *tp = (pjsip_transport*) entry->user_data;
int entry_id = entry->id;

pj_assert(tp != NULL);

PJ_UNUSED_ARG(timer_heap);
Expand All @@ -1079,8 +1087,21 @@ static void transport_idle_callback(pj_timer_heap_t *timer_heap,
* race condition with pjsip_tpmgr_acquire_transport2().
*/
pj_lock_acquire(tp->tpmgr->lock);

if (pj_atomic_get(tp->ref_cnt) == 0) {
tp->is_destroying = PJ_TRUE;

if (entry_id == INITIAL_IDLE_TIMER_ID) {
if (tp->last_recv_len > 0 && tp->tpmgr->tp_drop_data_cb) {
pjsip_tp_dropped_data dd;
pj_bzero(&dd, sizeof(dd));
dd.tp = tp;
dd.data = NULL;
dd.len = tp->last_recv_len;
dd.status = PJ_ESOCKETSTOP;
(*tp->tpmgr->tp_drop_data_cb)(&dd);
}
}
} else {
pj_lock_release(tp->tpmgr->lock);
return;
Expand Down Expand Up @@ -1179,6 +1200,8 @@ PJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp )
{
pj_time_val delay;

int timer_id = IDLE_TIMER_ID;

/* If transport is in graceful shutdown, then this is the
* last user who uses the transport. Schedule to destroy the
* transport immediately. Otherwise schedule idle timer.
Expand All @@ -1189,12 +1212,10 @@ PJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp )
if (tp->dir == PJSIP_TP_DIR_OUTGOING) {
delay.sec = PJSIP_TRANSPORT_IDLE_TIME;
} else {
if (tp->last_recv_ts.u64 == 0 &&
PJSIP_TRANSPORT_SERVER_IDLE_TIME_FIRST != 0)
{
delay.sec = PJSIP_TRANSPORT_SERVER_IDLE_TIME_FIRST;
} else {
delay.sec = PJSIP_TRANSPORT_SERVER_IDLE_TIME;
delay.sec = PJSIP_TRANSPORT_SERVER_IDLE_TIME;
if (tp->last_recv_ts.u64 == 0 && tp->initial_timeout) {
timer_id = INITIAL_IDLE_TIMER_ID;
delay.sec = tp->initial_timeout;
}
}
delay.msec = 0;
Expand All @@ -1207,7 +1228,7 @@ PJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp )
pjsip_endpt_schedule_timer_w_grp_lock(tp->tpmgr->endpt,
&tp->idle_timer,
&delay,
PJ_TRUE,
timer_id,
tp->grp_lock);
}
pj_lock_release(tpmgr->lock);
Expand Down Expand Up @@ -2056,6 +2077,15 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,
dd.status = PJSIP_ERXOVERFLOW;
(*mgr->tp_drop_data_cb)(&dd);
}

if (rdata->tp_info.transport->idle_timer.id ==
INITIAL_IDLE_TIMER_ID)
{
/* We are not getting the first valid data as expected,
* close the transport.
*/
pjsip_transport_shutdown(rdata->tp_info.transport);
}

/* Exhaust all data. */
return rdata->pkt_info.len;
Expand Down Expand Up @@ -2219,6 +2249,13 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,
}
*/

/* We have a valid message, cancel the initial timer. */
if (rdata->tp_info.transport->idle_timer.id == INITIAL_IDLE_TIMER_ID) {
rdata->tp_info.transport->idle_timer.id = PJ_FALSE;
pjsip_endpt_cancel_timer(mgr->endpt,
&rdata->tp_info.transport->idle_timer);
}

/* Call the transport manager's upstream message callback.
*/
mgr->on_rx_msg(mgr->endpt, PJ_SUCCESS, rdata);
Expand Down
49 changes: 6 additions & 43 deletions pjsip/src/pjsip/sip_transport_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ struct tcp_transport
/* Group lock to be used by TCP transport and ioqueue key */
pj_grp_lock_t *grp_lock;

/* Initial timer. */
pj_timer_entry initial_timer;
};


Expand Down Expand Up @@ -235,7 +233,8 @@ PJ_DEF(void) pjsip_tcp_transport_cfg_default(pjsip_tcp_transport_cfg *cfg,
pj_sockaddr_init(cfg->af, &cfg->bind_addr, NULL, 0);
cfg->async_cnt = 1;
cfg->reuse_addr = PJSIP_TCP_TRANSPORT_REUSEADDR;
cfg->initial_timeout = PJSIP_TCP_INITIAL_TIMEOUT;
cfg->initial_timeout = (PJSIP_TCP_INITIAL_TIMEOUT!=0)?
PJSIP_TCP_INITIAL_TIMEOUT:PJSIP_TRANSPORT_SERVER_IDLE_TIME_FIRST;
}


Expand Down Expand Up @@ -605,9 +604,6 @@ static pj_bool_t on_connect_complete(pj_activesock_t *asock,
/* TCP keep-alive timer callback */
static void tcp_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e);

/* TCP initial timer callback */
static void tcp_initial_timer(pj_timer_heap_t *th, pj_timer_entry *e);

/* Clean up TCP resources */
static void tcp_on_destroy(void *arg);

Expand Down Expand Up @@ -688,6 +684,7 @@ static pj_status_t tcp_create( struct tcp_listener *listener,
tcp->base.do_shutdown = &tcp_shutdown;
tcp->base.destroy = &tcp_destroy_transport;
tcp->base.factory = &listener->factory;
tcp->base.initial_timeout = listener->initial_timeout;

/* Create group lock */
status = pj_grp_lock_create_w_handler(pool, NULL, tcp, &tcp_on_destroy,
Expand Down Expand Up @@ -732,16 +729,9 @@ static pj_status_t tcp_create( struct tcp_listener *listener,

/* Initialize initial timer. */
if (is_server && listener->initial_timeout) {
pj_time_val delay = { 0 };

tcp->initial_timer.user_data = (void*)tcp;
tcp->initial_timer.cb = &tcp_initial_timer;

delay.sec = listener->initial_timeout;
pjsip_endpt_schedule_timer(listener->endpt,
&tcp->initial_timer,
&delay);
tcp->initial_timer.id = PJ_TRUE;
/* Initiate initial idle timer. */
pjsip_transport_add_ref(&tcp->base);
pjsip_transport_dec_ref(&tcp->base);
}

/* Done setting up basic transport. */
Expand Down Expand Up @@ -848,12 +838,6 @@ static pj_status_t tcp_destroy(pjsip_transport *transport,
tcp->ka_timer.id = PJ_FALSE;
}

/* Stop initial timer. */
if (tcp->initial_timer.id) {
pjsip_endpt_cancel_timer(tcp->base.endpt, &tcp->initial_timer);
tcp->initial_timer.id = PJ_FALSE;
}

/* Cancel all delayed transmits */
while (!pj_list_empty(&tcp->delayed_list)) {
struct delayed_tdata *pending_tx;
Expand Down Expand Up @@ -1394,12 +1378,6 @@ static pj_status_t tcp_shutdown(pjsip_transport *transport)
tcp->ka_timer.id = PJ_FALSE;
}

/* Stop initial timer. */
if (tcp->initial_timer.id) {
pjsip_endpt_cancel_timer(tcp->base.endpt, &tcp->initial_timer);
tcp->initial_timer.id = PJ_FALSE;
}

return PJ_SUCCESS;
}

Expand Down Expand Up @@ -1428,11 +1406,6 @@ static pj_bool_t on_data_read(pj_activesock_t *asock,
return PJ_FALSE;
}

if (tcp->initial_timer.id) {
pjsip_endpt_cancel_timer(tcp->base.endpt, &tcp->initial_timer);
tcp->initial_timer.id = PJ_FALSE;
}

/* Houston, we have packet! Report the packet to transport manager
* to be parsed.
*/
Expand Down Expand Up @@ -1650,16 +1623,6 @@ static void tcp_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e)
tcp->ka_timer.id = PJ_TRUE;
}

/* Transport keep-alive timer callback */
static void tcp_initial_timer(pj_timer_heap_t *th, pj_timer_entry *e)
{
pj_status_t status = PJ_ETIMEDOUT;
struct tcp_transport *tcp = (struct tcp_transport*) e->user_data;

PJ_UNUSED_ARG(th);

tcp_init_shutdown(tcp, status);
}

PJ_DEF(pj_sock_t) pjsip_tcp_transport_get_socket(pjsip_transport *transport)
{
Expand Down
1 change: 1 addition & 0 deletions pjsip/src/pjsip/sip_transport_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ static pj_status_t tls_create( struct tls_listener *listener,
tls->base.do_shutdown = &tls_shutdown;
tls->base.destroy = &tls_destroy_transport;
tls->base.factory = &listener->factory;
tls->base.initial_timeout = listener->tls_setting.initial_timeout;

tls->ssock = ssock;
tls->on_verify_cb = listener->tls_setting.on_verify_cb;
Expand Down

0 comments on commit cc50c8d

Please sign in to comment.