00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef __OPAL_H323TRANS_H
00032 #define __OPAL_H323TRANS_H
00033
00034 #ifdef P_USE_PRAGMA
00035 #pragma interface
00036 #endif
00037
00038 #include <opal/buildopts.h>
00039
00040 #include <h323/transaddr.h>
00041 #include <h323/h235auth.h>
00042
00043 #include <ptclib/asner.h>
00044
00045
00046 class H323EndPoint;
00047
00048
00049 class H323TransactionPDU {
00050 public:
00051 H323TransactionPDU();
00052 H323TransactionPDU(const H235Authenticators & auth);
00053
00054 virtual ~H323TransactionPDU() { }
00055
00056 virtual PBoolean Read(H323Transport & transport);
00057 virtual PBoolean Write(H323Transport & transport);
00058
00059 virtual PASN_Object & GetPDU() = 0;
00060 virtual PASN_Choice & GetChoice() = 0;
00061 virtual const PASN_Object & GetPDU() const = 0;
00062 virtual const PASN_Choice & GetChoice() const = 0;
00063 virtual unsigned GetSequenceNumber() const = 0;
00064 virtual unsigned GetRequestInProgressDelay() const = 0;
00065 #if PTRACING
00066 virtual const char * GetProtocolName() const = 0;
00067 #endif
00068 virtual H323TransactionPDU * ClonePDU() const = 0;
00069 virtual void DeletePDU() = 0;
00070
00071 const H235Authenticators & GetAuthenticators() const { return authenticators; }
00072 H235Authenticators & GetAuthenticators() { return authenticators; }
00073 void SetAuthenticators(
00074 const H235Authenticators & auth
00075 ) { authenticators = auth; }
00076
00077 H235Authenticator::ValidationResult Validate(
00078 const PASN_Array & clearTokens,
00079 unsigned clearOptionalField,
00080 const PASN_Array & cryptoTokens,
00081 unsigned cryptoOptionalField
00082 ) const { return authenticators.ValidatePDU(*this, clearTokens, clearOptionalField, cryptoTokens, cryptoOptionalField, rawPDU); }
00083
00084 void Prepare(
00085 PASN_Array & clearTokens,
00086 unsigned clearOptionalField,
00087 PASN_Array & cryptoTokens,
00088 unsigned cryptoOptionalField
00089 ) { authenticators.PreparePDU(*this, clearTokens, clearOptionalField, cryptoTokens, cryptoOptionalField); }
00090
00091 protected:
00092 mutable H235Authenticators authenticators;
00093 PPER_Stream rawPDU;
00094 };
00095
00096
00098
00099 class H323Transactor : public PObject
00100 {
00101 PCLASSINFO(H323Transactor, PObject);
00102 public:
00105
00108 H323Transactor(
00109 H323EndPoint & endpoint,
00110 H323Transport * transport,
00111 WORD localPort,
00112 WORD remotePort
00113 );
00114 H323Transactor(
00115 H323EndPoint & endpoint,
00116 const H323TransportAddress & iface,
00117 WORD localPort,
00118 WORD remotePort
00119 );
00120
00123 ~H323Transactor();
00125
00130 void PrintOn(
00131 ostream & strm
00132 ) const;
00134
00139 PBoolean SetTransport(
00140 const H323TransportAddress & iface
00141 );
00142
00145 H323TransportAddressArray GetInterfaceAddresses(
00146 PBoolean excludeLocalHost = PTrue,
00147 H323Transport * associatedTransport = NULL
00149 );
00150
00153 virtual PBoolean StartChannel();
00154
00158 virtual void StopChannel();
00159
00162 virtual H323TransactionPDU * CreateTransactionPDU() const = 0;
00163
00166 virtual PBoolean HandleTransaction(
00167 const PASN_Object & rawPDU
00168 ) = 0;
00169
00172 virtual void OnSendingPDU(
00173 PASN_Object & rawPDU
00174 ) = 0;
00175
00178 virtual PBoolean WritePDU(
00179 H323TransactionPDU & pdu
00180 );
00181
00184 virtual PBoolean WriteTo(
00185 H323TransactionPDU & pdu,
00186 const H323TransportAddressArray & addresses,
00187 PBoolean callback = PTrue
00188 );
00190
00195 H323EndPoint & GetEndPoint() const { return endpoint; }
00196
00199 H323Transport & GetTransport() const { return *transport; }
00200
00203 void SetCheckResponseCryptoTokens(
00204 PBoolean value
00205 ) { checkResponseCryptoTokens = value; }
00206
00209 PBoolean GetCheckResponseCryptoTokens() { return checkResponseCryptoTokens; }
00211
00212 protected:
00213 void Construct();
00214
00215 unsigned GetNextSequenceNumber();
00216 PBoolean SetUpCallSignalAddresses(
00217 H225_ArrayOf_TransportAddress & addresses
00218 );
00219
00220
00221 PDECLARE_NOTIFIER(PThread, H323Transactor, HandleTransactions);
00222
00223 class Request : public PObject
00224 {
00225 PCLASSINFO(Request, PObject);
00226 public:
00227 Request(
00228 unsigned seqNum,
00229 H323TransactionPDU & pdu
00230 );
00231 Request(
00232 unsigned seqNum,
00233 H323TransactionPDU & pdu,
00234 const H323TransportAddressArray & addresses
00235 );
00236
00237 PBoolean Poll(H323Transactor &,
00238 unsigned numRetries = 0,
00239 PTimeInterval timeout = 0);
00240 void CheckResponse(unsigned, const PASN_Choice *);
00241 void OnReceiveRIP(unsigned milliseconds);
00242
00243
00244 unsigned rejectReason;
00245 void * responseInfo;
00246
00247 H323TransportAddressArray requestAddresses;
00248
00249 unsigned sequenceNumber;
00250 H323TransactionPDU & requestPDU;
00251 PTimeInterval whenResponseExpected;
00252 PSyncPoint responseHandled;
00253 PMutex responseMutex;
00254
00255 enum {
00256 AwaitingResponse,
00257 ConfirmReceived,
00258 RejectReceived,
00259 TryAlternate,
00260 BadCryptoTokens,
00261 RequestInProgress,
00262 NoResponseReceived
00263 } responseResult;
00264 };
00265
00266 virtual PBoolean MakeRequest(
00267 Request & request
00268 );
00269 PBoolean CheckForResponse(
00270 unsigned,
00271 unsigned,
00272 const PASN_Choice * = NULL
00273 );
00274 PBoolean HandleRequestInProgress(
00275 const H323TransactionPDU & pdu,
00276 unsigned delay
00277 );
00278 PBoolean CheckCryptoTokens(
00279 const H323TransactionPDU & pdu,
00280 const PASN_Array & clearTokens,
00281 unsigned clearOptionalField,
00282 const PASN_Array & cryptoTokens,
00283 unsigned cryptoOptionalField
00284 );
00285
00286 void AgeResponses();
00287 PBoolean SendCachedResponse(
00288 const H323TransactionPDU & pdu
00289 );
00290
00291 class Response : public PString
00292 {
00293 PCLASSINFO(Response, PString);
00294 public:
00295 Response(const H323TransportAddress & addr, unsigned seqNum);
00296 ~Response();
00297
00298 void SetPDU(const H323TransactionPDU & pdu);
00299 PBoolean SendCachedResponse(H323Transport & transport);
00300
00301 PTime lastUsedTime;
00302 PTimeInterval retirementAge;
00303 H323TransactionPDU * replyPDU;
00304 };
00305
00306
00307 H323EndPoint & endpoint;
00308 WORD defaultLocalPort;
00309 WORD defaultRemotePort;
00310 H323Transport * transport;
00311 PBoolean checkResponseCryptoTokens;
00312
00313 unsigned nextSequenceNumber;
00314 PMutex nextSequenceNumberMutex;
00315
00316 PDictionary<POrdinalKey, Request> requests;
00317 PMutex requestsMutex;
00318 Request * lastRequest;
00319
00320 PMutex pduWriteMutex;
00321 PSortedList<Response> responses;
00322 };
00323
00324
00326
00327 class H323Transaction : public PObject
00328 {
00329 PCLASSINFO(H323Transaction, PObject);
00330 public:
00335 H323Transaction(
00336 H323Transactor & transactor,
00337 const H323TransactionPDU & requestToCopy,
00338 H323TransactionPDU * confirm,
00339 H323TransactionPDU * reject
00340 );
00341 ~H323Transaction();
00343
00344 enum Response {
00345 Ignore = -2,
00346 Reject = -1,
00347 Confirm = 0
00348 };
00349 inline static Response InProgress(unsigned time) { return (Response)(time&0xffff); }
00350
00351 virtual H323TransactionPDU * CreateRIP(
00352 unsigned sequenceNumber,
00353 unsigned delay
00354 ) const = 0;
00355
00356 PBoolean HandlePDU();
00357
00358 virtual PBoolean WritePDU(
00359 H323TransactionPDU & pdu
00360 );
00361
00362 PBoolean CheckCryptoTokens(
00363 const H235Authenticators & authenticators
00364 );
00365
00366 #if PTRACING
00367 virtual const char * GetName() const = 0;
00368 #endif
00369 virtual H235Authenticator::ValidationResult ValidatePDU() const = 0;
00370 virtual void SetRejectReason(
00371 unsigned reasonCode
00372 ) = 0;
00373
00374 PBoolean IsFastResponseRequired() const { return fastResponseRequired && canSendRIP; }
00375 PBoolean CanSendRIP() const { return canSendRIP; }
00376 H323TransportAddress GetReplyAddress() const { return replyAddresses[0]; }
00377 const H323TransportAddressArray & GetReplyAddresses() const { return replyAddresses; }
00378 PBoolean IsBehindNAT() const { return isBehindNAT; }
00379 H323Transactor & GetTransactor() const { return transactor; }
00380 H235Authenticator::ValidationResult GetAuthenticatorResult() const { return authenticatorResult; }
00381
00382 protected:
00383 virtual Response OnHandlePDU() = 0;
00384 PDECLARE_NOTIFIER(PThread, H323Transaction, SlowHandler);
00385
00386 H323Transactor & transactor;
00387 unsigned requestSequenceNumber;
00388 H323TransportAddressArray replyAddresses;
00389 PBoolean fastResponseRequired;
00390 H323TransactionPDU * request;
00391 H323TransactionPDU * confirm;
00392 H323TransactionPDU * reject;
00393
00394 H235Authenticators authenticators;
00395 H235Authenticator::ValidationResult authenticatorResult;
00396 PBoolean isBehindNAT;
00397 PBoolean canSendRIP;
00398 };
00399
00400
00402
00403 class H323TransactionServer : public PObject
00404 {
00405 PCLASSINFO(H323TransactionServer, PObject);
00406 public:
00411 H323TransactionServer(
00412 H323EndPoint & endpoint
00413 );
00414
00417 ~H323TransactionServer();
00419
00420 virtual WORD GetDefaultUdpPort() = 0;
00421
00426 H323EndPoint & GetOwnerEndPoint() const { return ownerEndPoint; }
00427
00441 PBoolean AddListeners(
00442 const H323TransportAddressArray & ifaces
00443 );
00444
00448 PBoolean AddListener(
00449 const H323TransportAddress & interfaceName
00450 );
00451
00458 PBoolean AddListener(
00459 H323Transport * transport
00460 );
00461
00468 PBoolean AddListener(
00469 H323Transactor * listener
00470 );
00471
00480 virtual H323Transactor * CreateListener(
00481 H323Transport * transport
00482 ) = 0;
00483
00487 PBoolean RemoveListener(
00488 H323Transactor * listener
00489 );
00490
00491 PBoolean SetUpCallSignalAddresses(H225_ArrayOf_TransportAddress & addresses);
00493
00494 protected:
00495 H323EndPoint & ownerEndPoint;
00496
00497 PThread * monitorThread;
00498 PSyncPoint monitorExit;
00499
00500 PMutex mutex;
00501 PLIST(ListenerList, H323Transactor);
00502 ListenerList listeners;
00503 };
00504
00505
00506 #endif // __OPAL_H323TRANS_H
00507
00508