1 /* 2 * Copyright (C) 2002-2003 Fhg Fokus 3 * 4 * This file is part of SEMS, a free SIP media server. 5 * 6 * SEMS is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. This program is released under 10 * the GPL with the additional exemption that compiling, linking, 11 * and/or using OpenSSL is allowed. 12 * 13 * For a license to use the SEMS software under conditions 14 * other than those described here, or to purchase support for this 15 * software, please contact iptel.org by e-mail at the following addresses: 16 * info@iptel.org 17 * 18 * SEMS is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 */ 27 /** @file AmSessionContainer.h */ 28 #ifndef AmSessionContainer_h 29 #define AmSessionContainer_h 30 31 #include "AmThread.h" 32 #include "AmSession.h" 33 34 #include "ampi/MonitoringAPI.h" 35 36 #include <string> 37 #include <queue> 38 #include <map> 39 40 using std::string; 41 42 /** 43 * \brief Centralized session container. 44 * 45 * This is the register for all active and dead sessions. 46 * If has a deamon which wakes up only if it has work. 47 * Then, it kills all dead sessions and try to go to bed 48 * (it cannot sleep if one or more sessions are still alive). 49 */ 50 class AmSessionContainer : public AmThread 51 { 52 static AmSessionContainer* _instance; 53 54 typedef std::queue<AmSession*> SessionQueue; 55 56 /** Container for dead sessions */ 57 SessionQueue d_sessions; 58 /** Mutex to protect the dead session container */ 59 AmMutex ds_mut; 60 61 /** is container closed for new sessions? */ 62 AmCondition<bool> _container_closed; 63 64 /** the daemon only runs if this is true */ 65 AmCondition<bool> _run_cond; 66 67 /** We are a Singleton ! Avoid people to have their own instance. */ 68 AmSessionContainer(); 69 70 71 bool enable_unclean_shutdown; 72 73 /** 74 * Tries to stop the session and queue it destruction. 75 */ 76 void stopAndQueue(AmSession* s); 77 78 /** @see AmThread::run() */ 79 void run(); 80 /** @see AmThread::on_stop() */ 81 void on_stop(); 82 83 bool clean_sessions(); 84 85 typedef std::queue<struct timeval> TimevalQueue; 86 87 /** Container for cps timevals*/ 88 TimevalQueue cps_queue; 89 /** Maximum cps since the lasd getMaxCPS()*/ 90 unsigned int max_cps; 91 /** Mutex to protect the cps container */ 92 AmMutex cps_mut; 93 94 enum { CPS_SAMPLERATE = 5 }; 95 96 unsigned int CPSLimit; 97 unsigned int CPSHardLimit; 98 99 bool check_and_add_cps(); 100 101 public: 102 static AmSessionContainer* instance(); 103 104 static void dispose(); 105 106 enum AddSessionStatus { 107 ShutDown, 108 Inserted, 109 AlreadyExist 110 }; 111 112 /** 113 * Creates a new session. 114 * @param req local request 115 * @return a new session or NULL on error. 116 */ 117 AmSession* createSession(const AmSipRequest& req, 118 string& app_name, 119 AmArg* session_params = NULL); 120 121 /** 122 * Adds a session to the container (UAS only). 123 * @return true if the session is new within the container. 124 */ 125 AddSessionStatus addSession(const string& callid, 126 const string& remote_tag, 127 const string& local_tag, 128 const string& via_branch, 129 AmSession* session); 130 131 /** 132 * Adds a session to the container. 133 * @return true if the session is new within the container. 134 */ 135 AddSessionStatus addSession(const string& local_tag, 136 AmSession* session); 137 138 /** 139 * Constructs a new session and adds it to the active session container. 140 * @param req client's request 141 */ 142 void startSessionUAS(AmSipRequest& req); 143 144 /** 145 * Constructs a new session and adds it to the active session container. 146 * @param req client's request 147 */ 148 string startSessionUAC(const AmSipRequest& req, 149 string& app_name, 150 AmArg* session_params = NULL); 151 152 /** 153 * Detroys a session. 154 */ 155 void destroySession(AmSession* s); 156 157 /** 158 * post an event into the event queue of the identified dialog. 159 * @return false if session doesn't exist 160 */ 161 bool postEvent(const string& callid, 162 const string& remote_tag, 163 const string& via_branch, 164 AmEvent* event); 165 166 /** 167 * post a generic event into the event queue of the identified dialog. 168 * sess_key is local_tag (to_tag) 169 * note: if hash_str is known, use 170 * postGenericEvent(hash_str,sess_key,event); 171 * for better performance. 172 * @return false if session doesn't exist 173 */ 174 bool postEvent(const string& local_tag, AmEvent* event); 175 176 /** 177 * broadcasts a server shutdown system event to all sessions 178 */ 179 void broadcastShutdown(); 180 181 /** enable unclean shutdown (will not broadcastShutdown event) */ 182 void enableUncleanShutdown(); 183 184 /** Set the maximum number of calls per second to be accepted */ 185 void setCPSLimit(unsigned int limit); 186 187 /** Set the maximum number of calls per second to be accepted as a percent 188 * of the current CPS. Intented to be used by the components. 0 means turning off 189 * the soft limit. 190 */ 191 void setCPSSoftLimit(unsigned int percent); 192 193 /** Return the maximum number of calls per second to be accepted */ 194 pair<unsigned int, unsigned int> getCPSLimit(); 195 196 /** 197 * Gets the timeaverage of calls per second in the last CPS_SAMPLERATE sec window 198 */ 199 unsigned int getAvgCPS(); 200 /** 201 * Gets the maximum of calls per second since last query 202 */ 203 unsigned int getMaxCPS(); 204 205 void initMonitoring(); 206 207 _MONITORING_DEFINE_INTERFACE; 208 209 }; 210 211 #endif 212