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