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: 21283 $
00032  * $Author: rjongbloed $
00033  * $Date: 2008-10-11 07:10:58 +0000 (Sat, 11 Oct 2008) $
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 PString
00059 {
00060   PCLASSINFO(OpalTransportAddress, PString);
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 
00086     PBoolean IsEquivalent(
00087       const OpalTransportAddress & address
00088     ) const;
00089 
00092     PBoolean IsCompatible(
00093       const OpalTransportAddress & address
00094     ) const;
00095 
00099     PBoolean GetIpAddress(PIPSocket::Address & ip) const;
00100 
00104     PBoolean GetIpAndPort(PIPSocket::Address & ip, WORD & port) const;
00105 
00109     virtual PString GetHostName() const;
00110 
00111     enum BindOptions {
00112       NoBinding,
00113       HostOnly,
00114       FullTSAP,
00115       Streamed,
00116       Datagram,
00117       RouteInterface,
00118       NumBindOptions
00119     };
00120 
00152     OpalListener * CreateListener(
00153       OpalEndPoint & endpoint,   
00154       BindOptions option         
00155     ) const;
00156 
00184     virtual OpalTransport * CreateTransport(
00185       OpalEndPoint & endpoint,   
00186       BindOptions option = HostOnly 
00187     ) const;
00189 
00190 
00191   protected:
00192     void SetInternalTransport(
00193       WORD port,             
00194       const char * proto     
00195     );
00196 
00197     OpalInternalTransport * transport;
00198 };
00199 
00200 
00201 PDECLARE_ARRAY(OpalTransportAddressArray, OpalTransportAddress)
00202   public:
00203     OpalTransportAddressArray(
00204       const OpalTransportAddress & address
00205     ) { AppendAddress(address); }
00206     OpalTransportAddressArray(
00207       const PStringArray & array
00208     ) { AppendStringCollection(array); }
00209     OpalTransportAddressArray(
00210       const PStringList & list
00211     ) { AppendStringCollection(list); }
00212     OpalTransportAddressArray(
00213       const PSortedStringList & list
00214     ) { AppendStringCollection(list); }
00215 
00216     void AppendString(
00217       const char * address
00218     );
00219     void AppendString(
00220       const PString & address
00221     );
00222     void AppendAddress(
00223       const OpalTransportAddress & address
00224     );
00225 
00226   protected:
00227     void AppendStringCollection(
00228       const PCollection & coll
00229     );
00230 };
00231 
00232 
00233 
00234 
00236 
00249 class OpalListener : public PObject
00250 {
00251     PCLASSINFO(OpalListener, PObject);
00252   public:
00257     OpalListener(
00258       OpalEndPoint & endpoint   
00259     );
00261 
00266     void PrintOn(
00267       ostream & strm
00268     ) const;
00270 
00273     enum ThreadMode {
00274       SpawnNewThreadMode,
00275       HandOffThreadMode,
00276       SingleThreadMode
00277     };
00278 
00293     virtual PBoolean Open(
00294       const PNotifier & acceptHandler,  
00295       ThreadMode mode = SpawnNewThreadMode 
00296     ) = 0;
00297 
00300     virtual PBoolean IsOpen() = 0;
00301 
00304     virtual void Close() = 0;
00305 
00308     virtual OpalTransport * Accept(
00309       const PTimeInterval & timeout  
00310     ) = 0;
00311 
00314     virtual OpalTransport * CreateTransport(
00315       const OpalTransportAddress & localAddress,
00316       const OpalTransportAddress & remoteAddress
00317     ) const = 0;
00318 
00321     virtual OpalTransportAddress GetLocalAddress(
00322       const OpalTransportAddress & preferredAddress = OpalTransportAddress()
00323     ) const = 0;
00324 
00328     OpalTransportAddress GetTransportAddress() const { return GetLocalAddress(); }
00329 
00332     void CloseWait();
00333 
00337     void CleanUpOnTermination() { CloseWait(); }
00339 
00340 
00341   protected:
00350     PDECLARE_NOTIFIER(PThread, OpalListener, ListenForConnections);
00351     PBoolean StartThread(
00352       const PNotifier & acceptHandler,  
00353       ThreadMode mode                   
00354     );
00355 
00356     OpalEndPoint & endpoint;
00357     PThread      * thread;
00358     PNotifier      acceptHandler;
00359     ThreadMode     threadMode;
00360 };
00361 
00362 
00363 PLIST(OpalListenerList, OpalListener);
00364 
00365 
00366 class OpalListenerIP : public OpalListener
00367 {
00368   PCLASSINFO(OpalListenerIP, OpalListener);
00369   public:
00374     OpalListenerIP(
00375       OpalEndPoint & endpoint,                 
00376       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00377       WORD port = 0,                           
00378       PBoolean exclusive = PTrue
00379     );
00380     OpalListenerIP(
00381       OpalEndPoint & endpoint,                  
00382       const OpalTransportAddress & binding,     
00383       OpalTransportAddress::BindOptions option  
00384     );
00386 
00391     virtual OpalTransportAddress GetLocalAddress(
00392       const OpalTransportAddress & preferredAddress = OpalTransportAddress()
00393     ) const;
00395 
00398     WORD GetListenerPort() const { return listenerPort; }
00399 
00400     virtual const char * GetProtoPrefix() const = 0;
00402 
00403 
00404   protected:
00405     PIPSocket::Address localAddress;
00406     WORD               listenerPort;
00407     PBoolean               exclusiveListener;
00408 };
00409 
00410 
00411 class OpalListenerTCP : public OpalListenerIP
00412 {
00413   PCLASSINFO(OpalListenerTCP, OpalListenerIP);
00414   public:
00419     OpalListenerTCP(
00420       OpalEndPoint & endpoint,                 
00421       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00422       WORD port = 0,                           
00423       PBoolean exclusive = PTrue
00424     );
00425     OpalListenerTCP(
00426       OpalEndPoint & endpoint,                  
00427       const OpalTransportAddress & binding,     
00428       OpalTransportAddress::BindOptions option  
00429     );
00430 
00433     ~OpalListenerTCP();
00435 
00458     virtual PBoolean Open(
00459       const PNotifier & acceptHandler,  
00460       ThreadMode mode = SpawnNewThreadMode 
00461     );
00462 
00465     virtual PBoolean IsOpen();
00466 
00469     virtual void Close();
00470 
00473     virtual OpalTransport * Accept(
00474       const PTimeInterval & timeout  
00475     );
00476 
00479     virtual OpalTransport * CreateTransport(
00480       const OpalTransportAddress & localAddress,
00481       const OpalTransportAddress & remoteAddress
00482     ) const;
00484 
00485 
00486   protected:
00487     virtual const char * GetProtoPrefix() const;
00488 
00489     PTCPSocket listener;
00490 };
00491 
00492 
00493 class OpalListenerUDP : public OpalListenerIP
00494 {
00495   PCLASSINFO(OpalListenerUDP, OpalListenerIP);
00496   public:
00501     OpalListenerUDP(
00502       OpalEndPoint & endpoint,  
00503       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00504       WORD port = 0,            
00505       PBoolean exclusive = PTrue
00506     );
00507     OpalListenerUDP(
00508       OpalEndPoint & endpoint,                  
00509       const OpalTransportAddress & binding,     
00510       OpalTransportAddress::BindOptions option  
00511     );
00512 
00515     ~OpalListenerUDP();
00517 
00540     virtual PBoolean Open(
00541       const PNotifier & acceptHandler,  
00542       ThreadMode mode = SpawnNewThreadMode 
00543     );
00544 
00547     virtual PBoolean IsOpen();
00548 
00551     virtual void Close();
00552 
00555     virtual OpalTransport * Accept(
00556       const PTimeInterval & timeout  
00557     );
00558 
00561     virtual OpalTransport * CreateTransport(
00562       const OpalTransportAddress & localAddress,
00563       const OpalTransportAddress & remoteAddress
00564     ) const;
00566 
00567 
00568   protected:
00569     virtual const char * GetProtoPrefix() const;
00570 
00571     PMonitoredSocketsPtr listenerBundle;
00572 };
00573 
00574 
00576 
00581 class OpalTransport : public PIndirectChannel
00582 {
00583     PCLASSINFO(OpalTransport, PIndirectChannel);
00584   public:
00589     OpalTransport(OpalEndPoint & endpoint);
00590 
00593     ~OpalTransport();
00595 
00600     void PrintOn(
00601       ostream & strm
00602     ) const;
00604 
00609     virtual PBoolean IsReliable() const = 0;
00610 
00617     virtual PString GetInterface() const;
00618 
00625     virtual bool SetInterface(
00626       const PString & iface  
00627     );
00628 
00631     virtual OpalTransportAddress GetLocalAddress() const = 0;
00632 
00637     virtual PBoolean SetLocalAddress(
00638       const OpalTransportAddress & address
00639     ) = 0;
00640 
00643     virtual OpalTransportAddress GetRemoteAddress() const = 0;
00644 
00650     virtual PBoolean SetRemoteAddress(
00651       const OpalTransportAddress & address
00652     ) = 0;
00653 
00656     virtual PBoolean Connect() = 0;
00657 
00660     PBoolean ConnectTo(
00661       const OpalTransportAddress & address
00662     ) { return SetRemoteAddress(address) && Connect(); }
00663 
00666     virtual PBoolean Close();
00667 
00670     void CloseWait();
00671 
00675     void CleanUpOnTermination() { CloseWait(); }
00676 
00679     virtual PBoolean IsCompatibleTransport(
00680       const OpalTransportAddress & address
00681     ) const = 0;
00682 
00684     enum PromisciousModes {
00685       AcceptFromRemoteOnly,
00686       AcceptFromAnyAutoSet,
00687       AcceptFromAny,
00688       NumPromisciousModes
00689     };
00690 
00701     virtual void SetPromiscuous(
00702       PromisciousModes promiscuous
00703     );
00704 
00709     virtual OpalTransportAddress GetLastReceivedAddress() const;
00710 
00715     virtual PString GetLastReceivedInterface() const;
00716 
00722     virtual PBoolean ReadPDU(
00723       PBYTEArray & packet   
00724     ) = 0;
00725 
00731     virtual PBoolean WritePDU(
00732       const PBYTEArray & pdu     
00733     ) = 0;
00734 
00735     typedef PBoolean (*WriteConnectCallback)(OpalTransport & transport, void * userData);
00736 
00749     virtual PBoolean WriteConnect(
00750       WriteConnectCallback function,  
00751       void * userData                 
00752     );
00753 
00756     virtual void AttachThread(
00757       PThread * thread
00758     );
00759 
00762     virtual PBoolean IsRunning() const;
00764 
00765     OpalEndPoint & GetEndPoint() const { return endpoint; }
00766 
00769     virtual const char * GetProtoPrefix() const = 0;
00770 
00771     PMutex & GetWriteMutex() { return m_writeMutex; }
00772 
00773   protected:
00774     OpalEndPoint & endpoint;
00775     PThread      * thread;      
00776     PMutex         m_writeMutex;
00777 };
00778 
00779 
00780 class OpalTransportIP : public OpalTransport
00781 {
00782   PCLASSINFO(OpalTransportIP, OpalTransport);
00783   public:
00788     OpalTransportIP(
00789       OpalEndPoint & endpoint,    
00790       PIPSocket::Address binding, 
00791       WORD port                   
00792     );
00794 
00799     virtual OpalTransportAddress GetLocalAddress() const;
00800 
00805     virtual PBoolean SetLocalAddress(
00806       const OpalTransportAddress & address
00807     );
00808 
00811     virtual OpalTransportAddress GetRemoteAddress() const;
00812 
00818     virtual PBoolean SetRemoteAddress(
00819       const OpalTransportAddress & address
00820     );
00821 
00823 
00824   protected:
00827     virtual const char * GetProtoPrefix() const = 0;
00828 
00829     PIPSocket::Address localAddress;  // Address of the local interface
00830     WORD               localPort;
00831     PIPSocket::Address remoteAddress; // Address of the remote host
00832     WORD               remotePort;
00833 };
00834 
00835 
00836 class OpalTransportTCP : public OpalTransportIP
00837 {
00838     PCLASSINFO(OpalTransportTCP, OpalTransportIP);
00839   public:
00844     OpalTransportTCP(
00845       OpalEndPoint & endpoint,    
00846       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00847       WORD port = 0,              
00848       PBoolean reuseAddr = PFalse      
00849     );
00850     OpalTransportTCP(
00851       OpalEndPoint & endpoint,    
00852       PTCPSocket * socket         
00853     );
00854 
00856     ~OpalTransportTCP();
00858 
00863     virtual PBoolean IsReliable() const;
00864 
00867     virtual PBoolean IsCompatibleTransport(
00868       const OpalTransportAddress & address
00869     ) const;
00870 
00873     virtual PBoolean Connect();
00874 
00880     virtual PBoolean ReadPDU(
00881       PBYTEArray & pdu  
00882     );
00883 
00889     virtual PBoolean WritePDU(
00890       const PBYTEArray & pdu     
00891     );
00893 
00894 
00895   protected:
00898     virtual const char * GetProtoPrefix() const;
00899 
00909     virtual PBoolean OnOpen();
00910 
00911 
00912     PBoolean reuseAddressFlag;
00913 };
00914 
00915 
00916 class OpalTransportUDP : public OpalTransportIP
00917 {
00918   PCLASSINFO(OpalTransportUDP, OpalTransportIP);
00919   public:
00924     OpalTransportUDP(
00925       OpalEndPoint & endpoint,    
00926       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00927       WORD port = 0,              
00928       bool reuseAddr = false,     
00929       bool preOpen = false        
00930     );
00931 
00934     OpalTransportUDP(
00935       OpalEndPoint & endpoint,              
00936       const PBYTEArray & preReadPacket,     
00937       const PMonitoredSocketsPtr & sockets, 
00938       const PString & iface,                
00939       PIPSocket::Address remoteAddress,     
00940       WORD remotePort                       
00941     );
00942 
00944     ~OpalTransportUDP();
00946 
00949     virtual PBoolean Read(
00950       void * buffer,
00951       PINDEX length
00952     );
00954 
00959     virtual PBoolean IsReliable() const;
00960 
00963     virtual PBoolean IsCompatibleTransport(
00964       const OpalTransportAddress & address
00965     ) const;
00966 
00974     virtual PBoolean Connect();
00975 
00978     virtual PString GetInterface() const;
00979 
00986     virtual bool SetInterface(
00987       const PString & iface  
00988     );
00989 
00992     virtual OpalTransportAddress GetLocalAddress() const;
00993 
00998     virtual PBoolean SetLocalAddress(
00999       const OpalTransportAddress & address
01000     );
01001 
01007     virtual PBoolean SetRemoteAddress(
01008       const OpalTransportAddress & address
01009     );
01010 
01022     virtual void SetPromiscuous(
01023       PromisciousModes promiscuous
01024     );
01025 
01030     virtual OpalTransportAddress GetLastReceivedAddress() const;
01031 
01036     virtual PString GetLastReceivedInterface() const;
01037 
01043     virtual PBoolean ReadPDU(
01044       PBYTEArray & packet   
01045     );
01046 
01052     virtual PBoolean WritePDU(
01053       const PBYTEArray & pdu     
01054     );
01055 
01066     virtual PBoolean WriteConnect(
01067       WriteConnectCallback function,  
01068       void * userData                 
01069     );
01071 
01072   protected:
01075     virtual const char * GetProtoPrefix() const;
01076 
01077     OpalManager & manager;
01078     PBYTEArray    preReadPacket;
01079 };
01080 
01081 
01083 
01084 class OpalInternalTransport : public PObject
01085 {
01086     PCLASSINFO(OpalInternalTransport, PObject);
01087   public:
01088     virtual PString GetHostName(
01089       const OpalTransportAddress & address
01090     ) const;
01091 
01092     virtual PBoolean GetIpAndPort(
01093       const OpalTransportAddress & address,
01094       PIPSocket::Address & ip,
01095       WORD & port
01096     ) const;
01097 
01098     virtual OpalListener * CreateListener(
01099       const OpalTransportAddress & address,
01100       OpalEndPoint & endpoint,
01101       OpalTransportAddress::BindOptions options
01102     ) const  = 0;
01103 
01104     virtual OpalTransport * CreateTransport(
01105       const OpalTransportAddress & address,
01106       OpalEndPoint & endpoint,
01107       OpalTransportAddress::BindOptions options
01108     ) const = 0;
01109 };
01110 
01111 
01113 
01114 class OpalInternalIPTransport : public OpalInternalTransport
01115 {
01116     PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport);
01117   public:
01118     virtual PString GetHostName(
01119       const OpalTransportAddress & address
01120     ) const;
01121     virtual PBoolean GetIpAndPort(
01122       const OpalTransportAddress & address,
01123       PIPSocket::Address & ip,
01124       WORD & port
01125     ) const;
01126 
01127     static PBoolean GetAdjustedIpAndPort(const OpalTransportAddress & address,
01128                                      OpalEndPoint & endpoint,
01129                                      OpalTransportAddress::BindOptions option,
01130                                      PIPSocket::Address & ip,
01131                                      WORD & port,
01132                                      PBoolean & reuseAddr);
01133 };
01134 
01135 template <class ListenerType, class TransportType, unsigned AltTypeOption, class AltTypeClass>
01136 class OpalInternalIPTransportTemplate : public OpalInternalIPTransport
01137 {
01138   public:
01139     OpalListener * CreateListener(
01140       const OpalTransportAddress & address,
01141       OpalEndPoint & endpoint,
01142       OpalTransportAddress::BindOptions options
01143     ) const
01144     {
01145       return new ListenerType(endpoint, address, options);
01146     }
01147 
01148     OpalTransport * CreateTransport(
01149       const OpalTransportAddress & address,
01150       OpalEndPoint & endpoint,
01151       OpalTransportAddress::BindOptions options
01152     ) const
01153     {
01154       PIPSocket::Address ip;
01155       WORD port;
01156       PBoolean reuseAddr;
01157       if (GetAdjustedIpAndPort(address, endpoint, options, ip, port, reuseAddr)) {
01158         if (options == AltTypeOption)
01159           return new AltTypeClass(endpoint, ip, 0, reuseAddr);
01160         else
01161           return new TransportType(endpoint, ip, 0, reuseAddr);
01162       }
01163       return NULL;
01164     }
01165 };
01166 
01167 typedef OpalInternalIPTransportTemplate<OpalListenerTCP, OpalTransportTCP, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPTransport;
01168 typedef OpalInternalIPTransportTemplate<OpalListenerUDP, OpalTransportUDP, OpalTransportAddress::Streamed, OpalTransportTCP> OpalInternalUDPTransport;
01169 
01170 #if OPAL_PTLIB_SSL
01171 
01172 class PSSLContext;
01173 
01174 class OpalListenerTCPS : public OpalListenerTCP
01175 {
01176   PCLASSINFO(OpalListenerTCPS, OpalListenerTCP);
01177   public:
01178     OpalListenerTCPS(
01179       OpalEndPoint & endpoint,                 
01180       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
01181       WORD port = 0,                           
01182       PBoolean exclusive = PTrue
01183     );
01184     OpalListenerTCPS(
01185       OpalEndPoint & endpoint,                  
01186       const OpalTransportAddress & binding,     
01187       OpalTransportAddress::BindOptions option  
01188     );
01189 
01192     ~OpalListenerTCPS();
01193 
01194     OpalTransport * Accept(const PTimeInterval & timeout);
01195     const char * GetProtoPrefix() const;
01196 
01197   protected:
01198     void Construct();
01199 
01200     PSSLContext * sslContext;
01201 };
01202 
01203 class OpalTransportTCPS : public OpalTransportTCP
01204 {
01205   PCLASSINFO(OpalTransportTCPS, OpalTransportTCP);
01206     public:
01207       OpalTransportTCPS(
01208         OpalEndPoint & endpoint,    
01209         PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
01210         WORD port = 0,              
01211         PBoolean reuseAddr = PFalse      
01212       );
01213       OpalTransportTCPS(
01214         OpalEndPoint & endpoint,    
01215         PTCPSocket * socket         
01216       );
01217 
01219       ~OpalTransportTCPS();
01220 
01221       PBoolean IsCompatibleTransport(const OpalTransportAddress & address) const;
01222       PBoolean Connect();
01223       PBoolean OnOpen();
01224       const char * GetProtoPrefix() const;
01225 
01226     protected:
01227       PSSLContext * sslContext;
01228 };
01229 
01230 typedef OpalInternalIPTransportTemplate<OpalListenerTCPS, OpalTransportTCPS, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPSTransport;
01231 
01232 
01233 #endif // OPAL_PTLIB_SSL
01234 
01235 
01236 #endif  // OPAL_OPAL_TRANSPORT_H
01237 
01238 
01239 // End of File ///////////////////////////////////////////////////////////////

Generated on Mon Feb 23 02:01:40 2009 for OPAL by  doxygen 1.5.1