summaryrefslogtreecommitdiff
path: root/pjnath/src/pjnath/stun_transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjnath/src/pjnath/stun_transaction.c')
-rw-r--r--pjnath/src/pjnath/stun_transaction.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/pjnath/src/pjnath/stun_transaction.c b/pjnath/src/pjnath/stun_transaction.c
index ebee152a..1242dfe7 100644
--- a/pjnath/src/pjnath/stun_transaction.c
+++ b/pjnath/src/pjnath/stun_transaction.c
@@ -31,16 +31,17 @@
struct pj_stun_client_tsx
{
char obj_name[PJ_MAX_OBJ_NAME];
- pj_stun_config *cfg;
pj_stun_tsx_cb cb;
void *user_data;
pj_bool_t complete;
pj_bool_t require_retransmit;
+ unsigned rto_msec;
pj_timer_entry retransmit_timer;
unsigned transmit_count;
pj_time_val retransmit_time;
+ pj_timer_heap_t *timer_heap;
pj_timer_entry destroy_timer;
@@ -70,7 +71,8 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_create(pj_stun_config *cfg,
PJ_ASSERT_RETURN(cb->on_send_msg, PJ_EINVAL);
tsx = PJ_POOL_ZALLOC_T(pool, pj_stun_client_tsx);
- tsx->cfg = cfg;
+ tsx->rto_msec = cfg->rto_msec;
+ tsx->timer_heap = cfg->timer_heap;
pj_memcpy(&tsx->cb, cb, sizeof(*cb));
tsx->retransmit_timer.cb = &retransmit_timer_callback;
@@ -99,22 +101,23 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_schedule_destroy(
/* Cancel previously registered timer */
if (tsx->destroy_timer.id != 0) {
- pj_timer_heap_cancel(tsx->cfg->timer_heap, &tsx->destroy_timer);
+ pj_timer_heap_cancel(tsx->timer_heap, &tsx->destroy_timer);
tsx->destroy_timer.id = 0;
}
/* Stop retransmission, just in case */
if (tsx->retransmit_timer.id != 0) {
- pj_timer_heap_cancel(tsx->cfg->timer_heap, &tsx->retransmit_timer);
+ pj_timer_heap_cancel(tsx->timer_heap, &tsx->retransmit_timer);
tsx->retransmit_timer.id = 0;
}
- status = pj_timer_heap_schedule(tsx->cfg->timer_heap,
+ status = pj_timer_heap_schedule(tsx->timer_heap,
&tsx->destroy_timer, delay);
if (status != PJ_SUCCESS)
return status;
tsx->destroy_timer.id = TIMER_ACTIVE;
+ tsx->cb.on_complete = NULL;
return PJ_SUCCESS;
}
@@ -128,11 +131,11 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_destroy(pj_stun_client_tsx *tsx)
PJ_ASSERT_RETURN(tsx, PJ_EINVAL);
if (tsx->retransmit_timer.id != 0) {
- pj_timer_heap_cancel(tsx->cfg->timer_heap, &tsx->retransmit_timer);
+ pj_timer_heap_cancel(tsx->timer_heap, &tsx->retransmit_timer);
tsx->retransmit_timer.id = 0;
}
if (tsx->destroy_timer.id != 0) {
- pj_timer_heap_cancel(tsx->cfg->timer_heap, &tsx->destroy_timer);
+ pj_timer_heap_cancel(tsx->timer_heap, &tsx->destroy_timer);
tsx->destroy_timer.id = 0;
}
@@ -186,7 +189,7 @@ static pj_status_t tsx_transmit_msg(pj_stun_client_tsx *tsx)
/* Calculate retransmit/timeout delay */
if (tsx->transmit_count == 0) {
tsx->retransmit_time.sec = 0;
- tsx->retransmit_time.msec = tsx->cfg->rto_msec;
+ tsx->retransmit_time.msec = tsx->rto_msec;
} else if (tsx->transmit_count < PJ_STUN_MAX_TRANSMIT_COUNT-1) {
unsigned msec;
@@ -205,7 +208,7 @@ static pj_status_t tsx_transmit_msg(pj_stun_client_tsx *tsx)
* cancel it (as opposed to when schedule_timer() failed we cannot
* cancel transmission).
*/;
- status = pj_timer_heap_schedule(tsx->cfg->timer_heap,
+ status = pj_timer_heap_schedule(tsx->timer_heap,
&tsx->retransmit_timer,
&tsx->retransmit_time);
if (status != PJ_SUCCESS) {
@@ -223,9 +226,12 @@ static pj_status_t tsx_transmit_msg(pj_stun_client_tsx *tsx)
/* Send message */
status = tsx->cb.on_send_msg(tsx, tsx->last_pkt, tsx->last_pkt_size);
- if (status != PJ_SUCCESS) {
+
+ if (status == PJNATH_ESTUNDESTROYED) {
+ /* We've been destroyed, don't access the object. */
+ } else if (status != PJ_SUCCESS) {
if (tsx->retransmit_timer.id != 0) {
- pj_timer_heap_cancel(tsx->cfg->timer_heap,
+ pj_timer_heap_cancel(tsx->timer_heap,
&tsx->retransmit_timer);
tsx->retransmit_timer.id = 0;
}
@@ -279,12 +285,15 @@ static void retransmit_timer_callback(pj_timer_heap_t *timer_heap,
tsx->cb.on_complete(tsx, PJNATH_ESTUNTIMEDOUT, NULL, NULL, 0);
}
}
+ /* We might have been destroyed, don't try to access the object */
return;
}
tsx->retransmit_timer.id = 0;
status = tsx_transmit_msg(tsx);
- if (status != PJ_SUCCESS) {
+ if (status == PJNATH_ESTUNDESTROYED) {
+ /* We've been destroyed, don't try to access the object */
+ } else if (status != PJ_SUCCESS) {
tsx->retransmit_timer.id = 0;
if (!tsx->complete) {
tsx->complete = PJ_TRUE;
@@ -292,6 +301,7 @@ static void retransmit_timer_callback(pj_timer_heap_t *timer_heap,
tsx->cb.on_complete(tsx, status, NULL, NULL, 0);
}
}
+ /* We might have been destroyed, don't try to access the object */
}
}
@@ -305,7 +315,7 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_retransmit(pj_stun_client_tsx *tsx)
}
if (tsx->retransmit_timer.id != 0) {
- pj_timer_heap_cancel(tsx->cfg->timer_heap, &tsx->retransmit_timer);
+ pj_timer_heap_cancel(tsx->timer_heap, &tsx->retransmit_timer);
tsx->retransmit_timer.id = 0;
}
@@ -351,7 +361,7 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx,
* We can cancel retransmit timer now.
*/
if (tsx->retransmit_timer.id) {
- pj_timer_heap_cancel(tsx->cfg->timer_heap, &tsx->retransmit_timer);
+ pj_timer_heap_cancel(tsx->timer_heap, &tsx->retransmit_timer);
tsx->retransmit_timer.id = 0;
}
@@ -384,6 +394,7 @@ PJ_DEF(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx,
if (tsx->cb.on_complete) {
tsx->cb.on_complete(tsx, status, msg, src_addr, src_addr_len);
}
+ /* We might have been destroyed, don't try to access the object */
}
return PJ_SUCCESS;