diff --git a/apps/xmlrpc2di/XMLRPC2DI.cpp b/apps/xmlrpc2di/XMLRPC2DI.cpp index 0d471953..cc743eff 100644 --- a/apps/xmlrpc2di/XMLRPC2DI.cpp +++ b/apps/xmlrpc2di/XMLRPC2DI.cpp @@ -329,14 +329,21 @@ XMLRPC2DIServer::XMLRPC2DIServer(unsigned int port, s(s), // register method 'calls' calls_method(s), - // register method 'get_loglevel' - setloglevel_method(s), // register method 'set_loglevel' - getloglevel_method(s) + setloglevel_method(s), + // register method 'get_loglevel' + getloglevel_method(s), + // register method 'set_shutdownmode' + setshutdownmode_method(s), + // register method 'get_shutdownmode' + getshutdownmode_method(s) + { DBG("XMLRPC Server: enabled builtin method 'calls'\n"); DBG("XMLRPC Server: enabled builtin method 'get_loglevel'\n"); DBG("XMLRPC Server: enabled builtin method 'set_loglevel'\n"); + DBG("XMLRPC Server: enabled builtin method 'get_shutdownmode'\n"); + DBG("XMLRPC Server: enabled builtin method 'set_shutdownmode'\n"); // export all methods via 'di' function? if (di_export) { @@ -441,6 +448,18 @@ void XMLRPC2DIServerSetLoglevelMethod::execute(XmlRpcValue& params, XmlRpcValue& result = "200 OK"; } + +void XMLRPC2DIServerGetShutdownmodeMethod::execute(XmlRpcValue& params, XmlRpcValue& result) { + DBG("XMLRPC2DI: get_shutdownmode returns %s\n", AmConfig::ShutdownMode?"true":"false"); + result = (bool)AmConfig::ShutdownMode; +} + +void XMLRPC2DIServerSetShutdownmodeMethod::execute(XmlRpcValue& params, XmlRpcValue& result) { + AmConfig::ShutdownMode = params[0]; + DBG("XMLRPC2DI: set shutdownmode to %s.\n", AmConfig::ShutdownMode?"true":"false"); + result = "200 OK"; +} + void XMLRPC2DIServerDIMethod::execute(XmlRpcValue& params, XmlRpcValue& result) { try { if (params.size() < 2) { diff --git a/apps/xmlrpc2di/XMLRPC2DI.h b/apps/xmlrpc2di/XMLRPC2DI.h index 4d21cc98..13cc43bf 100644 --- a/apps/xmlrpc2di/XMLRPC2DI.h +++ b/apps/xmlrpc2di/XMLRPC2DI.h @@ -57,6 +57,9 @@ DEF_XMLRPCSERVERMETHOD(XMLRPC2DIServerCallsMethod, "calls"); DEF_XMLRPCSERVERMETHOD(XMLRPC2DIServerSetLoglevelMethod, "set_loglevel"); DEF_XMLRPCSERVERMETHOD(XMLRPC2DIServerGetLoglevelMethod, "get_loglevel"); +DEF_XMLRPCSERVERMETHOD(XMLRPC2DIServerSetShutdownmodeMethod, "set_shutdownmode"); +DEF_XMLRPCSERVERMETHOD(XMLRPC2DIServerGetShutdownmodeMethod, "get_shutdownmode"); + class XMLRPC2DIServerDIMethod : public XmlRpcServerMethod { @@ -90,6 +93,8 @@ class XMLRPC2DIServer : public AmThread { XMLRPC2DIServerCallsMethod calls_method; XMLRPC2DIServerSetLoglevelMethod setloglevel_method; XMLRPC2DIServerGetLoglevelMethod getloglevel_method; + XMLRPC2DIServerSetShutdownmodeMethod setshutdownmode_method; + XMLRPC2DIServerGetShutdownmodeMethod getshutdownmode_method; XMLRPC2DIServerDIMethod* di_method; void registerMethods(const std::string& iface); diff --git a/core/AmApi.cpp b/core/AmApi.cpp index 74489a9e..6ab5bfb2 100644 --- a/core/AmApi.cpp +++ b/core/AmApi.cpp @@ -76,27 +76,35 @@ void AmSessionFactory::configureSession(AmSession* sess) { void AmSessionFactory::onOoDRequest(const AmSipRequest& req) { - if(req.method == "OPTIONS"){ - - // Basic OPTIONS support - if (!AmConfig::OptionsSessionLimit || - (AmSession::getSessionNum() < AmConfig::OptionsSessionLimit)) { - AmSipDialog::reply_error(req, 200, "OK"); - } else { + + if (req.method == "OPTIONS") { + // Basic OPTIONS support + if (AmConfig::OptionsSessionLimit && + (AmSession::getSessionNum() >= AmConfig::OptionsSessionLimit)) { // return error code if near to overload AmSipDialog::reply_error(req, AmConfig::OptionsSessionLimitErrCode, AmConfig::OptionsSessionLimitErrReason); + return; } + + if (AmConfig::ShutdownMode) { + // return error code if in shutdown mode + AmSipDialog::reply_error(req, + AmConfig::ShutdownModeErrCode, + AmConfig::ShutdownModeErrReason); return; + } + AmSipDialog::reply_error(req, 200, "OK"); + return; } - ERROR("sorry, we don't support beginning a new session with " + ERROR("sorry, we don't support beginning a new session with " "a '%s' message\n", req.method.c_str()); - AmSipDialog::reply_error(req,501,"Not Implemented"); - return; + AmSipDialog::reply_error(req,501,"Not Implemented"); + return; } // void AmSessionFactory::postEvent(AmEvent* ev) { diff --git a/core/AmConfig.cpp b/core/AmConfig.cpp index eaa54209..29774031 100644 --- a/core/AmConfig.cpp +++ b/core/AmConfig.cpp @@ -94,6 +94,10 @@ unsigned int AmConfig::OptionsSessionLimit = 0; unsigned int AmConfig::OptionsSessionLimitErrCode = 503; string AmConfig::OptionsSessionLimitErrReason = "Server overload"; +bool AmConfig::ShutdownMode = false; +unsigned int AmConfig::ShutdownModeErrCode = 503; +string AmConfig::ShutdownModeErrReason = "Server shutting down"; + AmSipDialog::provisional_100rel AmConfig::rel100 = REL100_SUPPORTED; vector AmConfig::CodecOrder; @@ -487,6 +491,24 @@ int AmConfig::readConfiguration() } } + if(cfg.hasParameter("shutdown_mode_reply")){ + string c_reply = cfg.getParameter("shutdown_mode_reply"); + size_t spos = c_reply.find(" "); + if (spos == string::npos || spos == c_reply.length()) { + ERROR("invalid shutdown_mode_reply specified, expected \" \"," + "e.g. shutdown_mode_reply=\"503 Not At The Moment, Please\".\n"); + ret = -1; + + } else { + if (str2i(c_reply.substr(0, spos), ShutdownModeErrCode)) { + ERROR("invalid shutdown_mode_reply specified, expected \" \"," + "e.g. shutdown_mode_reply=\"503 Not At The Moment, Please\".\n"); + ret = -1; + } + ShutdownModeErrReason = c_reply.substr(spos+1); + } + } + if (cfg.hasParameter("100rel")) { string rel100s = cfg.getParameter("100rel"); if (rel100s == "disabled" || rel100s == "off") { diff --git a/core/AmConfig.h b/core/AmConfig.h index 2612e4ae..6a99c3cc 100644 --- a/core/AmConfig.h +++ b/core/AmConfig.h @@ -162,6 +162,10 @@ struct AmConfig static unsigned int OptionsSessionLimitErrCode; static string OptionsSessionLimitErrReason; + static bool ShutdownMode; + static unsigned int ShutdownModeErrCode; + static string ShutdownModeErrReason; + static AmSipDialog::provisional_100rel rel100; /** Time of no RTP after which Session is regarded as dead, 0 for no Timeout */ diff --git a/core/AmSessionContainer.cpp b/core/AmSessionContainer.cpp index 0bf1bb3d..4fb2e198 100644 --- a/core/AmSessionContainer.cpp +++ b/core/AmSessionContainer.cpp @@ -367,6 +367,15 @@ bool AmSessionContainer::postEvent(const string& local_tag, AmSession* AmSessionContainer::createSession(AmSipRequest& req, AmArg* session_params) { + if (AmConfig::ShutdownMode) { + _run_cond.set(true); // so that thread stops + DBG("Shutdown mode. Not creating session.\n"); + + AmSipDialog::reply_error(req,AmConfig::ShutdownModeErrCode, + AmConfig::ShutdownModeErrReason); + return NULL; + } + if (AmConfig::SessionLimit && AmConfig::SessionLimit <= AmSession::session_num) { diff --git a/core/etc/sems.conf.sample b/core/etc/sems.conf.sample index 4ed6c745..21714bff 100644 --- a/core/etc/sems.conf.sample +++ b/core/etc/sems.conf.sample @@ -228,15 +228,6 @@ stderr=no # (same as -D) loglevel=2 -# optional parameter: max_shutdown_time=