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: 19605 $
00032  * $Author: csoutheren $
00033  * $Date: 2008-02-27 07:01:25 +0000 (Wed, 27 Feb 2008) $
00034  */
00035 
00036 #ifndef __OPAL_TRANSPORT_H
00037 #define __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 
00368 OpalTransportAddressArray OpalGetInterfaceAddresses(
00369   const OpalListenerList & listeners, 
00370   PBoolean excludeLocalHost = PTrue,       
00371   OpalTransport * associatedTransport = NULL
00373 );
00374 
00375 OpalTransportAddressArray OpalGetInterfaceAddresses(
00376   const OpalTransportAddress & addr,  
00377   PBoolean excludeLocalHost = PTrue,       
00378   OpalTransport * associatedTransport = NULL
00380 );
00381 
00382 
00383 class OpalListenerIP : public OpalListener
00384 {
00385   PCLASSINFO(OpalListenerIP, OpalListener);
00386   public:
00391     OpalListenerIP(
00392       OpalEndPoint & endpoint,                 
00393       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00394       WORD port = 0,                           
00395       PBoolean exclusive = PTrue
00396     );
00397     OpalListenerIP(
00398       OpalEndPoint & endpoint,                  
00399       const OpalTransportAddress & binding,     
00400       OpalTransportAddress::BindOptions option  
00401     );
00403 
00408     virtual OpalTransportAddress GetLocalAddress(
00409       const OpalTransportAddress & preferredAddress = OpalTransportAddress()
00410     ) const;
00412 
00415     WORD GetListenerPort() const { return listenerPort; }
00416 
00417     virtual const char * GetProtoPrefix() const = 0;
00419 
00420 
00421   protected:
00422     PIPSocket::Address localAddress;
00423     WORD               listenerPort;
00424     PBoolean               exclusiveListener;
00425 };
00426 
00427 
00428 class OpalListenerTCP : public OpalListenerIP
00429 {
00430   PCLASSINFO(OpalListenerTCP, OpalListenerIP);
00431   public:
00436     OpalListenerTCP(
00437       OpalEndPoint & endpoint,                 
00438       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00439       WORD port = 0,                           
00440       PBoolean exclusive = PTrue
00441     );
00442     OpalListenerTCP(
00443       OpalEndPoint & endpoint,                  
00444       const OpalTransportAddress & binding,     
00445       OpalTransportAddress::BindOptions option  
00446     );
00447 
00450     ~OpalListenerTCP();
00452 
00475     virtual PBoolean Open(
00476       const PNotifier & acceptHandler,  
00477       ThreadMode mode = SpawnNewThreadMode 
00478     );
00479 
00482     virtual PBoolean IsOpen();
00483 
00486     virtual void Close();
00487 
00490     virtual OpalTransport * Accept(
00491       const PTimeInterval & timeout  
00492     );
00493 
00496     virtual OpalTransport * CreateTransport(
00497       const OpalTransportAddress & localAddress,
00498       const OpalTransportAddress & remoteAddress
00499     ) const;
00501 
00502 
00503   protected:
00504     virtual const char * GetProtoPrefix() const;
00505 
00506     PTCPSocket listener;
00507 };
00508 
00509 
00510 class OpalListenerUDP : public OpalListenerIP
00511 {
00512   PCLASSINFO(OpalListenerUDP, OpalListenerIP);
00513   public:
00518     OpalListenerUDP(
00519       OpalEndPoint & endpoint,  
00520       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00521       WORD port = 0,            
00522       PBoolean exclusive = PTrue
00523     );
00524     OpalListenerUDP(
00525       OpalEndPoint & endpoint,                  
00526       const OpalTransportAddress & binding,     
00527       OpalTransportAddress::BindOptions option  
00528     );
00529 
00532     ~OpalListenerUDP();
00534 
00557     virtual PBoolean Open(
00558       const PNotifier & acceptHandler,  
00559       ThreadMode mode = SpawnNewThreadMode 
00560     );
00561 
00564     virtual PBoolean IsOpen();
00565 
00568     virtual void Close();
00569 
00572     virtual OpalTransport * Accept(
00573       const PTimeInterval & timeout  
00574     );
00575 
00578     virtual OpalTransport * CreateTransport(
00579       const OpalTransportAddress & localAddress,
00580       const OpalTransportAddress & remoteAddress
00581     ) const;
00583 
00584 
00585   protected:
00586     virtual const char * GetProtoPrefix() const;
00587 
00588     PMonitoredSocketsPtr listenerBundle;
00589 };
00590 
00591 
00593 
00598 class OpalTransport : public PIndirectChannel
00599 {
00600     PCLASSINFO(OpalTransport, PIndirectChannel);
00601   public:
00606     OpalTransport(OpalEndPoint & endpoint);
00607 
00610     ~OpalTransport();
00612 
00617     void PrintOn(
00618       ostream & strm
00619     ) const;
00621 
00626     virtual PBoolean IsReliable() const = 0;
00627 
00634     virtual PString GetInterface() const;
00635 
00642     virtual bool SetInterface(
00643       const PString & iface  
00644     );
00645 
00648     virtual OpalTransportAddress GetLocalAddress() const = 0;
00649 
00654     virtual PBoolean SetLocalAddress(
00655       const OpalTransportAddress & address
00656     ) = 0;
00657 
00660     virtual OpalTransportAddress GetRemoteAddress() const = 0;
00661 
00667     virtual PBoolean SetRemoteAddress(
00668       const OpalTransportAddress & address
00669     ) = 0;
00670 
00673     virtual PBoolean Connect() = 0;
00674 
00677     PBoolean ConnectTo(
00678       const OpalTransportAddress & address
00679     ) { return SetRemoteAddress(address) && Connect(); }
00680 
00683     virtual PBoolean Close();
00684 
00687     void CloseWait();
00688 
00692     void CleanUpOnTermination() { CloseWait(); }
00693 
00696     virtual PBoolean IsCompatibleTransport(
00697       const OpalTransportAddress & address
00698     ) const = 0;
00699 
00701     enum PromisciousModes {
00702       AcceptFromRemoteOnly,
00703       AcceptFromAnyAutoSet,
00704       AcceptFromAny,
00705       NumPromisciousModes
00706     };
00707 
00718     virtual void SetPromiscuous(
00719       PromisciousModes promiscuous
00720     );
00721 
00726     virtual OpalTransportAddress GetLastReceivedAddress() const;
00727 
00732     virtual PString GetLastReceivedInterface() const;
00733 
00739     virtual PBoolean ReadPDU(
00740       PBYTEArray & packet   
00741     ) = 0;
00742 
00748     virtual PBoolean WritePDU(
00749       const PBYTEArray & pdu     
00750     ) = 0;
00751 
00752     typedef PBoolean (*WriteConnectCallback)(OpalTransport & transport, void * userData);
00753 
00766     virtual PBoolean WriteConnect(
00767       WriteConnectCallback function,  
00768       void * userData                 
00769     );
00770 
00773     virtual void AttachThread(
00774       PThread * thread
00775     );
00776 
00779     virtual PBoolean IsRunning() const;
00781 
00782     OpalEndPoint & GetEndPoint() const { return endpoint; }
00783 
00784     virtual void SetReadsPerPDU(int) {}
00785 
00788     virtual const char * GetProtoPrefix() const = 0;
00789 
00790   protected:
00791     OpalEndPoint & endpoint;
00792     PThread      * thread;      
00793 };
00794 
00795 
00796 class OpalTransportIP : public OpalTransport
00797 {
00798   PCLASSINFO(OpalTransportIP, OpalTransport);
00799   public:
00804     OpalTransportIP(
00805       OpalEndPoint & endpoint,    
00806       PIPSocket::Address binding, 
00807       WORD port                   
00808     );
00810 
00815     virtual OpalTransportAddress GetLocalAddress() const;
00816 
00821     virtual PBoolean SetLocalAddress(
00822       const OpalTransportAddress & address
00823     );
00824 
00827     virtual OpalTransportAddress GetRemoteAddress() const;
00828 
00834     virtual PBoolean SetRemoteAddress(
00835       const OpalTransportAddress & address
00836     );
00837 
00839 
00840   protected:
00843     virtual const char * GetProtoPrefix() const = 0;
00844 
00845     PIPSocket::Address localAddress;  // Address of the local interface
00846     WORD               localPort;
00847     PIPSocket::Address remoteAddress; // Address of the remote host
00848     WORD               remotePort;
00849 };
00850 
00851 
00852 class OpalTransportTCP : public OpalTransportIP
00853 {
00854     PCLASSINFO(OpalTransportTCP, OpalTransportIP);
00855   public:
00860     OpalTransportTCP(
00861       OpalEndPoint & endpoint,    
00862       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00863       WORD port = 0,              
00864       PBoolean reuseAddr = PFalse      
00865     );
00866     OpalTransportTCP(
00867       OpalEndPoint & endpoint,    
00868       PTCPSocket * socket         
00869     );
00870 
00872     ~OpalTransportTCP();
00874 
00879     virtual PBoolean IsReliable() const;
00880 
00883     virtual PBoolean IsCompatibleTransport(
00884       const OpalTransportAddress & address
00885     ) const;
00886 
00889     virtual PBoolean Connect();
00890 
00896     virtual PBoolean ReadPDU(
00897       PBYTEArray & pdu  
00898     );
00899 
00905     virtual PBoolean WritePDU(
00906       const PBYTEArray & pdu     
00907     );
00909 
00910 
00911   protected:
00914     virtual const char * GetProtoPrefix() const;
00915 
00925     virtual PBoolean OnOpen();
00926 
00927 
00928     PBoolean reuseAddressFlag;
00929 };
00930 
00931 
00932 class OpalTransportUDP : public OpalTransportIP
00933 {
00934   PCLASSINFO(OpalTransportUDP, OpalTransportIP);
00935   public:
00940     OpalTransportUDP(
00941       OpalEndPoint & endpoint,    
00942       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
00943       WORD port = 0,              
00944       PBoolean reuseAddr = PFalse      
00945     );
00946 
00949     OpalTransportUDP(
00950       OpalEndPoint & endpoint,              
00951       const PBYTEArray & preReadPacket,     
00952       const PMonitoredSocketsPtr & sockets, 
00953       const PString & iface,                
00954       PIPSocket::Address remoteAddress,     
00955       WORD remotePort                       
00956     );
00957 
00959     ~OpalTransportUDP();
00961 
00964     virtual PBoolean Read(
00965       void * buffer,
00966       PINDEX length
00967     );
00969 
00974     virtual PBoolean IsReliable() const;
00975 
00978     virtual PBoolean IsCompatibleTransport(
00979       const OpalTransportAddress & address
00980     ) const;
00981 
00989     virtual PBoolean Connect();
00990 
00993     virtual PString GetInterface() const;
00994 
01001     virtual bool SetInterface(
01002       const PString & iface  
01003     );
01004 
01007     virtual OpalTransportAddress GetLocalAddress() const;
01008 
01013     virtual PBoolean SetLocalAddress(
01014       const OpalTransportAddress & address
01015     );
01016 
01022     virtual PBoolean SetRemoteAddress(
01023       const OpalTransportAddress & address
01024     );
01025 
01037     virtual void SetPromiscuous(
01038       PromisciousModes promiscuous
01039     );
01040 
01045     virtual OpalTransportAddress GetLastReceivedAddress() const;
01046 
01051     virtual PString GetLastReceivedInterface() const;
01052 
01058     virtual PBoolean ReadPDU(
01059       PBYTEArray & packet   
01060     );
01061 
01067     virtual PBoolean WritePDU(
01068       const PBYTEArray & pdu     
01069     );
01070 
01081     virtual PBoolean WriteConnect(
01082       WriteConnectCallback function,  
01083       void * userData                 
01084     );
01086 
01087     virtual void SetReadsPerPDU(int v) { readsPerPdu = v; }
01088 
01089   protected:
01092     virtual const char * GetProtoPrefix() const;
01093 
01094     OpalManager & manager;
01095     PBYTEArray    preReadPacket;
01096     int readsPerPdu;
01097 };
01098 
01099 
01101 
01102 class OpalInternalTransport : public PObject
01103 {
01104     PCLASSINFO(OpalInternalTransport, PObject);
01105   public:
01106     virtual PString GetHostName(
01107       const OpalTransportAddress & address
01108     ) const;
01109 
01110     virtual PBoolean GetIpAndPort(
01111       const OpalTransportAddress & address,
01112       PIPSocket::Address & ip,
01113       WORD & port
01114     ) const;
01115 
01116     virtual OpalListener * CreateListener(
01117       const OpalTransportAddress & address,
01118       OpalEndPoint & endpoint,
01119       OpalTransportAddress::BindOptions options
01120     ) const  = 0;
01121 
01122     virtual OpalTransport * CreateTransport(
01123       const OpalTransportAddress & address,
01124       OpalEndPoint & endpoint,
01125       OpalTransportAddress::BindOptions options
01126     ) const = 0;
01127 };
01128 
01129 
01131 
01132 class OpalInternalIPTransport : public OpalInternalTransport
01133 {
01134     PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport);
01135   public:
01136     virtual PString GetHostName(
01137       const OpalTransportAddress & address
01138     ) const;
01139     virtual PBoolean GetIpAndPort(
01140       const OpalTransportAddress & address,
01141       PIPSocket::Address & ip,
01142       WORD & port
01143     ) const;
01144 
01145     static PBoolean GetAdjustedIpAndPort(const OpalTransportAddress & address,
01146                                      OpalEndPoint & endpoint,
01147                                      OpalTransportAddress::BindOptions option,
01148                                      PIPSocket::Address & ip,
01149                                      WORD & port,
01150                                      PBoolean & reuseAddr);
01151 };
01152 
01153 template <class ListenerType, class TransportType, unsigned AltTypeOption, class AltTypeClass>
01154 class OpalInternalIPTransportTemplate : public OpalInternalIPTransport
01155 {
01156   public:
01157     OpalListener * CreateListener(
01158       const OpalTransportAddress & address,
01159       OpalEndPoint & endpoint,
01160       OpalTransportAddress::BindOptions options
01161     ) const
01162     {
01163       return new ListenerType(endpoint, address, options);
01164     }
01165 
01166     OpalTransport * CreateTransport(
01167       const OpalTransportAddress & address,
01168       OpalEndPoint & endpoint,
01169       OpalTransportAddress::BindOptions options
01170     ) const
01171     {
01172       PIPSocket::Address ip;
01173       WORD port;
01174       PBoolean reuseAddr;
01175       if (GetAdjustedIpAndPort(address, endpoint, options, ip, port, reuseAddr)) {
01176         if (options == AltTypeOption)
01177           return new AltTypeClass(endpoint, ip, 0, reuseAddr);
01178         else
01179           return new TransportType(endpoint, ip, 0, reuseAddr);
01180       }
01181       return NULL;
01182     }
01183 };
01184 
01185 typedef OpalInternalIPTransportTemplate<OpalListenerTCP, OpalTransportTCP, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPTransport;
01186 typedef OpalInternalIPTransportTemplate<OpalListenerUDP, OpalTransportUDP, OpalTransportAddress::Streamed, OpalTransportTCP> OpalInternalUDPTransport;
01187 
01188 #if P_SSL
01189 
01190 class PSSLContext;
01191 
01192 class OpalListenerTCPS : public OpalListenerTCP
01193 {
01194   PCLASSINFO(OpalListenerTCPS, OpalListenerTCP);
01195   public:
01196     OpalListenerTCPS(
01197       OpalEndPoint & endpoint,                 
01198       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
01199       WORD port = 0,                           
01200       PBoolean exclusive = PTrue
01201     );
01202     OpalListenerTCPS(
01203       OpalEndPoint & endpoint,                  
01204       const OpalTransportAddress & binding,     
01205       OpalTransportAddress::BindOptions option  
01206     );
01207 
01210     ~OpalListenerTCPS();
01211 
01212     OpalTransport * Accept(const PTimeInterval & timeout);
01213     const char * GetProtoPrefix() const;
01214 
01215   protected:
01216     void Construct();
01217 
01218     PSSLContext * sslContext;
01219 };
01220 
01221 class OpalTransportTCPS : public OpalTransportTCP
01222 {
01223   PCLASSINFO(OpalTransportTCPS, OpalTransportTCP);
01224     public:
01225       OpalTransportTCPS(
01226         OpalEndPoint & endpoint,    
01227         PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 
01228         WORD port = 0,              
01229         PBoolean reuseAddr = PFalse      
01230       );
01231       OpalTransportTCPS(
01232         OpalEndPoint & endpoint,    
01233         PTCPSocket * socket         
01234       );
01235 
01237       ~OpalTransportTCPS();
01238 
01239       PBoolean IsCompatibleTransport(const OpalTransportAddress & address) const;
01240       PBoolean Connect();
01241       PBoolean OnOpen();
01242       const char * GetProtoPrefix() const;
01243 
01244     protected:
01245       PSSLContext * sslContext;
01246 };
01247 
01248 typedef OpalInternalIPTransportTemplate<OpalListenerTCPS, OpalTransportTCPS, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPSTransport;
01249 
01250 
01251 #endif // P_SSL
01252 
01253 
01254 #endif  // __OPAL_TRANSPORT_H
01255 
01256 
01257 // End of File ///////////////////////////////////////////////////////////////

Generated on Fri Mar 7 07:36:40 2008 for OPAL by  doxygen 1.5.1