transports.h

Go to the documentation of this file.
00001 /*
00002  * transport.h
00003  *
00004  * Transport declarations
00005  *
00006  * Open Phone Abstraction Library (OPAL)
00007  * Formally known as the Open H323 project.
00008  *
00009  * Copyright (c) 2001 Equivalence Pty. Ltd.
00010  * Portions Copyright (C) 2006 by Post Increment
00011  *
00012  * The contents of this file are subject to the Mozilla Public License
00013  * Version 1.0 (the "License"); you may not use this file except in
00014  * compliance with the License. You may obtain a copy of the License at
00015  * http://www.mozilla.org/MPL/
00016  *
00017  * Software distributed under the License is distributed on an "AS IS"
00018  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00019  * the License for the specific language governing rights and limitations
00020  * under the License.
00021  *
00022  * The Original Code is Open Phone Abstraction Library.
00023  *
00024  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00025  *
00026  * Contributor(s): Post Increment
00027  *     Portions of this code were written with the assistance of funding from
00028  *     US Joint Forces Command Joint Concept Development & Experimentation (J9)
00029  *     http://www.jfcom.mil/about/abt_j9.htm
00030  *
00031  * $Revision: 24351 $
00032  * $Author: rjongbloed $
00033  * $Date: 2010-05-18 00:24:54 -0500 (Tue, 18 May 2010) $
00034  */
00035 
00036 #ifndef OPAL_OPAL_TRANSPORT_H
00037 #define OPAL_OPAL_TRANSPORT_H
00038 
00039 #ifdef P_USE_PRAGMA
00040 #pragma interface
00041 #endif
00042 
00043 #include <opal/buildopts.h>
00044 
00045 #include <ptlib/sockets.h>
00046 #include <ptclib/psockbun.h>
00047 
00048 
00049 class OpalManager;
00050 class OpalEndPoint;
00051 class OpalListener;
00052 class OpalTransport;
00053 class OpalInternalTransport;
00054 
00055 
00057 
00058 class OpalTransportAddress : public PCaselessString
00059 {
00060   PCLASSINFO(OpalTransportAddress, PCaselessString);
00061   public:
00064     OpalTransportAddress();
00065     OpalTransportAddress(
00066       const char * address,      
00067       WORD port = 0,             
00068       const char * proto = NULL  
00069     );
00070     OpalTransportAddress(
00071       const PString & address,   
00072       WORD port = 0,             
00073       const char * proto = NULL  
00074     );
00075     OpalTransportAddress(
00076       const PIPSocket::Address & ip,  
00077       WORD port,                      
00078       const char * proto = NULL       
00079     );
00081 
00089     PBoolean IsEquivalent(
00090       const OpalTransportAddress & address,   
00091       bool wildcards = false   
00092     ) const;
00093 
00096     PBoolean IsCompatible(
00097       const OpalTransportAddress & address
00098     ) const;
00099 
00102     PCaselessString GetProto() const { return Left(Find('$')); }
00103 
00107     PBoolean GetIpAddress(PIPSocket::Address & ip) const;
00108 
00112     PBoolean GetIpAndPort(PIPSocket::Address & ip, WORD & port) const;
00113     PBoolean GetIpAndPort(PIPSocketAddressAndPort & ipPort) const;
00114 
00118     virtual PString GetHostName() const;
00119 
00120     enum BindOptions {
00121       NoBinding,
00122       HostOnly,
00123       FullTSAP,
00124       Streamed,
00125       Datagram,
00126       RouteInterface,
00127       NumBindOptions
00128     };
00129 
00161     OpalListener * CreateListener(
00162       OpalEndPoint & endpoint,   
00163       BindOptions option         
00164     ) const;
00165 
00193     virtual OpalTransport * CreateTransport(
00194       OpalEndPoint & endpoint,   
00195       BindOptions option = HostOnly 
00196     ) const;
00198 
00199 
00200   protected:
00201     void SetInternalTransport(
00202       WORD port,             
00203       const char * proto     
00204     );
00205 
00206     OpalInternalTransport * transport;
00207 };
00208 
00209 
00210 PDECLARE_ARRAY(OpalTransportAddressArray, OpalTransportAddress)
00211   public:
00212     OpalTransportAddressArray(
00213       const OpalTransportAddress & address
00214     ) { AppendAddress(address); }
00215     OpalTransportAddressArray(
00216       const PStringArray & array
00217     ) { AppendStringCollection(array); }
00218     OpalTransportAddressArray(
00219       const PStringList & list
00220     ) { AppendStringCollection(list); }
00221     OpalTransportAddressArray(
00222       const PSortedStringList & list
00223     ) { AppendStringCollection(list); }
00224 
00225     void AppendString(
00226       const char * address
00227     );
00228     void AppendString(
00229       const PString & address
00230     );
00231     void AppendAddress(
00232       const OpalTransportAddress & address
00233     );
00234 
00235   protected:
00236     void AppendStringCollection(
00237       const PCollection & coll
00238     );
00239 };
00240 
00241 
00242 
00243 
00245 
00258 class OpalListener : public PObject
00259 {
00260     PCLASSINFO(OpalListener, PObject);
00261   public:
00266     OpalListener(
00267       OpalEndPoint & endpoint   
00268     );
00270 
00275     void PrintOn(
00276       ostream & strm
00277     ) const;
00279 
00282     enum ThreadMode {
00283       SpawnNewThreadMode,
00284       HandOffThreadMode,
00285       SingleThreadMode
00286     };
00287 
00302     virtual PBoolean Open(
00303       const PNotifier & acceptHandler,  
00304       ThreadMode mode = SpawnNewThreadMode 
00305     ) = 0;
00306 
00309     virtual PBoolean IsOpen() = 0;
00310 
00313     virtual void Close() = 0;
00314 
00317     virtual OpalTransport * Accept(
00318       const PTimeInterval & timeout  
00319     ) = 0;
00320 
00323     virtual OpalTransport * CreateTransport(
00324       const OpalTransportAddress & localAddress,
00325       const OpalTransportAddress & remoteAddress
00326     ) const = 0;
00327 
00333     virtual OpalTransportAddress GetLocalAddress(
00334       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
00335     ) const = 0;
00336 
00339     void CloseWait();
00340 
00344     void CleanUpOnTermination() { CloseWait(); }
00346 
00347 
00348   protected:
00357     PDECLARE_NOTIFIER(PThread, OpalListener, ListenForConnections);
00358     PBoolean StartThread(
00359       const PNotifier & acceptHandler,  
00360       ThreadMode mode                   
00361     );
00362 
00363     OpalEndPoint & endpoint;
00364     PThread      * thread;
00365     PNotifier      acceptHandler;
00366     ThreadMode     threadMode;
00367 };
00368 
00369 
00370 PLIST(OpalListenerList, OpalListener);
00371 
00372 
00373 class OpalListenerIP : public OpalListener
00374 {
00375   PCLASSINFO(OpalListenerIP, OpalListener);
00376   public:
00381     OpalListenerIP(
00382       OpalEndPoint & endpoint,                 
00383       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00384       WORD port = 0,                           
00385       PBoolean exclusive = true               
00386     );
00387     OpalListenerIP(
00388       OpalEndPoint & endpoint,                  
00389       const OpalTransportAddress & binding,     
00390       OpalTransportAddress::BindOptions option  
00391     );
00393 
00401     virtual OpalTransportAddress GetLocalAddress(
00402       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
00403     ) const;
00405 
00408     WORD GetListenerPort() const { return listenerPort; }
00409 
00410     virtual const char * GetProtoPrefix() const = 0;
00412 
00413 
00414   protected:
00415     PIPSocket::Address localAddress;
00416     WORD               listenerPort;
00417     PBoolean               exclusiveListener;
00418 };
00419 
00420 
00421 class OpalListenerTCP : public OpalListenerIP
00422 {
00423   PCLASSINFO(OpalListenerTCP, OpalListenerIP);
00424   public:
00429     OpalListenerTCP(
00430       OpalEndPoint & endpoint,                 
00431       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00432       WORD port = 0,                           
00433       PBoolean exclusive = true               
00434     );
00435     OpalListenerTCP(
00436       OpalEndPoint & endpoint,                  
00437       const OpalTransportAddress & binding,     
00438       OpalTransportAddress::BindOptions option  
00439     );
00440 
00443     ~OpalListenerTCP();
00445 
00468     virtual PBoolean Open(
00469       const PNotifier & acceptHandler,  
00470       ThreadMode mode = SpawnNewThreadMode 
00471     );
00472 
00475     virtual PBoolean IsOpen();
00476 
00479     virtual void Close();
00480 
00483     virtual OpalTransport * Accept(
00484       const PTimeInterval & timeout  
00485     );
00486 
00489     virtual OpalTransport * CreateTransport(
00490       const OpalTransportAddress & localAddress,
00491       const OpalTransportAddress & remoteAddress
00492     ) const;
00494 
00495 
00496   protected:
00497     virtual const char * GetProtoPrefix() const;
00498 
00499     PTCPSocket listener;
00500 };
00501 
00502 
00503 class OpalListenerUDP : public OpalListenerIP
00504 {
00505   PCLASSINFO(OpalListenerUDP, OpalListenerIP);
00506   public:
00511     OpalListenerUDP(
00512       OpalEndPoint & endpoint,  
00513       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00514       WORD port = 0,            
00515       PBoolean exclusive = true  
00516     );
00517     OpalListenerUDP(
00518       OpalEndPoint & endpoint,                  
00519       const OpalTransportAddress & binding,     
00520       OpalTransportAddress::BindOptions option  
00521     );
00522 
00525     ~OpalListenerUDP();
00527 
00550     virtual PBoolean Open(
00551       const PNotifier & acceptHandler,  
00552       ThreadMode mode = SpawnNewThreadMode 
00553     );
00554 
00557     virtual PBoolean IsOpen();
00558 
00561     virtual void Close();
00562 
00565     virtual OpalTransport * Accept(
00566       const PTimeInterval & timeout  
00567     );
00568 
00571     virtual OpalTransport * CreateTransport(
00572       const OpalTransportAddress & localAddress,
00573       const OpalTransportAddress & remoteAddress
00574     ) const;
00575 
00581     virtual OpalTransportAddress GetLocalAddress(
00582       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
00583     ) const;
00585 
00590     void SetBufferSize(
00591       PINDEX size
00592     ) { m_bufferSize = size; }
00594 
00595 
00596   protected:
00597     virtual const char * GetProtoPrefix() const;
00598 
00599     PMonitoredSocketsPtr listenerBundle;
00600     PINDEX               m_bufferSize;
00601 };
00602 
00603 
00605 
00610 class OpalTransport : public PIndirectChannel
00611 {
00612     PCLASSINFO(OpalTransport, PIndirectChannel);
00613   public:
00618     OpalTransport(OpalEndPoint & endpoint);
00619 
00622     ~OpalTransport();
00624 
00629     void PrintOn(
00630       ostream & strm
00631     ) const;
00633 
00638     virtual PBoolean IsReliable() const = 0;
00639 
00646     virtual PString GetInterface() const;
00647 
00654     virtual bool SetInterface(
00655       const PString & iface  
00656     );
00657 
00660     virtual OpalTransportAddress GetLocalAddress(
00661       bool allowNAT = true   
00662     ) const = 0;
00663 
00668     virtual PBoolean SetLocalAddress(
00669       const OpalTransportAddress & address
00670     ) = 0;
00671 
00674     virtual OpalTransportAddress GetRemoteAddress() const = 0;
00675 
00681     virtual PBoolean SetRemoteAddress(
00682       const OpalTransportAddress & address
00683     ) = 0;
00684 
00687     virtual PBoolean Connect() = 0;
00688 
00691     PBoolean ConnectTo(
00692       const OpalTransportAddress & address
00693     ) { return SetRemoteAddress(address) && Connect(); }
00694 
00697     virtual PBoolean Close();
00698 
00701     void CloseWait();
00702 
00706     void CleanUpOnTermination() { CloseWait(); }
00707 
00710     virtual PBoolean IsCompatibleTransport(
00711       const OpalTransportAddress & address
00712     ) const = 0;
00713 
00715     enum PromisciousModes {
00716       AcceptFromRemoteOnly,
00717       AcceptFromAnyAutoSet,
00718       AcceptFromAny,
00719       NumPromisciousModes
00720     };
00721 
00732     virtual void SetPromiscuous(
00733       PromisciousModes promiscuous
00734     );
00735 
00740     virtual OpalTransportAddress GetLastReceivedAddress() const;
00741 
00746     virtual PString GetLastReceivedInterface() const;
00747 
00757     virtual PBoolean ReadPDU(
00758       PBYTEArray & packet   
00759     ) = 0;
00760 
00766     virtual PBoolean WritePDU(
00767       const PBYTEArray & pdu     
00768     ) = 0;
00769 
00770     typedef PBoolean (*WriteConnectCallback)(OpalTransport & transport, void * userData);
00771 
00784     virtual PBoolean WriteConnect(
00785       WriteConnectCallback function,  
00786       void * userData                 
00787     );
00788 
00791     virtual void AttachThread(
00792       PThread * thread
00793     );
00794 
00797     virtual PBoolean IsRunning() const;
00799 
00800     OpalEndPoint & GetEndPoint() const { return endpoint; }
00801 
00804     virtual const char * GetProtoPrefix() const = 0;
00805 
00806     PMutex & GetWriteMutex() { return m_writeMutex; }
00807 
00808   protected:
00809     OpalEndPoint & endpoint;
00810     PThread      * thread;      
00811     PMutex         m_writeMutex;
00812 };
00813 
00814 
00815 class OpalTransportIP : public OpalTransport
00816 {
00817   PCLASSINFO(OpalTransportIP, OpalTransport);
00818   public:
00823     OpalTransportIP(
00824       OpalEndPoint & endpoint,    
00825       PIPSocket::Address binding, 
00826       WORD port                   
00827     );
00829 
00834     virtual OpalTransportAddress GetLocalAddress(
00835       bool allowNAT = true   
00836     ) const;
00837 
00842     virtual PBoolean SetLocalAddress(
00843       const OpalTransportAddress & address
00844     );
00845 
00848     virtual OpalTransportAddress GetRemoteAddress() const;
00849 
00855     virtual PBoolean SetRemoteAddress(
00856       const OpalTransportAddress & address
00857     );
00858 
00860 
00861   protected:
00864     virtual const char * GetProtoPrefix() const = 0;
00865 
00866     PIPSocket::Address localAddress;  // Address of the local interface
00867     WORD               localPort;
00868     PIPSocket::Address remoteAddress; // Address of the remote host
00869     WORD               remotePort;
00870 };
00871 
00872 
00873 class OpalTransportTCP : public OpalTransportIP
00874 {
00875     PCLASSINFO(OpalTransportTCP, OpalTransportIP);
00876   public:
00881     OpalTransportTCP(
00882       OpalEndPoint & endpoint,    
00883       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00884       WORD port = 0,              
00885       PBoolean reuseAddr = false      
00886     );
00887     OpalTransportTCP(
00888       OpalEndPoint & endpoint,    
00889       PTCPSocket * socket         
00890     );
00891 
00893     ~OpalTransportTCP();
00895 
00900     virtual PBoolean IsReliable() const;
00901 
00904     virtual PBoolean IsCompatibleTransport(
00905       const OpalTransportAddress & address
00906     ) const;
00907 
00910     virtual PBoolean Connect();
00911 
00921     virtual PBoolean ReadPDU(
00922       PBYTEArray & pdu  
00923     );
00924 
00930     virtual PBoolean WritePDU(
00931       const PBYTEArray & pdu     
00932     );
00934 
00935 
00936   protected:
00939     virtual const char * GetProtoPrefix() const;
00940 
00950     virtual PBoolean OnOpen();
00951 
00952 
00953     PBoolean reuseAddressFlag;
00954 };
00955 
00956 
00957 class OpalTransportUDP : public OpalTransportIP
00958 {
00959   PCLASSINFO(OpalTransportUDP, OpalTransportIP);
00960   public:
00965     OpalTransportUDP(
00966       OpalEndPoint & endpoint,    
00967       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00968       WORD port = 0,              
00969       bool reuseAddr = false,     
00970       bool preOpen = false        
00971     );
00972 
00975     OpalTransportUDP(
00976       OpalEndPoint & endpoint,              
00977       const PMonitoredSocketsPtr & sockets, 
00978       const PString & iface                 
00979     );
00980 
00982     ~OpalTransportUDP();
00984 
00987     virtual PBoolean Read(
00988       void * buffer,
00989       PINDEX length
00990     );
00992 
00997     virtual PBoolean IsReliable() const;
00998 
01001     virtual PBoolean IsCompatibleTransport(
01002       const OpalTransportAddress & address
01003     ) const;
01004 
01012     virtual PBoolean Connect();
01013 
01016     virtual PString GetInterface() const;
01017 
01024     virtual bool SetInterface(
01025       const PString & iface  
01026     );
01027 
01030     virtual OpalTransportAddress GetLocalAddress(
01031       bool allowNAT = true   
01032     ) const;
01033 
01038     virtual PBoolean SetLocalAddress(
01039       const OpalTransportAddress & address
01040     );
01041 
01047     virtual PBoolean SetRemoteAddress(
01048       const OpalTransportAddress & address
01049     );
01050 
01062     virtual void SetPromiscuous(
01063       PromisciousModes promiscuous
01064     );
01065 
01070     virtual OpalTransportAddress GetLastReceivedAddress() const;
01071 
01076     virtual PString GetLastReceivedInterface() const;
01077 
01087     virtual PBoolean ReadPDU(
01088       PBYTEArray & packet   
01089     );
01090 
01096     virtual PBoolean WritePDU(
01097       const PBYTEArray & pdu     
01098     );
01099 
01110     virtual PBoolean WriteConnect(
01111       WriteConnectCallback function,  
01112       void * userData                 
01113     );
01114 
01117     void SetBufferSize(
01118       PINDEX size
01119     ) { m_bufferSize = size; }
01121 
01122   protected:
01125     virtual const char * GetProtoPrefix() const;
01126 
01127     OpalManager & manager;
01128     PINDEX        m_bufferSize;
01129     PBYTEArray    m_preReadPacket;
01130     bool          m_preReadOK;
01131 
01132   friend class OpalListenerUDP;
01133 };
01134 
01135 
01137 
01138 class OpalInternalTransport : public PObject
01139 {
01140     PCLASSINFO(OpalInternalTransport, PObject);
01141   public:
01142     virtual PString GetHostName(
01143       const OpalTransportAddress & address
01144     ) const;
01145 
01146     virtual PBoolean GetIpAndPort(
01147       const OpalTransportAddress & address,
01148       PIPSocket::Address & ip,
01149       WORD & port
01150     ) const;
01151 
01152     virtual OpalListener * CreateListener(
01153       const OpalTransportAddress & address,
01154       OpalEndPoint & endpoint,
01155       OpalTransportAddress::BindOptions options
01156     ) const  = 0;
01157 
01158     virtual OpalTransport * CreateTransport(
01159       const OpalTransportAddress & address,
01160       OpalEndPoint & endpoint,
01161       OpalTransportAddress::BindOptions options
01162     ) const = 0;
01163 };
01164 
01165 
01167 
01168 class OpalInternalIPTransport : public OpalInternalTransport
01169 {
01170     PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport);
01171   public:
01172     virtual PString GetHostName(
01173       const OpalTransportAddress & address
01174     ) const;
01175     virtual PBoolean GetIpAndPort(
01176       const OpalTransportAddress & address,
01177       PIPSocket::Address & ip,
01178       WORD & port
01179     ) const;
01180 
01181     static PBoolean GetAdjustedIpAndPort(const OpalTransportAddress & address,
01182                                      OpalEndPoint & endpoint,
01183                                      OpalTransportAddress::BindOptions option,
01184                                      PIPSocket::Address & ip,
01185                                      WORD & port,
01186                                      PBoolean & reuseAddr);
01187 };
01188 
01189 template <class ListenerType, class TransportType, unsigned AltTypeOption, class AltTypeClass>
01190 class OpalInternalIPTransportTemplate : public OpalInternalIPTransport
01191 {
01192   public:
01193     OpalListener * CreateListener(
01194       const OpalTransportAddress & address,
01195       OpalEndPoint & endpoint,
01196       OpalTransportAddress::BindOptions options
01197     ) const
01198     {
01199       return new ListenerType(endpoint, address, options);
01200     }
01201 
01202     OpalTransport * CreateTransport(
01203       const OpalTransportAddress & address,
01204       OpalEndPoint & endpoint,
01205       OpalTransportAddress::BindOptions options
01206     ) const
01207     {
01208       PIPSocket::Address ip;
01209       WORD port;
01210       PBoolean reuseAddr;
01211       if (GetAdjustedIpAndPort(address, endpoint, options, ip, port, reuseAddr)) {
01212         if (options == AltTypeOption)
01213           return new AltTypeClass(endpoint, ip, 0, reuseAddr);
01214         else
01215           return new TransportType(endpoint, ip, 0, reuseAddr);
01216       }
01217       return NULL;
01218     }
01219 };
01220 
01221 typedef OpalInternalIPTransportTemplate<OpalListenerTCP, OpalTransportTCP, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPTransport;
01222 typedef OpalInternalIPTransportTemplate<OpalListenerUDP, OpalTransportUDP, OpalTransportAddress::Streamed, OpalTransportTCP> OpalInternalUDPTransport;
01223 
01224 #if OPAL_PTLIB_SSL
01225 
01226 class PSSLContext;
01227 
01228 class OpalListenerTCPS : public OpalListenerTCP
01229 {
01230   PCLASSINFO(OpalListenerTCPS, OpalListenerTCP);
01231   public:
01232     OpalListenerTCPS(
01233       OpalEndPoint & endpoint,                 
01234       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
01235       WORD port = 0,                           
01236       PBoolean exclusive = true               
01237     );
01238     OpalListenerTCPS(
01239       OpalEndPoint & endpoint,                  
01240       const OpalTransportAddress & binding,     
01241       OpalTransportAddress::BindOptions option  
01242     );
01243 
01246     ~OpalListenerTCPS();
01247 
01248     OpalTransport * Accept(const PTimeInterval & timeout);
01249     const char * GetProtoPrefix() const;
01250 
01251   protected:
01252     void Construct();
01253 
01254     PSSLContext * sslContext;
01255 };
01256 
01257 class OpalTransportTCPS : public OpalTransportTCP
01258 {
01259   PCLASSINFO(OpalTransportTCPS, OpalTransportTCP);
01260     public:
01261       OpalTransportTCPS(
01262         OpalEndPoint & endpoint,    
01263         PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
01264         WORD port = 0,              
01265         PBoolean reuseAddr = false      
01266       );
01267       OpalTransportTCPS(
01268         OpalEndPoint & endpoint,    
01269         PTCPSocket * socket         
01270       );
01271 
01273       ~OpalTransportTCPS();
01274 
01275       PBoolean IsCompatibleTransport(const OpalTransportAddress & address) const;
01276       PBoolean Connect();
01277       PBoolean OnOpen();
01278       const char * GetProtoPrefix() const;
01279 
01280     protected:
01281       PSSLContext * sslContext;
01282 };
01283 
01284 typedef OpalInternalIPTransportTemplate<OpalListenerTCPS, OpalTransportTCPS, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPSTransport;
01285 
01286 
01287 #endif // OPAL_PTLIB_SSL
01288 
01289 
01290 #endif  // OPAL_OPAL_TRANSPORT_H
01291 
01292 
01293 // End of File ///////////////////////////////////////////////////////////////

Generated on Sun Nov 21 20:20:51 2010 for OPAL by  doxygen 1.4.7