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_H323_H323TRANS_H
00032 #define OPAL_H323_H323TRANS_H
00033
00034 #ifdef P_USE_PRAGMA
00035 #pragma interface
00036 #endif
00037
00038 #include <opal/buildopts.h>
00039
00040 #if OPAL_H323
00041
00042 #include <h323/transaddr.h>
00043 #include <h323/h235auth.h>
00044
00045 #include <ptclib/asner.h>
00046
00047
00048 class H323EndPoint;
00049
00050
00051 class H323TransactionPDU {
00052 public:
00053 H323TransactionPDU();
00054 H323TransactionPDU(const H235Authenticators & auth);
00055
00056 virtual ~H323TransactionPDU() { }
00057
00058 virtual PBoolean Read(H323Transport & transport);
00059 virtual PBoolean Write(H323Transport & transport);
00060
00061 virtual PASN_Object & GetPDU() = 0;
00062 virtual PASN_Choice & GetChoice() = 0;
00063 virtual const PASN_Object & GetPDU() const = 0;
00064 virtual const PASN_Choice & GetChoice() const = 0;
00065 virtual unsigned GetSequenceNumber() const = 0;
00066 virtual unsigned GetRequestInProgressDelay() const = 0;
00067 #if PTRACING
00068 virtual const char * GetProtocolName() const = 0;
00069 #endif
00070 virtual H323TransactionPDU * ClonePDU() const = 0;
00071 virtual void DeletePDU() = 0;
00072
00073 const H235Authenticators & GetAuthenticators() const { return authenticators; }
00074 H235Authenticators & GetAuthenticators() { return authenticators; }
00075 void SetAuthenticators(
00076 const H235Authenticators & auth
00077 ) { authenticators = auth; }
00078
00079 H235Authenticator::ValidationResult Validate(
00080 const PASN_Array & clearTokens,
00081 unsigned clearOptionalField,
00082 const PASN_Array & cryptoTokens,
00083 unsigned cryptoOptionalField
00084 ) const { return authenticators.ValidatePDU(*this, clearTokens, clearOptionalField, cryptoTokens, cryptoOptionalField, rawPDU); }
00085
00086 void Prepare(
00087 PASN_Array & clearTokens,
00088 unsigned clearOptionalField,
00089 PASN_Array & cryptoTokens,
00090 unsigned cryptoOptionalField
00091 ) { authenticators.PreparePDU(*this, clearTokens, clearOptionalField, cryptoTokens, cryptoOptionalField); }
00092
00093 protected:
00094 mutable H235Authenticators authenticators;
00095 PPER_Stream rawPDU;
00096 };
00097
00098
00100
00101 class H323Transactor : public PObject
00102 {
00103 PCLASSINFO(H323Transactor, PObject);
00104 public:
00107
00110 H323Transactor(
00111 H323EndPoint & endpoint,
00112 H323Transport * transport,
00113 WORD localPort,
00114 WORD remotePort
00115 );
00116 H323Transactor(
00117 H323EndPoint & endpoint,
00118 const H323TransportAddress & iface,
00119 WORD localPort,
00120 WORD remotePort
00121 );
00122
00125 ~H323Transactor();
00127
00132 void PrintOn(
00133 ostream & strm
00134 ) const;
00136
00141 PBoolean SetTransport(
00142 const H323TransportAddress & iface
00143 );
00144
00147 H323TransportAddressArray GetInterfaceAddresses(
00148 bool excludeLocalHost = true
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_H323
00507
00508 #endif // OPAL_H323_H323TRANS_H
00509
00510