fix session leak on 100rel disabled

In case 100rel is disabled on SEMS' side, but UAC requires it, SEMS
would reject the INVITE, drop further processing on the session, but
still keep it. If INVITE is first in session, UAC would clear the
dialog, but SEMS would still keep it.

But spotted and explained by Stefan S.
sayer/1.4-spce2.6
bpintea 15 years ago
parent a1fcef99d1
commit 98ae1ff252

@ -1216,16 +1216,23 @@ void AmSession::onFailure(AmSipDialogEventHandler::FailureCause cause,
const AmSipRequest *req, const AmSipReply *rpl)
{
switch (cause) {
case FAIL_REL100:
case FAIL_REL100_421:
case FAIL_REL100_420:
if (rpl) {
dlg.cancel();
if (dlg.getStatus() < AmSipDialog::Connected)
setStopped();
} else if (req) {
dlg.reply(*req, 421, "Extension Required", "", "",
if (cause == FAIL_REL100_421) {
dlg.reply(*req, 421, SIP_REPLY_EXTENSION_REQUIRED, "", "",
SIP_HDR_COLSP(SIP_HDR_REQUIRE) SIP_EXT_100REL CRLF);
if (dlg.getStatus() < AmSipDialog::Connected)
setStopped();
} else {
dlg.reply(*req, 420, SIP_REPLY_BAD_EXTENSION, "", "",
SIP_HDR_COLSP(SIP_HDR_UNSUPPORTED) SIP_EXT_100REL CRLF);
}
/* finally, stop session if running */
if (dlg.getStatus() < AmSipDialog::Connected)
setStopped();
}
break;
default:

@ -173,19 +173,17 @@ int AmSipDialog::rel100OnRequestIn(const AmSipRequest& req)
SIP_EXT_100REL))) {
ERROR("'" SIP_EXT_100REL "' extension required, but not advertised"
" by peer.\n");
if (hdl) hdl->onFailure(FAIL_REL100, &req, 0);
if (hdl) hdl->onFailure(FAIL_REL100_421, &req, 0);
return 0; // has been replied
}
break; // 100rel required
case REL100_DISABLED:
// TODO: shouldn't this be part of a more general check in SEMS?
if (key_in_list(getHeader(req.hdrs,SIP_HDR_REQUIRE),SIP_EXT_100REL))
reply_error(req, 420, SIP_REPLY_BAD_EXTENSION,
SIP_HDR_COLSP(SIP_HDR_UNSUPPORTED) SIP_EXT_100REL CRLF,
next_hop_for_replies ? next_hop_ip : "",
next_hop_for_replies ? next_hop_port : 0);
return 0;
if (key_in_list(getHeader(req.hdrs,SIP_HDR_REQUIRE),SIP_EXT_100REL)) {
if (hdl) hdl->onFailure(FAIL_REL100_420, &req, 0);
return 0; // has been replied
}
break;
default:
@ -416,7 +414,7 @@ int AmSipDialog::rel100OnReplyIn(const AmSipReply &reply)
!reply.rseq) {
ERROR(SIP_EXT_100REL " not supported or no positive RSeq value in "
"(reliable) 1xx.\n");
if (hdl) hdl->onFailure(FAIL_REL100, 0, &reply);
if (hdl) hdl->onFailure(FAIL_REL100_421, 0, &reply);
} else {
DBG(SIP_EXT_100REL " now active.\n");
if (hdl) hdl->onInvite1xxRel(reply);
@ -436,7 +434,7 @@ int AmSipDialog::rel100OnReplyIn(const AmSipReply &reply)
} else if (reliable_1xx && reply.method==SIP_METH_PRACK) {
if (300 <= reply.code) {
// if PRACK fails, tear down session
if (hdl) hdl->onFailure(FAIL_REL100, 0, &reply);
if (hdl) hdl->onFailure(FAIL_REL100_421, 0, &reply);
} else if (200 <= reply.code) {
if (hdl) hdl->onPrack2xx(reply);
} else {

@ -110,8 +110,10 @@ class AmSipDialogEventHandler
virtual void onPrack2xx(const AmSipReply &)=0;
enum FailureCause {
FAIL_REL100,
#define FAIL_REL100 AmSipDialogEventHandler::FAIL_REL100
FAIL_REL100_421,
#define FAIL_REL100_421 AmSipDialogEventHandler::FAIL_REL100_421
FAIL_REL100_420,
#define FAIL_REL100_420 AmSipDialogEventHandler::FAIL_REL100_420
};
virtual void onFailure(FailureCause cause, const AmSipRequest*,
const AmSipReply*)=0;

@ -52,4 +52,5 @@
#define SIP_REPLY_SERVER_INTERNAL_ERROR "Server Internal Error"
#define SIP_REPLY_BAD_EXTENSION "Bad Extension"
#define SIP_REPLY_EXTENSION_REQUIRED "Extension Required"
#endif /* __AMSIPHEADERS_H__ */

Loading…
Cancel
Save