4 * H.323 Transactor handler
8 * Copyright (c) 2003 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
20 * The Original Code is Open H323 Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Contributor(s): ______________________________________.
27 * Revision 1.17 2005/11/30 13:05:01 csoutheren
28 * Changed tags for Doxygen
30 * Revision 1.16 2004/08/24 08:11:24 csoutheren
31 * Added initial support for receiving broadcasts on Linux
33 * Revision 1.15 2003/12/11 05:39:04 csoutheren
34 * Added storage of H.225 version in endpoint structure
35 * Disabled sending RIPs to endpoints that cannot handle them
37 * Revision 1.14 2003/04/30 07:50:58 robertj
38 * Redesigned the alternate credentials in ARQ system as old implementation
39 * was fraught with concurrency issues, most importantly it can cause false
40 * detection of replay attacks taking out an endpoint completely.
42 * Revision 1.13 2003/04/10 09:40:05 robertj
43 * Added associated transport to new GetInterfaceAddresses() function so
44 * interfaces can be ordered according to active transport links. Improves
47 * Revision 1.12 2003/04/10 01:03:58 craigs
48 * Added functions to access to lists of interfaces
50 * Revision 1.11 2003/04/09 03:08:06 robertj
51 * Fixed race condition in shutting down transactor (pure virtual call)
53 * Revision 1.10 2003/04/01 05:59:30 robertj
54 * Fixed H.501 transaction code setting members for m_common PDU part.
56 * Revision 1.9 2003/04/01 04:47:48 robertj
57 * Abstracted H.225 RAS transaction processing (RIP and secondary thread) in
58 * server environment for use by H.501 peer elements.
60 * Revision 1.8 2003/03/26 00:46:25 robertj
61 * Had another go at making H323Transactor being able to be created
62 * without having a listener running.
64 * Revision 1.7 2003/03/25 04:56:17 robertj
65 * Fixed issues to do with multiple inheritence in transaction reply cache.
67 * Revision 1.6 2003/03/21 05:26:45 robertj
68 * Added setting of remote port in UDP transport constructor.
70 * Revision 1.5 2003/03/20 01:51:07 robertj
71 * More abstraction of H.225 RAS and H.501 protocols transaction handling.
73 * Revision 1.4 2003/03/01 00:23:42 craigs
74 * New PeerElement implementation
76 * Revision 1.3 2003/02/25 06:48:15 robertj
77 * More work on PDU transaction abstraction.
79 * Revision 1.2 2003/02/25 03:14:58 robertj
80 * Added missing virtual destructor.
82 * Revision 1.1 2003/02/21 05:28:39 craigs
83 * Factored out code for user with peer elements
87 #ifndef __OPAL_H323TRANS_H
88 #define __OPAL_H323TRANS_H
94 #include "transports.h"
97 #include <ptclib/asner.h>
100 class H323TransactionPDU
{
102 H323TransactionPDU();
103 H323TransactionPDU(const H235Authenticators
& auth
);
105 virtual ~H323TransactionPDU() { }
107 virtual BOOL
Read(H323Transport
& transport
);
108 virtual BOOL
Write(H323Transport
& transport
);
110 virtual PASN_Object
& GetPDU() = 0;
111 virtual PASN_Choice
& GetChoice() = 0;
112 virtual const PASN_Object
& GetPDU() const = 0;
113 virtual const PASN_Choice
& GetChoice() const = 0;
114 virtual unsigned GetSequenceNumber() const = 0;
115 virtual unsigned GetRequestInProgressDelay() const = 0;
117 virtual const char * GetProtocolName() const = 0;
119 virtual H323TransactionPDU
* ClonePDU() const = 0;
120 virtual void DeletePDU() = 0;
122 const H235Authenticators
& GetAuthenticators() const { return authenticators
; }
123 void SetAuthenticators(
124 const H235Authenticators
& auth
125 ) { authenticators
= auth
; }
127 H235Authenticator::ValidationResult
Validate(
128 const PASN_Array
& clearTokens
,
129 unsigned clearOptionalField
,
130 const PASN_Array
& cryptoTokens
,
131 unsigned cryptoOptionalField
132 ) const { return authenticators
.ValidatePDU(*this, clearTokens
, clearOptionalField
, cryptoTokens
, cryptoOptionalField
, rawPDU
); }
135 PASN_Array
& clearTokens
,
136 unsigned clearOptionalField
,
137 PASN_Array
& cryptoTokens
,
138 unsigned cryptoOptionalField
139 ) { authenticators
.PreparePDU(*this, clearTokens
, clearOptionalField
, cryptoTokens
, cryptoOptionalField
); }
142 H235Authenticators authenticators
;
147 ///////////////////////////////////////////////////////////
149 class H323Transactor
: public PObject
151 PCLASSINFO(H323Transactor
, PObject
);
153 /**@name Construction */
156 /**Create a new protocol handler.
159 H323EndPoint
& endpoint
, ///< Endpoint gatekeeper is associated with.
160 H323Transport
* transport
, ///< Transport over which to communicate.
161 WORD localPort
, ///< Local port to listen on
162 WORD remotePort
///< Remote port to connect on
165 H323EndPoint
& endpoint
, ///< Endpoint gatekeeper is associated with.
166 const H323TransportAddress
& iface
, ///< Local interface over which to communicate.
167 WORD localPort
, ///< Local port to listen on
168 WORD remotePort
///< Remote port to connect on
171 /**Destroy protocol handler.
176 /**@name Overrides from PObject */
178 /**Print the name of the gatekeeper.
181 ostream
& strm
///< Stream to print to.
185 /**@name new operations */
187 /**Set a new transport for use by the transactor.
190 const H323TransportAddress
& iface
///< Local interface for transport
193 /**Return the list of addresses used for this peer element
195 H323TransportAddressArray
GetInterfaceAddresses(
196 BOOL excludeLocalHost
= TRUE
, ///< Flag to exclude 127.0.0.1
197 H323Transport
* associatedTransport
= NULL
198 ///< Associated transport for precedence and translation
201 /**Start the channel processing transactions
203 virtual BOOL
StartChannel();
205 /**Stop the channel processing transactions.
206 Must be called in each descendants destructor.
208 virtual void StopChannel();
210 /**Create the transaction PDU for reading.
212 virtual H323TransactionPDU
* CreateTransactionPDU() const = 0;
214 /**Handle and dispatch a transaction PDU
216 virtual BOOL
HandleTransaction(
217 const PASN_Object
& rawPDU
220 /**Allow for modifications to PDU on send.
222 virtual void OnSendingPDU(
226 /**Write PDU to transport after executing callback.
228 virtual BOOL
WritePDU(
229 H323TransactionPDU
& pdu
232 /**Write PDU to transport after executing callback.
234 virtual BOOL
WriteTo(
235 H323TransactionPDU
& pdu
,
236 const H323TransportAddressArray
& addresses
,
241 /**@name Member variable access */
243 /**Get the gatekeepers associated endpoint.
245 H323EndPoint
& GetEndPoint() const { return endpoint
; }
247 /**Get the gatekeepers transport channel.
249 H323Transport
& GetTransport() const { return *transport
; }
251 /**Set flag to check all crypto tokens on responses.
253 void SetCheckResponseCryptoTokens(
254 BOOL value
///< New value for checking crypto tokens.
255 ) { checkResponseCryptoTokens
= value
; }
257 /**Get flag to check all crypto tokens on responses.
259 BOOL
GetCheckResponseCryptoTokens() { return checkResponseCryptoTokens
; }
265 unsigned GetNextSequenceNumber();
266 BOOL
SetUpCallSignalAddresses(
267 H225_ArrayOf_TransportAddress
& addresses
270 //Background thread handler.
271 PDECLARE_NOTIFIER(PThread
, H323Transactor
, HandleTransactions
);
273 class Request
: public PObject
275 PCLASSINFO(Request
, PObject
);
279 H323TransactionPDU
& pdu
283 H323TransactionPDU
& pdu
,
284 const H323TransportAddressArray
& addresses
287 BOOL
Poll(H323Transactor
&);
288 void CheckResponse(unsigned, const PASN_Choice
*);
289 void OnReceiveRIP(unsigned milliseconds
);
291 // Inter-thread transfer variables
292 unsigned rejectReason
;
295 H323TransportAddressArray requestAddresses
;
297 unsigned sequenceNumber
;
298 H323TransactionPDU
& requestPDU
;
299 PTimeInterval whenResponseExpected
;
300 PSyncPoint responseHandled
;
301 PMutex responseMutex
;
314 virtual BOOL
MakeRequest(
317 BOOL
CheckForResponse(
320 const PASN_Choice
* = NULL
322 BOOL
HandleRequestInProgress(
323 const H323TransactionPDU
& pdu
,
326 BOOL
CheckCryptoTokens(
327 const H323TransactionPDU
& pdu
,
328 const PASN_Array
& clearTokens
,
329 unsigned clearOptionalField
,
330 const PASN_Array
& cryptoTokens
,
331 unsigned cryptoOptionalField
335 BOOL
SendCachedResponse(
336 const H323TransactionPDU
& pdu
339 class Response
: public PString
341 PCLASSINFO(Response
, PString
);
343 Response(const H323TransportAddress
& addr
, unsigned seqNum
);
346 void SetPDU(const H323TransactionPDU
& pdu
);
347 BOOL
SendCachedResponse(H323Transport
& transport
);
350 PTimeInterval retirementAge
;
351 H323TransactionPDU
* replyPDU
;
354 // Configuration variables
355 H323EndPoint
& endpoint
;
356 WORD defaultLocalPort
;
357 WORD defaultRemotePort
;
358 H323Transport
* transport
;
359 BOOL checkResponseCryptoTokens
;
361 unsigned nextSequenceNumber
;
362 PMutex nextSequenceNumberMutex
;
364 PDictionary
<POrdinalKey
, Request
> requests
;
365 PMutex requestsMutex
;
366 Request
* lastRequest
;
368 PMutex pduWriteMutex
;
369 PSortedList
<Response
> responses
;
373 ////////////////////////////////////////////////////////////////////////////////////
375 class H323Transaction
: public PObject
377 PCLASSINFO(H323Transaction
, PObject
);
379 /**@name Construction */
381 /**Create a new transaction handler.
384 H323Transactor
& transactor
,
385 const H323TransactionPDU
& requestToCopy
,
386 H323TransactionPDU
* confirm
,
387 H323TransactionPDU
* reject
397 inline static Response
InProgress(unsigned time
) { return (Response
)(time
&0xffff); }
399 virtual H323TransactionPDU
* CreateRIP(
400 unsigned sequenceNumber
,
406 virtual BOOL
WritePDU(
407 H323TransactionPDU
& pdu
410 BOOL
CheckCryptoTokens(
411 const H235Authenticators
& authenticators
415 virtual const char * GetName() const = 0;
417 virtual H235Authenticator::ValidationResult
ValidatePDU() const = 0;
418 virtual void SetRejectReason(
422 BOOL
IsFastResponseRequired() const { return fastResponseRequired
&& canSendRIP
; }
423 BOOL
CanSendRIP() const { return canSendRIP
; }
424 H323TransportAddress
GetReplyAddress() const { return replyAddresses
[0]; }
425 const H323TransportAddressArray
& GetReplyAddresses() const { return replyAddresses
; }
426 BOOL
IsBehindNAT() const { return isBehindNAT
; }
427 H323Transactor
& GetTransactor() const { return transactor
; }
428 H235Authenticator::ValidationResult
GetAuthenticatorResult() const { return authenticatorResult
; }
431 virtual Response
OnHandlePDU() = 0;
432 PDECLARE_NOTIFIER(PThread
, H323Transaction
, SlowHandler
);
434 H323Transactor
& transactor
;
435 unsigned requestSequenceNumber
;
436 H323TransportAddressArray replyAddresses
;
437 BOOL fastResponseRequired
;
438 H323TransactionPDU
* request
;
439 H323TransactionPDU
* confirm
;
440 H323TransactionPDU
* reject
;
442 H235Authenticators authenticators
;
443 H235Authenticator::ValidationResult authenticatorResult
;
449 ///////////////////////////////////////////////////////////
451 class H323TransactionServer
: public PObject
453 PCLASSINFO(H323TransactionServer
, PObject
);
455 /**@name Construction */
457 /**Create a new gatekeeper.
459 H323TransactionServer(
460 H323EndPoint
& endpoint
463 /**Destroy gatekeeper.
465 ~H323TransactionServer();
468 virtual WORD
GetDefaultUdpPort() = 0;
470 /**@name Access functions */
472 /**Get the owner endpoint.
474 H323EndPoint
& GetOwnerEndPoint() const { return ownerEndPoint
; }
476 /**@name Protocol Handler Operations */
478 /**Add listeners to the transaction server.
479 If a listener already exists on the interface specified in the list
480 then it is ignored. If a listener does not yet exist a new one is
481 created and if a listener is running that is not in the list then it
482 is stopped and removed.
484 If the array is empty then the string "*" is assumed which will listen
485 on the standard UDP port on INADDR_ANY.
487 Returns TRUE if at least one interface was successfully started.
490 const H323TransportAddressArray
& ifaces
///< Interfaces to listen on.
493 /**Add a gatekeeper listener to this gatekeeper server given the
494 transport address for the local interface.
497 const H323TransportAddress
& interfaceName
500 /**Add a gatekeeper listener to this gatekeeper server given the transport.
501 Note that the transport is then owned by the listener and will be
502 deleted automatically when the listener is destroyed. Note also the
503 transport is deleted if this function returns FALSE and no listener was
507 H323Transport
* transport
510 /**Add a gatekeeper listener to this gatekeeper server.
511 Note that the gatekeeper listener is then owned by the gatekeeper
512 server and will be deleted automatically when the listener is removed.
513 Note also the listener is deleted if this function returns FALSE and
514 the listener was not used.
517 H323Transactor
* listener
520 /**Create a new H323GatkeeperListener.
521 The user woiuld not usually use this function as it is used internally
522 by the server when new listeners are added by H323TransportAddress.
524 However, a user may override this function to create objects that are
525 user defined descendants of H323GatekeeperListener so the user can
526 maintain extra information on a interface by interface basis.
528 virtual H323Transactor
* CreateListener(
529 H323Transport
* transport
///< Transport for listener
532 /**Remove a gatekeeper listener from this gatekeeper server.
533 The gatekeeper listener is automatically deleted.
536 H323Transactor
* listener
539 BOOL
SetUpCallSignalAddresses(H225_ArrayOf_TransportAddress
& addresses
);
543 H323EndPoint
& ownerEndPoint
;
545 PThread
* monitorThread
;
546 PSyncPoint monitorExit
;
549 PLIST(ListenerList
, H323Transactor
);
550 ListenerList listeners
;
551 BOOL usingAllInterfaces
;
555 #endif // __OPAL_H323TRANS_H
558 /////////////////////////////////////////////////////////////////////////////