# 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: 29047 $
    00032  * $Author: rjongbloed $
    00033  * $Date: 2013-01-29 20:23:19 -0600 (Tue, 29 Jan 2013) $
    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 typedef PSafePtr<OpalTransport> OpalTransportPtr;
    00056
    00057
    00059
    00154 class OpalTransportAddress : public PCaselessString
    00155 {
    00156   PCLASSINFO(OpalTransportAddress, PCaselessString);
    00157   public:
    00158     static const PCaselessString & IpPrefix();
    00159     static const PCaselessString & UdpPrefix();
    00160     static const PCaselessString & TcpPrefix();
    00161 #if OPAL_PTLIB_SSL
    00162     static const PCaselessString & TlsPrefix();
    00163 #endif
    00164
    00167     OpalTransportAddress();
    00168     OpalTransportAddress(
    00169       const char * address,
    00170       WORD port = 0,
    00171       const char * proto = NULL
    00172     );
    00173     OpalTransportAddress(
    00174       const PString & address,
    00175       WORD port = 0,
    00176       const char * proto = NULL
    00177     );
    00178     OpalTransportAddress(
    00179       const PIPSocket::Address & ip,
    00180       WORD port,
    00181       const char * proto = NULL
    00182     );
    00183
    00185     virtual PObject * Clone() const { return new OpalTransportAddress(*this); }
    00187
    00195     PBoolean IsEquivalent(
    00196       const OpalTransportAddress & address,
    00197       bool wildcards = false
    00198     ) const;
    00199
    00202     PBoolean IsCompatible(
    00203       const OpalTransportAddress & address
    00204     ) const;
    00205
    00208     PCaselessString GetProtoPrefix() const { return Left(Find('$')+1); }
    00209
    00210     // For backward compatibility
    00211     PCaselessString GetProto(bool withDollar = false) const { return Left(Find('$')+(withDollar?1:0)); }
    00212
    00216     PBoolean GetIpAddress(PIPSocket::Address & ip) const;
    00217
    00221     PBoolean GetIpAndPort(PIPSocket::Address & ip, WORD & port) const;
    00222     PBoolean GetIpAndPort(PIPSocketAddressAndPort & ipPort) const;
    00223
    00227     virtual PString GetHostName(
    00228       bool includeService = false
    00229     ) const;
    00230
    00231     enum BindOptions {
    00232       NoBinding,
    00233       HostOnly,
    00234       FullTSAP,
    00235       Streamed,
    00236       Datagram,
    00237       RouteInterface,
    00238       NumBindOptions
    00239     };
    00240
    00272     OpalListener * CreateListener(
    00273       OpalEndPoint & endpoint,
    00274       BindOptions option
    00275     ) const;
    00276
    00304     virtual OpalTransport * CreateTransport(
    00305       OpalEndPoint & endpoint,
    00306       BindOptions option = HostOnly
    00307     ) const;
    00309
    00310
    00311   protected:
    00312     void SetInternalTransport(
    00313       WORD port,
    00314       const char * proto
    00315     );
    00316
    00317     OpalInternalTransport * m_transport;
    00318 };
    00319
    00320
    00321 class OpalTransportAddressArray : public PArray<OpalTransportAddress>
    00322 {
    00323     typedef PArray<OpalTransportAddress> ParentClass;
    00324     PCLASSINFO(OpalTransportAddressArray, ParentClass);
    00325
    00326   protected:
    00327     inline OpalTransportAddressArray(int dummy, const OpalTransportAddressArray * c)
    00328       : ParentClass(dummy, c) { }
    00329
    00330   public:
    00331     OpalTransportAddressArray(PINDEX initialSize = 0)
    00332       : ParentClass(initialSize) { }
    00333     OpalTransportAddressArray(
    00334       const OpalTransportAddress & address
    00335     ) { AppendAddress(address); }
    00336     OpalTransportAddressArray(
    00337       const PStringArray & array
    00338     ) { AppendStringCollection(array); }
    00339     OpalTransportAddressArray(
    00340       const PStringList & list
    00341     ) { AppendStringCollection(list); }
    00342     OpalTransportAddressArray(
    00343       const PSortedStringList & list
    00344     ) { AppendStringCollection(list); }
    00345
    00346     void AppendString(
    00347       const char * address
    00348     );
    00349     void AppendString(
    00350       const PString & address
    00351     );
    00352     void AppendAddress(
    00353       const OpalTransportAddress & address
    00354     );
    00355
    00356     virtual PObject * Clone() const
    00357     {
    00358       return new OpalTransportAddressArray(0, this);
    00359     }
    00360
    00361   protected:
    00362     void AppendStringCollection(
    00363       const PCollection & coll
    00364     );
    00365 };
    00366
    00367
    00368
    00369
    00371
    00384 class OpalListener : public PObject
    00385 {
    00386     PCLASSINFO(OpalListener, PObject);
    00387   public:
    00392     OpalListener(
    00393       OpalEndPoint & endpoint
    00394     );
    00396
    00401     void PrintOn(
    00402       ostream & strm
    00403     ) const;
    00405
    00408     enum ThreadMode {
    00409       SpawnNewThreadMode,
    00410       HandOffThreadMode,
    00411       SingleThreadMode
    00412     };
    00413
    00414     typedef PNotifierTemplate<const OpalTransportPtr &> AcceptHandler;
    00415     #define PDECLARE_AcceptHandlerNotifier(cls, fn) PDECLARE_NOTIFIER2(OpalListener, cls, fn, const OpalTransportPtr &)
    00416
    00417
    00432     virtual bool Open(
    00433       const AcceptHandler & acceptHandler,
    00434       ThreadMode mode = SpawnNewThreadMode
    00435     );
    00436
    00439     virtual bool IsOpen() const = 0;
    00440
    00443     virtual void Close() = 0;
    00444
    00447     virtual OpalTransport * Accept(
    00448       const PTimeInterval & timeout
    00449     ) = 0;
    00450
    00453     virtual OpalTransport * CreateTransport(
    00454       const OpalTransportAddress & localAddress,
    00455       const OpalTransportAddress & remoteAddress
    00456     ) const = 0;
    00457
    00463     virtual OpalTransportAddress GetLocalAddress(
    00464       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
    00465     ) const = 0;
    00466
    00469     void CloseWait();
    00470
    00474     void CleanUpOnTermination() { CloseWait(); }
    00476
    00477
    00478   protected:
    00487     void ListenForConnections();
    00488     void TransportThreadMain(OpalTransportPtr transport);
    00489
    00490     OpalEndPoint & endpoint;
    00491     PThread      * thread;
    00492     AcceptHandler  acceptHandler;
    00493     ThreadMode     threadMode;
    00494 };
    00495
    00496
    00497 PLIST(OpalListenerList, OpalListener);
    00498
    00499
    00500 class OpalListenerIP : public OpalListener
    00501 {
    00502   PCLASSINFO(OpalListenerIP, OpalListener);
    00503   public:
    00508     OpalListenerIP(
    00509       OpalEndPoint & endpoint,
    00510       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
    00511       WORD port = 0,
    00512       PBoolean exclusive = true
    00513     );
    00514     OpalListenerIP(
    00515       OpalEndPoint & endpoint,
    00516       const OpalTransportAddress & binding,
    00517       OpalTransportAddress::BindOptions option
    00518     );
    00520
    00528     virtual OpalTransportAddress GetLocalAddress(
    00529       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
    00530     ) const;
    00532
    00535     WORD GetListenerPort() const { return listenerPort; }
    00536
    00537     virtual const PCaselessString & GetProtoPrefix() const = 0;
    00539
    00540
    00541   protected:
    00542     bool CanCreateTransport(
    00543       const OpalTransportAddress & localAddress,
    00544       const OpalTransportAddress & remoteAddress
    00545     ) const;
    00546
    00547     PIPSocket::Address localAddress;
    00548     WORD               listenerPort;
    00549     bool               exclusiveListener;
    00550 };
    00551
    00552
    00553 class OpalListenerTCP : public OpalListenerIP
    00554 {
    00555   PCLASSINFO(OpalListenerTCP, OpalListenerIP);
    00556   public:
    00561     OpalListenerTCP(
    00562       OpalEndPoint & endpoint,
    00563       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
    00564       WORD port = 0,
    00565       PBoolean exclusive = true
    00566     );
    00567     OpalListenerTCP(
    00568       OpalEndPoint & endpoint,
    00569       const OpalTransportAddress & binding,
    00570       OpalTransportAddress::BindOptions option
    00571     );
    00572
    00575     ~OpalListenerTCP();
    00577
    00600     virtual bool Open(
    00601       const AcceptHandler & acceptHandler,
    00602       ThreadMode mode = SpawnNewThreadMode
    00603     );
    00604
    00607     virtual bool IsOpen() const;
    00608
    00611     virtual void Close();
    00612
    00615     virtual OpalTransport * Accept(
    00616       const PTimeInterval & timeout
    00617     );
    00618
    00621     virtual OpalTransport * CreateTransport(
    00622       const OpalTransportAddress & localAddress,
    00623       const OpalTransportAddress & remoteAddress
    00624     ) const;
    00626
    00627
    00628   protected:
    00629     virtual const PCaselessString & GetProtoPrefix() const;
    00630
    00631     PTCPSocket listener;
    00632 };
    00633
    00634
    00635 class OpalListenerUDP : public OpalListenerIP
    00636 {
    00637   PCLASSINFO(OpalListenerUDP, OpalListenerIP);
    00638   public:
    00643     OpalListenerUDP(
    00644       OpalEndPoint & endpoint,
    00645       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
    00646       WORD port = 0,
    00647       PBoolean exclusive = true
    00648     );
    00649     OpalListenerUDP(
    00650       OpalEndPoint & endpoint,
    00651       const OpalTransportAddress & binding,
    00652       OpalTransportAddress::BindOptions option
    00653     );
    00654
    00657     ~OpalListenerUDP();
    00659
    00682     virtual bool Open(
    00683       const AcceptHandler & acceptHandler,
    00684       ThreadMode mode = SpawnNewThreadMode
    00685     );
    00686
    00689     virtual bool IsOpen() const;
    00690
    00693     virtual void Close();
    00694
    00697     virtual OpalTransport * Accept(
    00698       const PTimeInterval & timeout
    00699     );
    00700
    00703     virtual OpalTransport * CreateTransport(
    00704       const OpalTransportAddress & localAddress,
    00705       const OpalTransportAddress & remoteAddress
    00706     ) const;
    00707
    00713     virtual OpalTransportAddress GetLocalAddress(
    00714       const OpalTransportAddress & remoteAddress = OpalTransportAddress()
    00715     ) const;
    00717
    00722     void SetBufferSize(
    00723       PINDEX size
    00724     ) { m_bufferSize = size; }
    00726
    00727
    00728   protected:
    00729     virtual const PCaselessString & GetProtoPrefix() const;
    00730
    00731     PMonitoredSocketsPtr listenerBundle;
    00732     PINDEX               m_bufferSize;
    00733 };
    00734
    00735
    00737
    00742 class OpalTransport : public PSafeObject
    00743 {
    00744     PCLASSINFO(OpalTransport, PSafeObject);
    00745   protected:
    00750     OpalTransport(OpalEndPoint & endpoint, PChannel * channel);
    00751
    00752   public:
    00755     ~OpalTransport();
    00757
    00762     void PrintOn(
    00763       ostream & strm
    00764     ) const;
    00765
    00780     virtual PBoolean Write(
    00781       const void * buf,
    00782       PINDEX len
    00783     );
    00785
    00790     virtual PBoolean IsReliable() const = 0;
    00791
    00795     virtual bool IsAuthenticated(
    00796       const PString & /*domain*/
    00797     ) const { return true; }
    00798
    00805     virtual PString GetInterface() const;
    00806
    00813     virtual bool SetInterface(
    00814       const PString & iface
    00815     );
    00816
    00819     virtual OpalTransportAddress GetLocalAddress(
    00820       bool allowNAT = true
    00821     ) const = 0;
    00822
    00827     virtual PBoolean SetLocalAddress(
    00828       const OpalTransportAddress & address
    00829     ) = 0;
    00830
    00833     virtual OpalTransportAddress GetRemoteAddress() const = 0;
    00834
    00840     virtual PBoolean SetRemoteAddress(
    00841       const OpalTransportAddress & address
    00842     ) = 0;
    00843
    00846     virtual PBoolean Connect() = 0;
    00847
    00850     PBoolean ConnectTo(
    00851       const OpalTransportAddress & address
    00852     ) { return SetRemoteAddress(address) && Connect(); }
    00853
    00856     virtual PBoolean Close();
    00857
    00860     void CloseWait();
    00861
    00865     void CleanUpOnTermination() { CloseWait(); }
    00866
    00869     virtual PBoolean IsCompatibleTransport(
    00870       const OpalTransportAddress & address
    00871     ) const = 0;
    00872
    00874     enum PromisciousModes {
    00875       AcceptFromRemoteOnly,
    00876       AcceptFromAnyAutoSet,
    00877       AcceptFromAny,
    00878       NumPromisciousModes
    00879     };
    00880
    00891     virtual void SetPromiscuous(
    00892       PromisciousModes promiscuous
    00893     );
    00894
    00899     virtual OpalTransportAddress GetLastReceivedAddress() const;
    00900
    00905     virtual PString GetLastReceivedInterface() const;
    00906
    00916     virtual PBoolean ReadPDU(
    00917       PBYTEArray & packet
    00918     ) = 0;
    00919
    00925     virtual PBoolean WritePDU(
    00926       const PBYTEArray & pdu
    00927     ) = 0;
    00928
    00929     typedef PNotifierTemplate<bool &> WriteConnectCallback;
    00930     #define PDECLARE_WriteConnectCallback(cls, fn) PDECLARE_NOTIFIER2(OpalTransport, cls, fn, bool &)
    00931
    00944     virtual bool WriteConnect(
    00945       const WriteConnectCallback & function
    00946     );
    00947
    00952     void SetKeepAlive(
    00953       const PTimeInterval & timeout,
    00954       const PBYTEArray & data
    00955     );
    00956
    00959     virtual void AttachThread(
    00960       PThread * thread
    00961     );
    00962
    00965     virtual PBoolean IsRunning() const;
    00967
    00968     OpalEndPoint & GetEndPoint() const { return endpoint; }
    00969
    00972     virtual const PCaselessString & GetProtoPrefix() const = 0;
    00973
    00974     bool IsOpen() const
    00975       { return m_channel != NULL && m_channel->IsOpen(); }
    00976
    00977     bool IsGood() const
    00978       { return IsOpen() && !m_channel->bad() && !m_channel->eof(); }
    00979
    00980     PChannel::Errors GetErrorCode(PChannel::ErrorGroup group = PChannel::NumErrorGroups) const
    00981       { return m_channel != NULL ? m_channel->GetErrorCode(group) : PChannel::NotOpen; }
    00982
    00983     PString GetErrorText(PChannel::ErrorGroup group = PChannel::NumErrorGroups) const
    00984       { return m_channel != NULL ? m_channel->GetErrorText(group) : PString::Empty(); }
    00985
    00986     int GetErrorNumber(PChannel::ErrorGroup group = PChannel::NumErrorGroups) const
    00987       { return m_channel != NULL ? m_channel->GetErrorNumber(group) : -1; }
    00988
    00989     void SetReadTimeout(const PTimeInterval & t)
    00990       { if (m_channel != NULL) m_channel->SetReadTimeout(t); }
    00991
    00992     PChannel * GetChannel() const { return m_channel; }
    00993     void SetChannel(PChannel * chan) { m_channel = chan; }
    00994
    00995   protected:
    00996     PDECLARE_NOTIFIER(PTimer, OpalTransport, KeepAlive);
    00997
    00998     OpalEndPoint & endpoint;
    00999     PChannel     * m_channel;
    01000     PThread      * m_thread;
    01001     PTimer         m_keepAliveTimer;
    01002     PBYTEArray     m_keepAliveData;
    01003 };
    01004
    01005
    01006 class OpalTransportIP : public OpalTransport
    01007 {
    01008     PCLASSINFO(OpalTransportIP, OpalTransport);
    01009   protected:
    01014     OpalTransportIP(
    01015       OpalEndPoint & endpoint,
    01016       PChannel * channel,
    01017       PIPSocket::Address binding,
    01018       WORD port
    01019     );
    01021
    01022   public:
    01027     virtual OpalTransportAddress GetLocalAddress(
    01028       bool allowNAT = true
    01029     ) const;
    01030
    01035     virtual PBoolean SetLocalAddress(
    01036       const OpalTransportAddress & address
    01037     );
    01038
    01041     virtual OpalTransportAddress GetRemoteAddress() const;
    01042
    01048     virtual PBoolean SetRemoteAddress(
    01049       const OpalTransportAddress & address
    01050     );
    01051
    01053
    01054   protected:
    01057     virtual const PCaselessString & GetProtoPrefix() const = 0;
    01058
    01059     PIPSocket::Address localAddress;  // Address of the local interface
    01060     WORD               localPort;
    01061     PIPSocket::Address remoteAddress; // Address of the remote host
    01062     WORD               remotePort;
    01063 };
    01064
    01065
    01066 class OpalTransportTCP : public OpalTransportIP
    01067 {
    01068     PCLASSINFO(OpalTransportTCP, OpalTransportIP);
    01069   public:
    01074     OpalTransportTCP(
    01075       OpalEndPoint & endpoint,
    01076       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
    01077       WORD port = 0,
    01078       PBoolean reuseAddr = false
    01079     );
    01080     OpalTransportTCP(
    01081       OpalEndPoint & endpoint,
    01082       PChannel * socket
    01083     );
    01084
    01086     ~OpalTransportTCP();
    01088
    01093     virtual PBoolean IsReliable() const;
    01094
    01097     virtual PBoolean IsCompatibleTransport(
    01098       const OpalTransportAddress & address
    01099     ) const;
    01100
    01103     virtual PBoolean Connect();
    01104
    01114     virtual PBoolean ReadPDU(
    01115       PBYTEArray & pdu
    01116     );
    01117
    01123     virtual PBoolean WritePDU(
    01124       const PBYTEArray & pdu
    01125     );
    01127
    01128
    01129   protected:
    01132     virtual const PCaselessString & GetProtoPrefix() const;
    01133
    01134     bool OnConnectedSocket(PTCPSocket * socket);
    01135
    01136     PBoolean reuseAddressFlag;
    01137 };
    01138
    01139
    01140 class OpalTransportUDP : public OpalTransportIP
    01141 {
    01142   PCLASSINFO(OpalTransportUDP, OpalTransportIP);
    01143   public:
    01148     OpalTransportUDP(
    01149       OpalEndPoint & endpoint,
    01150       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
    01151       WORD port = 0,
    01152       bool reuseAddr = false,
    01153       bool preOpen = false
    01154     );
    01155
    01158     OpalTransportUDP(
    01159       OpalEndPoint & endpoint,
    01160       const PMonitoredSocketsPtr & sockets,
    01161       const PString & iface
    01162     );
    01163
    01165     ~OpalTransportUDP();
    01167
    01170     virtual PBoolean Read(
    01171       void * buffer,
    01172       PINDEX length
    01173     );
    01175
    01180     virtual PBoolean IsReliable() const;
    01181
    01184     virtual PBoolean IsCompatibleTransport(
    01185       const OpalTransportAddress & address
    01186     ) const;
    01187
    01195     virtual PBoolean Connect();
    01196
    01199     virtual PString GetInterface() const;
    01200
    01207     virtual bool SetInterface(
    01208       const PString & iface
    01209     );
    01210
    01213     virtual OpalTransportAddress GetLocalAddress(
    01214       bool allowNAT = true
    01215     ) const;
    01216
    01221     virtual PBoolean SetLocalAddress(
    01222       const OpalTransportAddress & address
    01223     );
    01224
    01230     virtual PBoolean SetRemoteAddress(
    01231       const OpalTransportAddress & address
    01232     );
    01233
    01245     virtual void SetPromiscuous(
    01246       PromisciousModes promiscuous
    01247     );
    01248
    01253     virtual OpalTransportAddress GetLastReceivedAddress() const;
    01254
    01259     virtual PString GetLastReceivedInterface() const;
    01260
    01270     virtual PBoolean ReadPDU(
    01271       PBYTEArray & packet
    01272     );
    01273
    01279     virtual PBoolean WritePDU(
    01280       const PBYTEArray & pdu
    01281     );
    01282
    01293     virtual bool WriteConnect(
    01294       const WriteConnectCallback & function
    01295     );
    01296
    01299     void SetBufferSize(
    01300       PINDEX size
    01301     ) { m_bufferSize = size; }
    01303
    01304   protected:
    01307     virtual const PCaselessString & GetProtoPrefix() const;
    01308
    01309     OpalManager & manager;
    01310     PINDEX        m_bufferSize;
    01311     PBYTEArray    m_preReadPacket;
    01312     bool          m_preReadOK;
    01313
    01314   friend class OpalListenerUDP;
    01315 };
    01316
    01317
    01319
    01320 class OpalInternalTransport : public PObject
    01321 {
    01322     PCLASSINFO(OpalInternalTransport, PObject);
    01323   public:
    01324     virtual bool Parse(
    01325       OpalTransportAddress & address,
    01326       WORD port
    01327     ) const = 0;
    01328
    01329     virtual PString GetHostName(
    01330       const OpalTransportAddress & address,
    01331       bool includeService
    01332     ) const;
    01333
    01334     virtual PBoolean GetIpAndPort(
    01335       const OpalTransportAddress & address,
    01336       PIPSocket::Address & ip,
    01337       WORD & port
    01338     ) const;
    01339
    01340     virtual OpalListener * CreateListener(
    01341       const OpalTransportAddress & address,
    01342       OpalEndPoint & endpoint,
    01343       OpalTransportAddress::BindOptions options
    01344     ) const  = 0;
    01345
    01346     virtual OpalTransport * CreateTransport(
    01347       const OpalTransportAddress & address,
    01348       OpalEndPoint & endpoint,
    01349       OpalTransportAddress::BindOptions options
    01350     ) const = 0;
    01351 };
    01352
    01353
    01355
    01356 class OpalInternalIPTransport : public OpalInternalTransport
    01357 {
    01358     PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport);
    01359   public:
    01360     virtual bool Parse(
    01361       OpalTransportAddress & address,
    01362       WORD port
    01363     ) const;
    01364     virtual PString GetHostName(
    01365       const OpalTransportAddress & address,
    01366       bool includeService
    01367     ) const;
    01368     virtual PBoolean GetIpAndPort(
    01369       const OpalTransportAddress & address,
    01370       PIPSocket::Address & ip,
    01371       WORD & port
    01372     ) const;
    01373
    01374     static PBoolean GetAdjustedIpAndPort(const OpalTransportAddress & address,
    01375                                      OpalEndPoint & endpoint,
    01376                                      OpalTransportAddress::BindOptions option,
    01377                                      PIPSocket::Address & ip,
    01378                                      WORD & port,
    01379                                      PBoolean & reuseAddr);
    01380 };
    01381
    01382 template <class ListenerType, class TransportType, unsigned AltTypeOption, class AltTypeClass>
    01383 class OpalInternalIPTransportTemplate : public OpalInternalIPTransport
    01384 {
    01385   public:
    01386     OpalListener * CreateListener(
    01387       const OpalTransportAddress & address,
    01388       OpalEndPoint & endpoint,
    01389       OpalTransportAddress::BindOptions options
    01390     ) const
    01391     {
    01392       return new ListenerType(endpoint, address, options);
    01393     }
    01394
    01395     OpalTransport * CreateTransport(
    01396       const OpalTransportAddress & address,
    01397       OpalEndPoint & endpoint,
    01398       OpalTransportAddress::BindOptions options
    01399     ) const
    01400     {
    01401       PIPSocket::Address ip;
    01402       WORD port;
    01403       PBoolean reuseAddr;
    01404       if (GetAdjustedIpAndPort(address, endpoint, options, ip, port, reuseAddr)) {
    01405         if (options == AltTypeOption)
    01406           return new AltTypeClass(endpoint, ip, 0, reuseAddr);
    01407         else
    01408           return new TransportType(endpoint, ip, 0, reuseAddr);
    01409       }
    01410       return NULL;
    01411     }
    01412 };
    01413
    01414 typedef OpalInternalIPTransportTemplate<OpalListenerTCP, OpalTransportTCP, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPTransport;
    01415 typedef OpalInternalIPTransportTemplate<OpalListenerUDP, OpalTransportUDP, OpalTransportAddress::Streamed, OpalTransportTCP> OpalInternalUDPTransport;
    01416
    01417 #if OPAL_PTLIB_SSL
    01418
    01419 class PSSLContext;
    01420 class PSSLChannel;
    01421
    01422 class OpalListenerTLS : public OpalListenerTCP
    01423 {
    01424   PCLASSINFO(OpalListenerTLS, OpalListenerTCP);
    01425   public:
    01426     OpalListenerTLS(
    01427       OpalEndPoint & endpoint,
    01428       PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
    01429       WORD port = 0,
    01430       PBoolean exclusive = true
    01431     );
    01432     OpalListenerTLS(
    01433       OpalEndPoint & endpoint,
    01434       const OpalTransportAddress & binding,
    01435       OpalTransportAddress::BindOptions option
    01436     );
    01437
    01440     ~OpalListenerTLS();
    01441
    01442     virtual PBoolean Open(const AcceptHandler & acceptHandler, ThreadMode mode = SpawnNewThreadMode);
    01443     virtual OpalTransport * Accept(const PTimeInterval & timeout);
    01444     virtual const PCaselessString & GetProtoPrefix() const;
    01445     virtual OpalTransport * CreateTransport(
    01446       const OpalTransportAddress & localAddress,
    01447       const OpalTransportAddress & remoteAddress
    01448     ) const;
    01449
    01450   protected:
    01451     PSSLContext * m_sslContext;
    01452 };
    01453
    01454
    01455 class OpalTransportTLS : public OpalTransportTCP
    01456 {
    01457   PCLASSINFO(OpalTransportTLS, OpalTransportTCP);
    01458     public:
    01459       OpalTransportTLS(
    01460         OpalEndPoint & endpoint,
    01461         PSSLChannel * ssl
    01462       );
    01463
    01464       OpalTransportTLS(
    01465         OpalEndPoint & endpoint,
    01466         PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
    01467         WORD port = 0,
    01468         PBoolean reuseAddr = false
    01469       );
    01470
    01472       ~OpalTransportTLS();
    01473
    01474       // Overrides
    01475       virtual PBoolean IsCompatibleTransport(const OpalTransportAddress & address) const;
    01476       virtual PBoolean Connect();
    01477       virtual const PCaselessString & GetProtoPrefix() const;
    01478       virtual bool IsAuthenticated(const PString & domain) const;
    01479 };
    01480
    01481 typedef OpalInternalIPTransportTemplate<OpalListenerTLS, OpalTransportTLS, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTLSTransport;
    01482
    01483 typedef OpalTransportTLS OpalTransportTCPS; // For backward compatibility
    01484 typedef OpalListenerTLS OpalListenerTCPS;
    01485
    01486
    01487 #endif // OPAL_PTLIB_SSL
    01488
    01489
    01490 #endif  // OPAL_OPAL_TRANSPORT_H
    01491
    01492
    01493 // End of File ///////////////////////////////////////////////////////////////