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: 27884 $
00032  * $Author: rjongbloed $
00033  * $Date: 2012-06-24 19:43:04 -0500 (Sun, 24 Jun 2012) $
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 
00149 class OpalTransportAddress : public PCaselessString
00150 {
00151   PCLASSINFO(OpalTransportAddress, PCaselessString);
00152   public:
00155     OpalTransportAddress();
00156     OpalTransportAddress(
00157       const char * address,      
00158       WORD port = 0,             
00159       const char * proto = NULL  
00160     );
00161     OpalTransportAddress(
00162       const PString & address,   
00163       WORD port = 0,             
00164       const char * proto = NULL  
00165     );
00166     OpalTransportAddress(
00167       const PIPSocket::Address & ip,  
00168       WORD port,                      
00169       const char * proto = NULL       
00170     );
00172 
00180     PBoolean IsEquivalent(
00181       const OpalTransportAddress & address,   
00182       bool wildcards = false   
00183     ) const;
00184 
00187     PBoolean IsCompatible(
00188       const OpalTransportAddress & address
00189     ) const;
00190 
00193     PCaselessString GetProto(bool withDollar = false) const { return Left(Find('$')+(withDollar?1:0)); }
00194 
00198     PBoolean GetIpAddress(PIPSocket::Address & ip) const;
00199 
00203     PBoolean GetIpAndPort(PIPSocket::Address & ip, WORD & port) const;
00204     PBoolean GetIpAndPort(PIPSocketAddressAndPort & ipPort) const;
00205 
00209     virtual PString GetHostName(
00210       bool includeService = false
00211     ) const;
00212 
00213     enum BindOptions {
00214       NoBinding,
00215       HostOnly,
00216       FullTSAP,
00217       Streamed,
00218       Datagram,
00219       RouteInterface,
00220       NumBindOptions
00221     };
00222 
00254     OpalListener * CreateListener(
00255       OpalEndPoint & endpoint,   
00256       BindOptions option         
00257     ) const;
00258 
00286     virtual OpalTransport * CreateTransport(
00287       OpalEndPoint & endpoint,   
00288       BindOptions option = HostOnly 
00289     ) const;
00291 
00292 
00293   protected:
00294     void SetInternalTransport(
00295       WORD port,             
00296       const char * proto     
00297     );
00298 
00299     OpalInternalTransport * transport;
00300 };
00301 
00302 
00303 PDECLARE_ARRAY(OpalTransportAddressArray, OpalTransportAddress)
00304   public:
00305     OpalTransportAddressArray(
00306       const OpalTransportAddress & address
00307     ) { AppendAddress(address); }
00308     OpalTransportAddressArray(
00309       const PStringArray & array
00310     ) { AppendStringCollection(array); }
00311     OpalTransportAddressArray(
00312       const PStringList & list
00313     ) { AppendStringCollection(list); }
00314     OpalTransportAddressArray(
00315       const PSortedStringList & list
00316     ) { AppendStringCollection(list); }
00317 
00318     void AppendString(
00319       const char * address
00320     );
00321     void AppendString(
00322       const PString & address
00323     );
00324     void AppendAddress(
00325       const OpalTransportAddress & address
00326     );
00327 
00328   protected:
00329     void AppendStringCollection(
00330       const PCollection & coll
00331     );
00332 };
00333 
00334 
00335 
00336 
00338 
00351 class OpalListener : public PObject
00352 {
00353     PCLASSINFO(OpalListener, PObject);
00354   public:
00359     OpalListener(
00360       OpalEndPoint & endpoint   
00361     );
00363 
00368     void PrintOn(
00369       ostream & strm
00370     ) const;
00372 
00375     enum ThreadMode {
00376       SpawnNewThreadMode,
00377       HandOffThreadMode,
00378       SingleThreadMode
00379     };
00380 
00395     virtual PBoolean Open(
00396       const PNotifier & acceptHandler,  
00397       ThreadMode mode = SpawnNewThreadMode 
00398     ) = 0;
00399 
00402     virtual PBoolean IsOpen() = 0;
00403 
00406     virtual void Close() = 0;
00407 
00410     virtual OpalTransport * Accept(
00411       const PTimeInterval & timeout  
00412     ) = 0;
00413 
00416     virtual OpalTransport * CreateTransport(
00417       const OpalTransportAddress & localAddress,
00418       const OpalTransportAddress & remoteAddress
00419     ) const = 0;
00420 
00426     virtual OpalTransportAddress GetLocalAddress(
00427       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
00428     ) const = 0;
00429 
00432     void CloseWait();
00433 
00437     void CleanUpOnTermination() { CloseWait(); }
00439 
00440 
00441   protected:
00450     PDECLARE_NOTIFIER(PThread, OpalListener, ListenForConnections);
00451     PBoolean StartThread(
00452       const PNotifier & acceptHandler,  
00453       ThreadMode mode                   
00454     );
00455 
00456     OpalEndPoint & endpoint;
00457     PThread      * thread;
00458     PNotifier      acceptHandler;
00459     ThreadMode     threadMode;
00460 };
00461 
00462 
00463 PLIST(OpalListenerList, OpalListener);
00464 
00465 
00466 class OpalListenerIP : public OpalListener
00467 {
00468   PCLASSINFO(OpalListenerIP, OpalListener);
00469   public:
00474     OpalListenerIP(
00475       OpalEndPoint & endpoint,                 
00476       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00477       WORD port = 0,                           
00478       PBoolean exclusive = true               
00479     );
00480     OpalListenerIP(
00481       OpalEndPoint & endpoint,                  
00482       const OpalTransportAddress & binding,     
00483       OpalTransportAddress::BindOptions option  
00484     );
00486 
00494     virtual OpalTransportAddress GetLocalAddress(
00495       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
00496     ) const;
00498 
00501     WORD GetListenerPort() const { return listenerPort; }
00502 
00503     virtual const char * GetProtoPrefix() const = 0;
00505 
00506 
00507   protected:
00508     PIPSocket::Address localAddress;
00509     WORD               listenerPort;
00510     PBoolean               exclusiveListener;
00511 };
00512 
00513 
00514 class OpalListenerTCP : public OpalListenerIP
00515 {
00516   PCLASSINFO(OpalListenerTCP, OpalListenerIP);
00517   public:
00522     OpalListenerTCP(
00523       OpalEndPoint & endpoint,                 
00524       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00525       WORD port = 0,                           
00526       PBoolean exclusive = true               
00527     );
00528     OpalListenerTCP(
00529       OpalEndPoint & endpoint,                  
00530       const OpalTransportAddress & binding,     
00531       OpalTransportAddress::BindOptions option  
00532     );
00533 
00536     ~OpalListenerTCP();
00538 
00561     virtual PBoolean Open(
00562       const PNotifier & acceptHandler,  
00563       ThreadMode mode = SpawnNewThreadMode 
00564     );
00565 
00568     virtual PBoolean IsOpen();
00569 
00572     virtual void Close();
00573 
00576     virtual OpalTransport * Accept(
00577       const PTimeInterval & timeout  
00578     );
00579 
00582     virtual OpalTransport * CreateTransport(
00583       const OpalTransportAddress & localAddress,
00584       const OpalTransportAddress & remoteAddress
00585     ) const;
00587 
00588 
00589   protected:
00590     virtual const char * GetProtoPrefix() const;
00591 
00592     PTCPSocket listener;
00593 };
00594 
00595 
00596 class OpalListenerUDP : public OpalListenerIP
00597 {
00598   PCLASSINFO(OpalListenerUDP, OpalListenerIP);
00599   public:
00604     OpalListenerUDP(
00605       OpalEndPoint & endpoint,  
00606       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00607       WORD port = 0,            
00608       PBoolean exclusive = true  
00609     );
00610     OpalListenerUDP(
00611       OpalEndPoint & endpoint,                  
00612       const OpalTransportAddress & binding,     
00613       OpalTransportAddress::BindOptions option  
00614     );
00615 
00618     ~OpalListenerUDP();
00620 
00643     virtual PBoolean Open(
00644       const PNotifier & acceptHandler,  
00645       ThreadMode mode = SpawnNewThreadMode 
00646     );
00647 
00650     virtual PBoolean IsOpen();
00651 
00654     virtual void Close();
00655 
00658     virtual OpalTransport * Accept(
00659       const PTimeInterval & timeout  
00660     );
00661 
00664     virtual OpalTransport * CreateTransport(
00665       const OpalTransportAddress & localAddress,
00666       const OpalTransportAddress & remoteAddress
00667     ) const;
00668 
00674     virtual OpalTransportAddress GetLocalAddress(
00675       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
00676     ) const;
00678 
00683     void SetBufferSize(
00684       PINDEX size
00685     ) { m_bufferSize = size; }
00687 
00688 
00689   protected:
00690     virtual const char * GetProtoPrefix() const;
00691 
00692     PMonitoredSocketsPtr listenerBundle;
00693     PINDEX               m_bufferSize;
00694 };
00695 
00696 
00698 
00703 class OpalTransport : public PIndirectChannel
00704 {
00705     PCLASSINFO(OpalTransport, PIndirectChannel);
00706   public:
00711     OpalTransport(OpalEndPoint & endpoint);
00712 
00715     ~OpalTransport();
00717 
00722     void PrintOn(
00723       ostream & strm
00724     ) const;
00726 
00731     virtual PBoolean IsReliable() const = 0;
00732 
00739     virtual PString GetInterface() const;
00740 
00747     virtual bool SetInterface(
00748       const PString & iface  
00749     );
00750 
00753     virtual OpalTransportAddress GetLocalAddress(
00754       bool allowNAT = true   
00755     ) const = 0;
00756 
00761     virtual PBoolean SetLocalAddress(
00762       const OpalTransportAddress & address
00763     ) = 0;
00764 
00767     virtual OpalTransportAddress GetRemoteAddress() const = 0;
00768 
00774     virtual PBoolean SetRemoteAddress(
00775       const OpalTransportAddress & address
00776     ) = 0;
00777 
00780     virtual PBoolean Connect() = 0;
00781 
00784     PBoolean ConnectTo(
00785       const OpalTransportAddress & address
00786     ) { return SetRemoteAddress(address) && Connect(); }
00787 
00790     virtual PBoolean Close();
00791 
00794     void CloseWait();
00795 
00799     void CleanUpOnTermination() { CloseWait(); }
00800 
00803     virtual PBoolean IsCompatibleTransport(
00804       const OpalTransportAddress & address
00805     ) const = 0;
00806 
00808     enum PromisciousModes {
00809       AcceptFromRemoteOnly,
00810       AcceptFromAnyAutoSet,
00811       AcceptFromAny,
00812       NumPromisciousModes
00813     };
00814 
00825     virtual void SetPromiscuous(
00826       PromisciousModes promiscuous
00827     );
00828 
00833     virtual OpalTransportAddress GetLastReceivedAddress() const;
00834 
00839     virtual PString GetLastReceivedInterface() const;
00840 
00850     virtual PBoolean ReadPDU(
00851       PBYTEArray & packet   
00852     ) = 0;
00853 
00859     virtual PBoolean WritePDU(
00860       const PBYTEArray & pdu     
00861     ) = 0;
00862 
00863     typedef PBoolean (*WriteConnectCallback)(OpalTransport & transport, void * userData);
00864 
00877     virtual PBoolean WriteConnect(
00878       WriteConnectCallback function,  
00879       void * userData                 
00880     );
00881 
00884     virtual void AttachThread(
00885       PThread * thread
00886     );
00887 
00890     virtual PBoolean IsRunning() const;
00892 
00893     OpalEndPoint & GetEndPoint() const { return endpoint; }
00894 
00897     virtual const char * GetProtoPrefix() const = 0;
00898 
00899     PMutex & GetWriteMutex() { return m_writeMutex; }
00900 
00901   protected:
00902     OpalEndPoint & endpoint;
00903     PThread      * thread;      
00904     PMutex         m_writeMutex;
00905 };
00906 
00907 
00908 class OpalTransportIP : public OpalTransport
00909 {
00910   PCLASSINFO(OpalTransportIP, OpalTransport);
00911   public:
00916     OpalTransportIP(
00917       OpalEndPoint & endpoint,    
00918       PIPSocket::Address binding, 
00919       WORD port                   
00920     );
00922 
00927     virtual OpalTransportAddress GetLocalAddress(
00928       bool allowNAT = true   
00929     ) const;
00930 
00935     virtual PBoolean SetLocalAddress(
00936       const OpalTransportAddress & address
00937     );
00938 
00941     virtual OpalTransportAddress GetRemoteAddress() const;
00942 
00948     virtual PBoolean SetRemoteAddress(
00949       const OpalTransportAddress & address
00950     );
00951 
00953 
00954   protected:
00957     virtual const char * GetProtoPrefix() const = 0;
00958 
00959     PIPSocket::Address localAddress;  // Address of the local interface
00960     WORD               localPort;
00961     PIPSocket::Address remoteAddress; // Address of the remote host
00962     WORD               remotePort;
00963 };
00964 
00965 
00966 class OpalTransportTCP : public OpalTransportIP
00967 {
00968     PCLASSINFO(OpalTransportTCP, OpalTransportIP);
00969   public:
00974     OpalTransportTCP(
00975       OpalEndPoint & endpoint,    
00976       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00977       WORD port = 0,              
00978       PBoolean reuseAddr = false      
00979     );
00980     OpalTransportTCP(
00981       OpalEndPoint & endpoint,    
00982       PTCPSocket * socket         
00983     );
00984 
00986     ~OpalTransportTCP();
00988 
00993     virtual PBoolean IsReliable() const;
00994 
00997     virtual PBoolean IsCompatibleTransport(
00998       const OpalTransportAddress & address
00999     ) const;
01000 
01003     virtual PBoolean Connect();
01004 
01014     virtual PBoolean ReadPDU(
01015       PBYTEArray & pdu  
01016     );
01017 
01023     virtual PBoolean WritePDU(
01024       const PBYTEArray & pdu     
01025     );
01027 
01028 
01029   protected:
01032     virtual const char * GetProtoPrefix() const;
01033 
01043     virtual PBoolean OnOpen();
01044 
01045 
01046     PBoolean reuseAddressFlag;
01047 };
01048 
01049 
01050 class OpalTransportUDP : public OpalTransportIP
01051 {
01052   PCLASSINFO(OpalTransportUDP, OpalTransportIP);
01053   public:
01058     OpalTransportUDP(
01059       OpalEndPoint & endpoint,    
01060       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
01061       WORD port = 0,              
01062       bool reuseAddr = false,     
01063       bool preOpen = false        
01064     );
01065 
01068     OpalTransportUDP(
01069       OpalEndPoint & endpoint,              
01070       const PMonitoredSocketsPtr & sockets, 
01071       const PString & iface                 
01072     );
01073 
01075     ~OpalTransportUDP();
01077 
01080     virtual PBoolean Read(
01081       void * buffer,
01082       PINDEX length
01083     );
01085 
01090     virtual PBoolean IsReliable() const;
01091 
01094     virtual PBoolean IsCompatibleTransport(
01095       const OpalTransportAddress & address
01096     ) const;
01097 
01105     virtual PBoolean Connect();
01106 
01109     virtual PString GetInterface() const;
01110 
01117     virtual bool SetInterface(
01118       const PString & iface  
01119     );
01120 
01123     virtual OpalTransportAddress GetLocalAddress(
01124       bool allowNAT = true   
01125     ) const;
01126 
01131     virtual PBoolean SetLocalAddress(
01132       const OpalTransportAddress & address
01133     );
01134 
01140     virtual PBoolean SetRemoteAddress(
01141       const OpalTransportAddress & address
01142     );
01143 
01155     virtual void SetPromiscuous(
01156       PromisciousModes promiscuous
01157     );
01158 
01163     virtual OpalTransportAddress GetLastReceivedAddress() const;
01164 
01169     virtual PString GetLastReceivedInterface() const;
01170 
01180     virtual PBoolean ReadPDU(
01181       PBYTEArray & packet   
01182     );
01183 
01189     virtual PBoolean WritePDU(
01190       const PBYTEArray & pdu     
01191     );
01192 
01203     virtual PBoolean WriteConnect(
01204       WriteConnectCallback function,  
01205       void * userData                 
01206     );
01207 
01210     void SetBufferSize(
01211       PINDEX size
01212     ) { m_bufferSize = size; }
01214 
01215   protected:
01218     virtual const char * GetProtoPrefix() const;
01219 
01220     OpalManager & manager;
01221     PINDEX        m_bufferSize;
01222     PBYTEArray    m_preReadPacket;
01223     bool          m_preReadOK;
01224 
01225   friend class OpalListenerUDP;
01226 };
01227 
01228 
01230 
01231 class OpalInternalTransport : public PObject
01232 {
01233     PCLASSINFO(OpalInternalTransport, PObject);
01234   public:
01235     virtual PString GetHostName(
01236       const OpalTransportAddress & address,
01237       bool includeService
01238     ) const;
01239 
01240     virtual PBoolean GetIpAndPort(
01241       const OpalTransportAddress & address,
01242       PIPSocket::Address & ip,
01243       WORD & port
01244     ) const;
01245 
01246     virtual OpalListener * CreateListener(
01247       const OpalTransportAddress & address,
01248       OpalEndPoint & endpoint,
01249       OpalTransportAddress::BindOptions options
01250     ) const  = 0;
01251 
01252     virtual OpalTransport * CreateTransport(
01253       const OpalTransportAddress & address,
01254       OpalEndPoint & endpoint,
01255       OpalTransportAddress::BindOptions options
01256     ) const = 0;
01257 };
01258 
01259 
01261 
01262 class OpalInternalIPTransport : public OpalInternalTransport
01263 {
01264     PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport);
01265   public:
01266     virtual PString GetHostName(
01267       const OpalTransportAddress & address,
01268       bool includeService
01269     ) const;
01270     virtual PBoolean GetIpAndPort(
01271       const OpalTransportAddress & address,
01272       PIPSocket::Address & ip,
01273       WORD & port
01274     ) const;
01275 
01276     static PBoolean GetAdjustedIpAndPort(const OpalTransportAddress & address,
01277                                      OpalEndPoint & endpoint,
01278                                      OpalTransportAddress::BindOptions option,
01279                                      PIPSocket::Address & ip,
01280                                      WORD & port,
01281                                      PBoolean & reuseAddr);
01282 };
01283 
01284 template <class ListenerType, class TransportType, unsigned AltTypeOption, class AltTypeClass>
01285 class OpalInternalIPTransportTemplate : public OpalInternalIPTransport
01286 {
01287   public:
01288     OpalListener * CreateListener(
01289       const OpalTransportAddress & address,
01290       OpalEndPoint & endpoint,
01291       OpalTransportAddress::BindOptions options
01292     ) const
01293     {
01294       return new ListenerType(endpoint, address, options);
01295     }
01296 
01297     OpalTransport * CreateTransport(
01298       const OpalTransportAddress & address,
01299       OpalEndPoint & endpoint,
01300       OpalTransportAddress::BindOptions options
01301     ) const
01302     {
01303       PIPSocket::Address ip;
01304       WORD port;
01305       PBoolean reuseAddr;
01306       if (GetAdjustedIpAndPort(address, endpoint, options, ip, port, reuseAddr)) {
01307         if (options == AltTypeOption)
01308           return new AltTypeClass(endpoint, ip, 0, reuseAddr);
01309         else
01310           return new TransportType(endpoint, ip, 0, reuseAddr);
01311       }
01312       return NULL;
01313     }
01314 };
01315 
01316 typedef OpalInternalIPTransportTemplate<OpalListenerTCP, OpalTransportTCP, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPTransport;
01317 typedef OpalInternalIPTransportTemplate<OpalListenerUDP, OpalTransportUDP, OpalTransportAddress::Streamed, OpalTransportTCP> OpalInternalUDPTransport;
01318 
01319 #if OPAL_PTLIB_SSL
01320 
01321 class PSSLContext;
01322 
01323 class OpalListenerTCPS : public OpalListenerTCP
01324 {
01325   PCLASSINFO(OpalListenerTCPS, OpalListenerTCP);
01326   public:
01327     OpalListenerTCPS(
01328       OpalEndPoint & endpoint,                 
01329       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
01330       WORD port = 0,                           
01331       PBoolean exclusive = true               
01332     );
01333     OpalListenerTCPS(
01334       OpalEndPoint & endpoint,                  
01335       const OpalTransportAddress & binding,     
01336       OpalTransportAddress::BindOptions option  
01337     );
01338 
01341     ~OpalListenerTCPS();
01342 
01343     OpalTransport * Accept(const PTimeInterval & timeout);
01344     const char * GetProtoPrefix() const;
01345 
01346   protected:
01347     void Construct();
01348 
01349     PSSLContext * sslContext;
01350 };
01351 
01352 class OpalTransportTCPS : public OpalTransportTCP
01353 {
01354   PCLASSINFO(OpalTransportTCPS, OpalTransportTCP);
01355     public:
01356       OpalTransportTCPS(
01357         OpalEndPoint & endpoint,    
01358         PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
01359         WORD port = 0,              
01360         PBoolean reuseAddr = false      
01361       );
01362       OpalTransportTCPS(
01363         OpalEndPoint & endpoint,    
01364         PTCPSocket * socket         
01365       );
01366 
01368       ~OpalTransportTCPS();
01369 
01370       PBoolean IsCompatibleTransport(const OpalTransportAddress & address) const;
01371       PBoolean Connect();
01372       PBoolean OnOpen();
01373       const char * GetProtoPrefix() const;
01374 
01375     protected:
01376       PSSLContext * sslContext;
01377 };
01378 
01379 typedef OpalInternalIPTransportTemplate<OpalListenerTCPS, OpalTransportTCPS, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPSTransport;
01380 
01381 
01382 #endif // OPAL_PTLIB_SSL
01383 
01384 
01385 #endif  // OPAL_OPAL_TRANSPORT_H
01386 
01387 
01388 // End of File ///////////////////////////////////////////////////////////////

Generated on 14 Aug 2013 for OPAL by  doxygen 1.4.7