diff --git a/core/sip/sip_trans.cpp b/core/sip/sip_trans.cpp index ef949466..f1b92a87 100644 --- a/core/sip/sip_trans.cpp +++ b/core/sip/sip_trans.cpp @@ -155,13 +155,15 @@ void trans_timer_cb(timer* t, unsigned int bucket_id, sip_trans* tr) if(bucket->exist(tr)){ DBG("Transaction timer expired: type=%c, trans=%p, eta=%i, t=%i\n", timer_name(t->type),tr,t->expires,wheeltimer::instance()->wall_clock); + + // timer_expired unlocks the bucket trans_layer::instance()->timer_expired(t,bucket,tr); } else { WARN("Ignoring expired timer (%p): transaction" " %p does not exist anymore\n",t,tr); + bucket->unlock(); } - bucket->unlock(); } else { ERROR("Invalid bucket id\n"); diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp index c468f5c7..cae6dfa2 100644 --- a/core/sip/trans_layer.cpp +++ b/core/sip/trans_layer.cpp @@ -747,9 +747,10 @@ void _trans_layer::timeout(trans_bucket* bucket, sip_trans* t) msg.cseq = req->cseq; msg.callid = req->callid; - ua->handle_sip_reply(&msg); - bucket->remove(t); + bucket->unlock(); + + ua->handle_sip_reply(&msg); } int _trans_layer::send_request(sip_msg* msg, trans_ticket* tt, @@ -1202,10 +1203,18 @@ void _trans_layer::received_msg(sip_msg* msg) // Reply matched UAC transaction DBG("Reply matched an existing transaction\n"); - if(update_uac_reply(bucket,t,msg) < 0){ + int res = update_uac_reply(bucket,t,msg); + if(res < 0){ ERROR("update_uac_trans() failed, so what happens now???\n"); break; } + if (res) { + bucket->unlock(); + ua->handle_sip_reply(msg); + DROP_MSG; + //return; - part of DROP_MSG + } + // do not touch the transaction anymore: // it could have been deleted !!! } @@ -1414,8 +1423,7 @@ int _trans_layer::update_uac_reply(trans_bucket* bucket, sip_trans* t, sip_msg* } pass_reply: - assert(ua); - ua->handle_sip_reply(msg); + return 1; end: return 0; } @@ -1656,7 +1664,9 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) tr->clear_timer(STIMER_B); if(tr->state == TS_CALLING) { DBG("Transaction timeout!\n"); + // unlocks the bucket timeout(bucket,tr); + return; } else { DBG("Transaction timeout timer hit while state=0x%x",tr->state); @@ -1697,8 +1707,9 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) case TS_TRYING: case TS_PROCEEDING: DBG("Transaction timeout!\n"); + // unlocks the bucket timeout(bucket,tr); - break; + return; } break; @@ -1787,7 +1798,7 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) // get the next ip if(tr->msg->h_dns.next_ip(&sa) < 0){ tr->clear_timer(STIMER_M); - return; + break; } //If a SRV record is involved, the port number @@ -1822,6 +1833,8 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr) ERROR("Invalid timer type %i\n",t->type); break; } + + bucket->unlock(); } /**