properly evaluate minimum session timer

fixes bug #42 (https://bugtracker.iptel.org/view.php?id=42)

422 Session Interval Too Small is replied with the configured
min-se value, if session refresh interval is too low.
sayer/1.4-spce2.6
Stefan Sayer 16 years ago
parent c397064d71
commit 6127241d2b

@ -69,6 +69,8 @@ int SSTB2BFactory::onLoad()
AmSession* SSTB2BFactory::onInvite(const AmSipRequest& req)
{
if (!session_timer_fact->onInvite(req, cfg))
return NULL;
SSTB2BDialog* b2b_dlg = new SSTB2BDialog();
AmSessionEventHandler* h = session_timer_fact->getHandler(b2b_dlg);
@ -76,6 +78,7 @@ AmSession* SSTB2BFactory::onInvite(const AmSipRequest& req)
ERROR("could not get a session timer event handler\n");
throw AmSession::Exception(500,"Server internal error");
}
if(h->configure(cfg)){
ERROR("Could not configure the session timer: disabling session timers.\n");
delete h;

@ -94,9 +94,10 @@ AmSessionEventHandlerFactory::AmSessionEventHandlerFactory(const string& name)
}
bool AmSessionEventHandlerFactory::onInvite(const AmSipRequest& req,
AmArg& session_params) {
AmArg& session_params,
AmConfigReader& cfg) {
WARN("discarding session parameters for new session.\n");
return onInvite(req);
return onInvite(req, cfg);
}
// AmSIPEventHandler::AmSIPEventHandler(const string& name)

@ -110,10 +110,10 @@ class AmSessionEventHandlerFactory: public AmPluginFactory
virtual AmSessionEventHandler* getHandler(AmSession*)=0;
/**
* @return true if session creation should be stopped
* @return false if session creation should be stopped
*/
virtual bool onInvite(const AmSipRequest& req)=0;
virtual bool onInvite(const AmSipRequest& req, AmArg& session_params);
virtual bool onInvite(const AmSipRequest& req, AmConfigReader& cfg)=0;
virtual bool onInvite(const AmSipRequest& req, AmArg& session_params, AmConfigReader& cfg);
};
/** \brief Interface for plugins to create sessions */

@ -195,7 +195,8 @@ public:
struct Exception {
int code;
string reason;
Exception(int c, string r) : code(c), reason(r) {}
string hdrs;
Exception(int c, string r, string h="") : code(c), reason(r), hdrs(h) {}
};
/**

@ -307,8 +307,8 @@ void AmSessionContainer::startSessionUAS(AmSipRequest& req)
}
}
catch(const AmSession::Exception& e){
ERROR("%i %s\n",e.code,e.reason.c_str());
AmSipDialog::reply_error(req,e.code,e.reason);
ERROR("%i %s %s\n",e.code,e.reason.c_str(), e.hdrs.c_str());
AmSipDialog::reply_error(req,e.code,e.reason, e.hdrs);
}
catch(const string& err){
ERROR("startSession: %s\n",err.c_str());

@ -76,10 +76,18 @@ int EchoFactory::onLoad()
AmSession* EchoFactory::onInvite(const AmSipRequest& req)
{
if (NULL != session_timer_f) {
if (!session_timer_f->onInvite(req, conf))
return NULL;
}
AmSession* s = new EchoDialog();
if (NULL != session_timer_f) {
AmSessionEventHandler* h = session_timer_f->getHandler(s);
if (NULL == h)
return NULL;
if(h->configure(conf)){
ERROR("Could not configure the session timer: disabling session timers.\n");

@ -37,11 +37,9 @@ int SessionTimerFactory::onLoad()
return 0;
}
bool SessionTimerFactory::onInvite(const AmSipRequest& req)
bool SessionTimerFactory::onInvite(const AmSipRequest& req, AmConfigReader& cfg)
{
if(!checkSessionExpires(req))
return true;
return false;
return checkSessionExpires(req, cfg);
}
@ -127,11 +125,9 @@ bool SessionTimer::onSendReply(const AmSipRequest& req,
return false;
}
/* Session Timer: -ssa */
int SessionTimer::configure(AmConfigReader& conf)
int SessionTimer::configure(AmConfigReader& conf)
{
if(session_timer_conf.readFromConfig(conf))
if(!session_timer_conf.readFromConfig(conf))
return -1;
session_interval = session_timer_conf.getSessionExpires();
@ -152,22 +148,29 @@ int SessionTimer::configure(AmConfigReader& conf)
* (<locally configured Min-SE)
* Throws SessionIntervalTooSmallException if too low
*/
bool SessionTimerFactory::checkSessionExpires(const AmSipRequest& req)
bool SessionTimerFactory::checkSessionExpires(const AmSipRequest& req, AmConfigReader& cfg)
{
AmSessionTimerConfig sst_cfg;
if (sst_cfg.readFromConfig(cfg)) {
return false;
}
string session_expires = getHeader(req.hdrs, SIP_HDR_SESSION_EXPIRES,
SIP_HDR_SESSION_EXPIRES_COMPACT, true);
if (session_expires.length()) {
unsigned int i_se;
if (!str2i(strip_header_params(session_expires), i_se)) {
//if (i_se < session_timer_conf.getMinimumTimer()) {
//TODO: reply 422...
//}
} else
throw AmSession::Exception(500,"internal error"); // malformed request?
if (i_se < sst_cfg.getMinimumTimer()) {
throw AmSession::Exception(422, "Session Interval Too Small",
SIP_HDR_COLSP(SIP_HDR_MIN_SE)+
int2str(sst_cfg.getMinimumTimer())+CRLF);
}
} else {
WARN("parsing session expires '%s' failed\n", session_expires.c_str());
throw AmSession::Exception(400,"Bad Request");
}
}
//}
return true;
}

@ -49,20 +49,20 @@ class AmTimeoutEvent;
/** \brief Factory of the session timer event handler */
class SessionTimerFactory: public AmSessionEventHandlerFactory
{
bool checkSessionExpires(const AmSipRequest& req);
bool checkSessionExpires(const AmSipRequest& req, AmConfigReader& cfg);
public:
SessionTimerFactory(const string& name)
: AmSessionEventHandlerFactory(name) {}
int onLoad();
bool onInvite(const AmSipRequest&);
bool onInvite(const AmSipRequest& req, AmConfigReader& cfg);
AmSessionEventHandler* getHandler(AmSession* s);
};
/** \brief config for the session timer */
class AmSessionTimerConfig
class AmSessionTimerConfig
{
/** Session Timer: enable? */

@ -74,9 +74,9 @@ int UACAuthFactory::onLoad()
return 0;
}
bool UACAuthFactory::onInvite(const AmSipRequest& req)
bool UACAuthFactory::onInvite(const AmSipRequest& req, AmConfigReader& conf)
{
return false;
return true;
}
AmSessionEventHandler* UACAuthFactory::getHandler(AmSession* s)

@ -72,7 +72,7 @@ class UACAuthFactory
// SessionEventHandler API
AmSessionEventHandler* getHandler(AmSession* s);
bool onInvite(const AmSipRequest&);
bool onInvite(const AmSipRequest& req, AmConfigReader& conf);
static UACAuthFactory* instance();
AmDynInvoke* getInstance() { return instance(); }

@ -12,3 +12,6 @@ star key pressed on the phone switches between adaptive playout
buffer and fifo playout buffer. Thus the effect of the adaptive
playout buffering can easily be verified.
The echo application is also a test application for RFC4028 SIP
Session Timers. For this, enable_session_timer=yes needs to be
set in echo.conf

Loading…
Cancel
Save