home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / openh323.tar.gz / openh323.tar / openh323 / include / h323trans.h < prev    next >
C/C++ Source or Header  |  2003-04-30  |  16KB  |  546 lines

  1. /*
  2.  * h323trans.h
  3.  *
  4.  * H.323 Transactor handler
  5.  *
  6.  * Open H323 Library
  7.  *
  8.  * Copyright (c) 2003 Equivalence Pty. Ltd.
  9.  *
  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/
  14.  *
  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
  18.  * under the License.
  19.  *
  20.  * The Original Code is Open H323 Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Contributor(s): ______________________________________.
  25.  *
  26.  * $Log: h323trans.h,v $
  27.  * Revision 1.14  2003/04/30 07:50:58  robertj
  28.  * Redesigned the alternate credentials in ARQ system as old implementation
  29.  *   was fraught with concurrency issues, most importantly it can cause false
  30.  *   detection of replay attacks taking out an endpoint completely.
  31.  *
  32.  * Revision 1.13  2003/04/10 09:40:05  robertj
  33.  * Added associated transport to new GetInterfaceAddresses() function so
  34.  *   interfaces can be ordered according to active transport links. Improves
  35.  *   interoperability.
  36.  *
  37.  * Revision 1.12  2003/04/10 01:03:58  craigs
  38.  * Added functions to access to lists of interfaces
  39.  *
  40.  * Revision 1.11  2003/04/09 03:08:06  robertj
  41.  * Fixed race condition in shutting down transactor (pure virtual call)
  42.  *
  43.  * Revision 1.10  2003/04/01 05:59:30  robertj
  44.  * Fixed H.501 transaction code setting members for m_common PDU part.
  45.  *
  46.  * Revision 1.9  2003/04/01 04:47:48  robertj
  47.  * Abstracted H.225 RAS transaction processing (RIP and secondary thread) in
  48.  *   server environment for use by H.501 peer elements.
  49.  *
  50.  * Revision 1.8  2003/03/26 00:46:25  robertj
  51.  * Had another go at making H323Transactor being able to be created
  52.  *   without having a listener running.
  53.  *
  54.  * Revision 1.7  2003/03/25 04:56:17  robertj
  55.  * Fixed issues to do with multiple inheritence in transaction reply cache.
  56.  *
  57.  * Revision 1.6  2003/03/21 05:26:45  robertj
  58.  * Added setting of remote port in UDP transport constructor.
  59.  *
  60.  * Revision 1.5  2003/03/20 01:51:07  robertj
  61.  * More abstraction of H.225 RAS and H.501 protocols transaction handling.
  62.  *
  63.  * Revision 1.4  2003/03/01 00:23:42  craigs
  64.  * New PeerElement implementation
  65.  *
  66.  * Revision 1.3  2003/02/25 06:48:15  robertj
  67.  * More work on PDU transaction abstraction.
  68.  *
  69.  * Revision 1.2  2003/02/25 03:14:58  robertj
  70.  * Added missing virtual destructor.
  71.  *
  72.  * Revision 1.1  2003/02/21 05:28:39  craigs
  73.  * Factored out code for user with peer elements
  74.  *
  75.  */
  76.  
  77. #ifndef __OPAL_H323TRANS_H
  78. #define __OPAL_H323TRANS_H
  79.  
  80. #ifdef P_USE_PRAGMA
  81. #pragma interface
  82. #endif
  83.  
  84. #include "transports.h"
  85. #include "h235auth.h"
  86.  
  87. #include <ptclib/asner.h>
  88.  
  89.  
  90. class H323TransactionPDU {
  91.   public:
  92.     H323TransactionPDU();
  93.     H323TransactionPDU(const H235Authenticators & auth);
  94.  
  95.     virtual ~H323TransactionPDU() { }
  96.  
  97.     virtual BOOL Read(H323Transport & transport);
  98.     virtual BOOL Write(H323Transport & transport);
  99.  
  100.     virtual PASN_Object & GetPDU() = 0;
  101.     virtual PASN_Choice & GetChoice() = 0;
  102.     virtual const PASN_Object & GetPDU() const = 0;
  103.     virtual const PASN_Choice & GetChoice() const = 0;
  104.     virtual unsigned GetSequenceNumber() const = 0;
  105.     virtual unsigned GetRequestInProgressDelay() const = 0;
  106. #if PTRACING
  107.     virtual const char * GetProtocolName() const = 0;
  108. #endif
  109.     virtual H323TransactionPDU * ClonePDU() const = 0;
  110.     virtual void DeletePDU() = 0;
  111.  
  112.     const H235Authenticators & GetAuthenticators() const { return authenticators; }
  113.     void SetAuthenticators(
  114.       const H235Authenticators & auth
  115.     ) { authenticators = auth; }
  116.  
  117.     H235Authenticator::ValidationResult Validate(
  118.       const PASN_Array & clearTokens,
  119.       unsigned clearOptionalField,
  120.       const PASN_Array & cryptoTokens,
  121.       unsigned cryptoOptionalField
  122.     ) const { return authenticators.ValidatePDU(*this, clearTokens, clearOptionalField, cryptoTokens, cryptoOptionalField, rawPDU); }
  123.  
  124.     void Prepare(
  125.       PASN_Array & clearTokens,
  126.       unsigned clearOptionalField,
  127.       PASN_Array & cryptoTokens,
  128.       unsigned cryptoOptionalField
  129.     ) { authenticators.PreparePDU(*this, clearTokens, clearOptionalField, cryptoTokens, cryptoOptionalField); }
  130.  
  131.   protected:
  132.     H235Authenticators authenticators;
  133.     PPER_Stream        rawPDU;
  134. };
  135.  
  136.  
  137. ///////////////////////////////////////////////////////////
  138.  
  139. class H323Transactor : public PObject
  140. {
  141.   PCLASSINFO(H323Transactor, PObject);
  142.   public:
  143.   /**@name Construction */
  144.   //@{
  145.  
  146.     /**Create a new protocol handler.
  147.      */
  148.     H323Transactor(
  149.       H323EndPoint & endpoint,   /// Endpoint gatekeeper is associated with.
  150.       H323Transport * transport, /// Transport over which to communicate.
  151.       WORD localPort,                     /// Local port to listen on
  152.       WORD remotePort                     /// Remote port to connect on
  153.     );
  154.     H323Transactor(
  155.       H323EndPoint & endpoint,   /// Endpoint gatekeeper is associated with.
  156.       const H323TransportAddress & iface, /// Local interface over which to communicate.
  157.       WORD localPort,                     /// Local port to listen on
  158.       WORD remotePort                     /// Remote port to connect on
  159.     );
  160.  
  161.     /**Destroy protocol handler.
  162.      */
  163.     ~H323Transactor();
  164.   //@}
  165.  
  166.   /**@name Overrides from PObject */
  167.   //@{
  168.     /**Print the name of the gatekeeper.
  169.       */
  170.     void PrintOn(
  171.       ostream & strm    /// Stream to print to.
  172.     ) const;
  173.   //@}
  174.  
  175.   /**@name new operations */
  176.   //@{
  177.     /**Set a new transport for use by the transactor.
  178.       */
  179.     BOOL SetTransport(
  180.       const H323TransportAddress & iface // Local interface for transport
  181.     );
  182.  
  183.     /**Return the list of addresses used for this peer element
  184.       */
  185.     H323TransportAddressArray GetInterfaceAddresses(
  186.       BOOL excludeLocalHost = TRUE,       /// Flag to exclude 127.0.0.1
  187.       H323Transport * associatedTransport = NULL
  188.                           /// Associated transport for precedence and translation
  189.     );
  190.  
  191.     /**Start the channel processing transactions
  192.       */
  193.     virtual BOOL StartChannel();
  194.  
  195.     /**Stop the channel processing transactions.
  196.        Must be called in each descendants destructor.
  197.       */
  198.     virtual void StopChannel();
  199.  
  200.     /**Create the transaction PDU for reading.
  201.       */
  202.     virtual H323TransactionPDU * CreateTransactionPDU() const = 0;
  203.  
  204.     /**Handle and dispatch a transaction PDU
  205.       */
  206.     virtual BOOL HandleTransaction(
  207.       const PASN_Object & rawPDU
  208.     ) = 0;
  209.  
  210.     /**Allow for modifications to PDU on send.
  211.       */
  212.     virtual void OnSendingPDU(
  213.       PASN_Object & rawPDU
  214.     ) = 0;
  215.  
  216.     /**Write PDU to transport after executing callback.
  217.       */
  218.     virtual BOOL WritePDU(
  219.       H323TransactionPDU & pdu
  220.     );
  221.  
  222.     /**Write PDU to transport after executing callback.
  223.       */
  224.     virtual BOOL WriteTo(
  225.       H323TransactionPDU & pdu,
  226.       const H323TransportAddressArray & addresses,
  227.       BOOL callback = TRUE
  228.     );
  229.   //@}
  230.  
  231.   /**@name Member variable access */
  232.   //@{
  233.     /**Get the gatekeepers associated endpoint.
  234.       */
  235.     H323EndPoint & GetEndPoint() const { return endpoint; }
  236.  
  237.     /**Get the gatekeepers transport channel.
  238.       */
  239.     H323Transport & GetTransport() const { return *transport; }
  240.  
  241.     /**Set flag to check all crypto tokens on responses.
  242.       */
  243.     void SetCheckResponseCryptoTokens(
  244.       BOOL value    /// New value for checking crypto tokens.
  245.     ) { checkResponseCryptoTokens = value; }
  246.  
  247.     /**Get flag to check all crypto tokens on responses.
  248.       */
  249.     BOOL GetCheckResponseCryptoTokens() { return checkResponseCryptoTokens; }
  250.   //@}
  251.  
  252.   protected:
  253.     void Construct();
  254.  
  255.     unsigned GetNextSequenceNumber();
  256.     BOOL SetUpCallSignalAddresses(
  257.       H225_ArrayOf_TransportAddress & addresses
  258.     );
  259.  
  260.     //Background thread handler.
  261.     PDECLARE_NOTIFIER(PThread, H323Transactor, HandleTransactions);
  262.     
  263.     class Request : public PObject
  264.     {
  265.         PCLASSINFO(Request, PObject);
  266.       public:
  267.         Request(
  268.           unsigned seqNum,
  269.           H323TransactionPDU & pdu
  270.         );
  271.         Request(
  272.           unsigned seqNum,
  273.           H323TransactionPDU & pdu,
  274.           const H323TransportAddressArray & addresses
  275.         );
  276.  
  277.         BOOL Poll(H323Transactor &);
  278.         void CheckResponse(unsigned, const PASN_Choice *);
  279.         void OnReceiveRIP(unsigned milliseconds);
  280.  
  281.         // Inter-thread transfer variables
  282.         unsigned rejectReason;
  283.         void   * responseInfo;
  284.  
  285.         H323TransportAddressArray requestAddresses;
  286.  
  287.         unsigned             sequenceNumber;
  288.         H323TransactionPDU & requestPDU;
  289.         PTimeInterval        whenResponseExpected;
  290.         PSyncPoint           responseHandled;
  291.         PMutex               responseMutex;
  292.  
  293.         enum {
  294.           AwaitingResponse,
  295.           ConfirmReceived,
  296.           RejectReceived,
  297.           TryAlternate,
  298.           BadCryptoTokens,
  299.           RequestInProgress,
  300.           NoResponseReceived
  301.         } responseResult;
  302.     };
  303.  
  304.     virtual BOOL MakeRequest(
  305.       Request & request
  306.     );
  307.     BOOL CheckForResponse(
  308.       unsigned,
  309.       unsigned,
  310.       const PASN_Choice * = NULL
  311.     );
  312.     BOOL HandleRequestInProgress(
  313.       const H323TransactionPDU & pdu,
  314.       unsigned delay
  315.     );
  316.     BOOL CheckCryptoTokens(
  317.       const H323TransactionPDU & pdu,
  318.       const PASN_Array & clearTokens,
  319.       unsigned clearOptionalField,
  320.       const PASN_Array & cryptoTokens,
  321.       unsigned cryptoOptionalField
  322.     );
  323.  
  324.     void AgeResponses();
  325.     BOOL SendCachedResponse(
  326.       const H323TransactionPDU & pdu
  327.     );
  328.  
  329.     class Response : public PString
  330.     {
  331.         PCLASSINFO(Response, PString);
  332.       public:
  333.         Response(const H323TransportAddress & addr, unsigned seqNum);
  334.         ~Response();
  335.  
  336.         void SetPDU(const H323TransactionPDU & pdu);
  337.         BOOL SendCachedResponse(H323Transport & transport);
  338.  
  339.         PTime                lastUsedTime;
  340.         PTimeInterval        retirementAge;
  341.         H323TransactionPDU * replyPDU;
  342.     };
  343.  
  344.     // Configuration variables
  345.     H323EndPoint  & endpoint;
  346.     WORD            defaultLocalPort;
  347.     WORD            defaultRemotePort;
  348.     H323Transport * transport;
  349.     BOOL            checkResponseCryptoTokens;
  350.  
  351.     unsigned  nextSequenceNumber;
  352.     PMutex    nextSequenceNumberMutex;
  353.  
  354.     PDictionary<POrdinalKey, Request> requests;
  355.     PMutex                            requestsMutex;
  356.     Request                         * lastRequest;
  357.  
  358.     PMutex                pduWriteMutex;
  359.     PSortedList<Response> responses;
  360. };
  361.  
  362.  
  363. ////////////////////////////////////////////////////////////////////////////////////
  364.  
  365. class H323Transaction : public PObject
  366. {
  367.     PCLASSINFO(H323Transaction, PObject);
  368.   public:
  369.   /**@name Construction */
  370.   //@{
  371.     /**Create a new transaction handler.
  372.      */
  373.     H323Transaction(
  374.       H323Transactor & transactor,
  375.       const H323TransactionPDU & requestToCopy,
  376.       H323TransactionPDU * confirm,
  377.       H323TransactionPDU * reject
  378.     );
  379.     ~H323Transaction();
  380.   //@}
  381.  
  382.     enum Response {
  383.       Ignore = -2,
  384.       Reject = -1,
  385.       Confirm = 0
  386.     };
  387.     inline static Response InProgress(unsigned time) { return (Response)(time&0xffff); }
  388.  
  389.     virtual H323TransactionPDU * CreateRIP(
  390.       unsigned sequenceNumber,
  391.       unsigned delay
  392.     ) const = 0;
  393.  
  394.     BOOL HandlePDU();
  395.  
  396.     virtual BOOL WritePDU(
  397.       H323TransactionPDU & pdu
  398.     );
  399.  
  400.     BOOL CheckCryptoTokens(
  401.       const H235Authenticators & authenticators
  402.     );
  403.  
  404. #if PTRACING
  405.     virtual const char * GetName() const = 0;
  406. #endif
  407.     virtual H235Authenticator::ValidationResult ValidatePDU() const = 0;
  408.     virtual void SetRejectReason(
  409.       unsigned reasonCode
  410.     ) = 0;
  411.  
  412.     BOOL IsFastResponseRequired() const { return fastResponseRequired; }
  413.     H323TransportAddress GetReplyAddress() const { return replyAddresses[0]; }
  414.     const H323TransportAddressArray & GetReplyAddresses() const { return replyAddresses; }
  415.     BOOL IsBehindNAT() const { return isBehindNAT; }
  416.     H323Transactor & GetTransactor() const { return transactor; }
  417.     H235Authenticator::ValidationResult GetAuthenticatorResult() const { return authenticatorResult; }
  418.  
  419.   protected:
  420.     virtual Response OnHandlePDU() = 0;
  421.     PDECLARE_NOTIFIER(PThread, H323Transaction, SlowHandler);
  422.  
  423.     H323Transactor         & transactor;
  424.     unsigned                 requestSequenceNumber;
  425.     H323TransportAddressArray replyAddresses;
  426.     BOOL                     fastResponseRequired;
  427.     H323TransactionPDU     * request;
  428.     H323TransactionPDU     * confirm;
  429.     H323TransactionPDU     * reject;
  430.  
  431.     H235Authenticators                  authenticators;
  432.     H235Authenticator::ValidationResult authenticatorResult;
  433.     BOOL                                isBehindNAT;
  434. };
  435.  
  436.  
  437. ///////////////////////////////////////////////////////////
  438.  
  439. class H323TransactionServer : public PObject
  440. {
  441.   PCLASSINFO(H323TransactionServer, PObject);
  442.   public:
  443.   /**@name Construction */
  444.   //@{
  445.     /**Create a new gatekeeper.
  446.      */
  447.     H323TransactionServer(
  448.       H323EndPoint & endpoint
  449.     );
  450.  
  451.     /**Destroy gatekeeper.
  452.      */
  453.     ~H323TransactionServer();
  454.   //@}
  455.  
  456.     virtual WORD GetDefaultUdpPort() = 0;
  457.  
  458.   /**@name Access functions */
  459.   //@{
  460.     /**Get the owner endpoint.
  461.      */
  462.     H323EndPoint & GetOwnerEndPoint() const { return ownerEndPoint; }
  463.  
  464.   /**@name Protocol Handler Operations */
  465.   //@{
  466.     /**Add listeners to the transaction server.
  467.        If a listener already exists on the interface specified in the list
  468.        then it is ignored. If a listener does not yet exist a new one is
  469.        created and if a listener is running that is not in the list then it
  470.        is stopped and removed.
  471.  
  472.        If the array is empty then the string "*" is assumed which will listen
  473.        on the standard UDP port on INADDR_ANY.
  474.  
  475.        Returns TRUE if at least one interface was successfully started.
  476.       */
  477.     BOOL AddListeners(
  478.       const H323TransportAddressArray & ifaces /// Interfaces to listen on.
  479.     );
  480.  
  481.     /**Add a gatekeeper listener to this gatekeeper server given the
  482.        transport address for the local interface.
  483.       */
  484.     BOOL AddListener(
  485.       const H323TransportAddress & interfaceName
  486.     );
  487.  
  488.     /**Add a gatekeeper listener to this gatekeeper server given the transport.
  489.        Note that the transport is then owned by the listener and will be
  490.        deleted automatically when the listener is destroyed. Note also the
  491.        transport is deleted if this function returns FALSE and no listener was
  492.        created.
  493.       */
  494.     BOOL AddListener(
  495.       H323Transport * transport
  496.     );
  497.  
  498.     /**Add a gatekeeper listener to this gatekeeper server.
  499.        Note that the gatekeeper listener is then owned by the gatekeeper
  500.        server and will be deleted automatically when the listener is removed.
  501.        Note also the listener is deleted if this function returns FALSE and
  502.        the listener was not used.
  503.       */
  504.     BOOL AddListener(
  505.       H323Transactor * listener
  506.     );
  507.  
  508.     /**Create a new H323GatkeeperListener.
  509.        The user woiuld not usually use this function as it is used internally
  510.        by the server when new listeners are added by H323TransportAddress.
  511.  
  512.        However, a user may override this function to create objects that are
  513.        user defined descendants of H323GatekeeperListener so the user can
  514.        maintain extra information on a interface by interface basis.
  515.       */
  516.     virtual H323Transactor * CreateListener(
  517.       H323Transport * transport  // Transport for listener
  518.     ) = 0;
  519.  
  520.     /**Remove a gatekeeper listener from this gatekeeper server.
  521.        The gatekeeper listener is automatically deleted.
  522.       */
  523.     BOOL RemoveListener(
  524.       H323Transactor * listener
  525.     );
  526.  
  527.     BOOL SetUpCallSignalAddresses(H225_ArrayOf_TransportAddress & addresses);
  528.   //@}
  529.  
  530.   protected:
  531.     H323EndPoint & ownerEndPoint;
  532.  
  533.     PThread      * monitorThread;
  534.     PSyncPoint     monitorExit;
  535.  
  536.     PMutex         mutex;
  537.     PLIST(ListenerList, H323Transactor);
  538.     ListenerList listeners;
  539. };
  540.  
  541.  
  542. #endif // __OPAL_H323TRANS_H
  543.  
  544.  
  545. /////////////////////////////////////////////////////////////////////////////
  546.