1 //////////////////////////////////////////////////////////////////
5 // Routing Mechanism for GNU Gatekeeper
7 // Copyright (c) Citron Network Inc. 2003
9 // This work is published under the GNU Public License (GPL)
10 // see file COPYING for details.
11 // We also explicitely grant the right to link this code
12 // with the OpenH323 library.
14 // initial author: Chih-Wei Huang <cwhuang@linux.org.tw>
15 // initial version: 06/18/2003
17 //////////////////////////////////////////////////////////////////
20 #define ROUTING_H "@(#) $Id: Routing.h,v 1.26 2007/03/10 12:16:09 shorne Exp $"
25 #include "singleton.h"
28 // forward references to avoid includes
29 class H225_AdmissionRequest;
30 class H225_LocationRequest;
31 class H225_Setup_UUIE;
32 class H225_Facility_UUIE;
33 class H225_TransportAddress;
34 class H225_ArrayOf_AliasAddress;
37 template <class> class H225SignalingMsg;
38 typedef H225SignalingMsg<H225_Setup_UUIE> SetupMsg;
39 typedef H225SignalingMsg<H225_Facility_UUIE> FacilityMsg;
45 /// An entry for a single call destination route
47 // a policy can set flags to indicate extra status of a processed request
55 const endptr &destEndpoint
58 const PString &policyName,
59 const H225_TransportAddress &destAddr
62 const PString &policyName,
63 const PIPSocket::Address &destIpAddr,
67 PString AsString() const;
69 bool IsFailoverActive(
73 H225_TransportAddress m_destAddr; /// destination address for signaling
74 endptr m_destEndpoint; /// destination endpoint record (if available)
75 H225_AliasAddress m_srcAddr; /// source alias that matched the route
76 PString m_policy; /// name of the policy that found the route
77 PString m_routeId; /// optional policy-specific route identifier
78 int m_proxyMode; /// per-route proxy mode flag
79 unsigned m_flags; /// additional route specific flags
80 unsigned char m_rerouteCauses[16]; /// bit flags to trigger rerouting on particular Q931 causes
83 class RoutingRequest {
92 // note this is not a polymorphic class
95 const std::list<Route> &failedRoutes
105 void RemoveAllRoutes();
106 std::list<Route> &GetRoutes() { return m_routes; }
108 void SetRejectReason(unsigned reason) { m_reason = reason; }
109 void SetFlag(unsigned f) { m_flags |= f; }
110 unsigned GetRejectReason() const { return m_reason; }
111 unsigned GetFlags() const { return m_flags; }
114 RoutingRequest(const RoutingRequest&);
115 RoutingRequest& operator=(const RoutingRequest&);
118 int m_reason; /// reject reason, if no routes are found
119 unsigned m_flags; /// request specific flags
120 std::list<Route> m_routes;
121 std::list<Route> m_failedRoutes;
124 template<class R, class W>
125 class Request : public RoutingRequest {
130 Request(ReqObj & r, Wrapper *w) : m_request(r), m_wrapper(w) {}
131 Request(ReqObj & r, Wrapper *w, const std::list<Route> &failedRoutes)
132 : RoutingRequest(failedRoutes), m_request(r), m_wrapper(w) {}
136 ReqObj & GetRequest() { return m_request; }
137 Wrapper *GetWrapper() { return m_wrapper; }
138 H225_ArrayOf_AliasAddress *GetAliases();
139 void SetAliases(H225_ArrayOf_AliasAddress & aliases);
140 const ReqObj & GetRequest() const { return m_request; }
141 const Wrapper *GetWrapper() const { return m_wrapper; }
142 const H225_ArrayOf_AliasAddress *GetAliases() const
143 { return const_cast<Request<R, W> *>(this)->GetAliases(); }
150 typedef Request<H225_AdmissionRequest, RasMsg> AdmissionRequest;
151 typedef Request<H225_LocationRequest, RasMsg> LocationRequest;
152 typedef Request<H225_Setup_UUIE, SetupMsg> SetupRequest;
153 typedef Request<H225_Facility_UUIE, FacilityMsg> FacilityRequest;
156 class Policy : public SList<Policy> {
158 Policy() : m_name("Undefined") {}
160 template <class R> bool HandleRas(Request<R,RasMsg> & request)
164 const char* tagname = request.GetWrapper()
165 ? request.GetWrapper()->GetTagName() : "unknown";
166 const unsigned seqnum = request.GetRequest().m_requestSeqNum.GetValue();
167 PTRACE(5,"ROUTING\tChecking policy "<<m_name
168 <<" for the request "<<tagname<<' '<<seqnum
171 if( OnRequest(request) ) {
173 PTRACE(5,"ROUTING\tPolicy "<<m_name
174 <<" applied to the request "<<tagname<<' '<<seqnum
180 return m_next && m_next->HandleRas(request);
183 bool Handle(SetupRequest &request);
184 bool Handle(FacilityRequest &request);
187 // new virtual function
188 // if return false, the policy is disable
189 virtual bool IsActive() { return true; }
191 // methods to handle the request
192 // return true: fate of the request is determined (confirm or reject)
193 // return false: undetermined, try next
194 virtual bool OnRequest(AdmissionRequest &) { return false; }
195 virtual bool OnRequest(LocationRequest &) { return false; }
196 virtual bool OnRequest(SetupRequest &) { return false; }
197 virtual bool OnRequest(FacilityRequest &) { return false; }
200 /// human readable name for the policy - it should be set inside constructors
201 /// of derived policies, default value is "undefined"
205 class AliasesPolicy : public Policy {
207 AliasesPolicy() { m_name = "Aliases"; }
210 // override from class Policy
211 virtual bool OnRequest(AdmissionRequest &);
212 virtual bool OnRequest(LocationRequest &);
213 virtual bool OnRequest(SetupRequest &);
214 virtual bool OnRequest(FacilityRequest &);
216 // new virtual function
217 virtual bool FindByAliases(RoutingRequest&, H225_ArrayOf_AliasAddress &) = 0;
218 virtual bool FindByAliases(LocationRequest&, H225_ArrayOf_AliasAddress&) = 0;
221 class Analyzer : public Singleton<Analyzer> {
228 bool Parse(AdmissionRequest &);
229 bool Parse(LocationRequest &);
230 bool Parse(SetupRequest &);
231 bool Parse(FacilityRequest &);
234 typedef std::map<PString, Policy *, pstr_prefix_lesser> Rules;
236 Policy *Create(const PString & policy);
237 Policy *ChoosePolicy(const H225_ArrayOf_AliasAddress *, Rules &);
240 PReadWriteMutex m_reloadMutex;
244 template<class R, class W>
245 inline bool Request<R, W>::Process()
247 return Analyzer::Instance()->Parse(*this);
250 /** A class that supports ACD (Automatic Call Distribution). A call
251 made to specified alias(-es) (called virtual queue) is signalled
252 via the GK status line to an external application (an ACD application)
253 that decides where the call should be routed (e.g. what agent should
254 answe the call). Basically, it rewrites virtual queue alias
255 into the alias of the specified agent.
257 The route request is uniquelly identified by (EndpointIdentifier,CRV)
266 /// reload settings from the config file
270 True if there is at least one virtual queue configured.
272 bool IsActive() const { return m_active; }
274 /** Send RouteRequest to the GK status line and wait
275 for a routing decision to be made by some external application
279 True if the external application routed the call (either by specifying
280 an alias or by rejecting the call), false if timed out waiting
281 for the routing decision.
282 If the request was rejected, destinationInfo is set to an epmty array
285 bool SendRouteRequest(
286 /// source IP of the request (endpoint for ARQ, gatekeeper for LRQ)
287 const PString& source,
290 /// CRV (Call Reference Value) of the call associated with this request
292 /// destination (virtual queue) aliases as specified
293 /// by the calling endpoint (modified by this function on successful return)
294 H225_ArrayOf_AliasAddress* destinationInfo,
295 /// destinationCallSignalAddr (optionally set by this function on successful return)
297 /// an actual virtual queue name (should be present in destinationInfo too)
298 const PString& vqueue,
299 /// a sequence of aliases for the calling endpoint
300 /// (in the "alias:type[=alias:type]..." format)
301 const PString& sourceInfo,
302 /// the callID as string
303 const PString& callID
306 /** Make a routing decision for a pending route request (inserted
310 True if the matching pending request has been found, false otherwise.
313 /// aliases for the routing target (an agent that the call will be routed to)
314 /// that will replace the original destination info
315 const H225_ArrayOf_AliasAddress& agent,
316 /// ip that will replace the destionationCallSignalAddress (RouteToGateway)
317 /// used only if set (port != 0)
318 const PString& destinationip,
319 /// identifier of the endpoint associated with the route request
320 const PString& callingEpId,
321 /// CRV of the call associated with the route request
323 /// callID of the call associated with the route request
324 const PString& callID
327 /** Make a routing decision for a pending route request (inserted
331 True if the matching pending request has been found, false otherwise.
334 /// alias for the routing target that
335 /// will replace the original destination info
336 const PString& agent,
337 /// will replace the original destinationCallSignallAddress
338 const PString& destinationip,
339 /// identifier of the endpoint associated with the route request
340 const PString& callingEpId,
341 /// CRV of the call associated with the route request
343 /// callID of the call associated with the route request
344 const PString& callID
347 /** Reject a pending route request (inserted by SendRequest).
350 True if the matching pending request has been found, false otherwise.
353 /// identifier of the endpoint associated with the route request
354 const PString& callingEpId,
355 /// CRV of the call associated with the route request
357 /// callID of the call associated with the route request
358 const PString& callID
362 True if the specified alias matches a name of an existing virtual queue.
364 bool IsDestinationVirtualQueue(
365 const PString& destinationAlias /// alias to be matched
369 /// a holder for a pending route request
373 const PString& callingEpId,
375 const PString& callID,
376 H225_ArrayOf_AliasAddress* agent,
377 PString* callsignaladdr
380 m_callingEpId((const char*)callingEpId), m_crv(crv), m_callID(callID),
381 m_agent(agent), m_callsignaladdr(callsignaladdr) {}
383 /// identifier for the endpoint associated with this request
384 PString m_callingEpId;
385 /// CRV for the call associated with this request
387 /// callID for the call associated with this request
389 /// aliases for the virtual queue matched (on input)
390 /// aliases for the target agent - target route (on output)
391 H225_ArrayOf_AliasAddress* m_agent;
392 /// destinationCallSignallAddress for the target agent - target route IF NOT NULL
393 PString* m_callsignaladdr;
394 /// a synchronization point for signalling that routing decision
395 /// has been made by the external application
399 typedef std::list<RouteRequest *> RouteRequests;
401 RouteRequest *InsertRequest(
402 /// identifier for the endpoint associated with this request
403 const PString& callingEpId,
404 /// CRV for the call associated with this request
406 /// callID for the call associated with this request
407 const PString& callID,
408 /// a pointer to an array to be filled with agent aliases
409 /// when the routing decision has been made
410 H225_ArrayOf_AliasAddress* agent,
411 /// a pointer to a string to be filled with a callSignalAddress
412 /// when the routing decision has been made (optional)
414 /// set by the function to true if another route request for the same
419 /// an array of names (aliases) for the virtual queues
420 PStringArray m_virtualQueueAliases;
421 /// an array of prefixes for the virtual queues
422 PStringArray m_virtualQueuePrefixes;
423 /// a regular expression for the virtual queues
424 PString m_virtualQueueRegex;
425 /// virtual queues enabled/disabled
427 /// time (in milliseconds) to wait for a routing decision to be made
428 long m_requestTimeout;
429 /// a list of active (pending) route requests
430 RouteRequests m_pendingRequests;
431 /// a mutex protecting pending requests and virtual queues lists
436 } // end of namespace Routing