00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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 bool excludeLocalHost,
00371 OpalTransport * associatedTransport,
00372 PNatMethod * natMethod
00373 );
00374
00375 OpalTransportAddressArray OpalGetInterfaceAddresses(
00376 const OpalTransportAddress & addr,
00377 bool excludeLocalHost,
00378 OpalTransport * associatedTransport,
00379 PNatMethod * natMethod
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
00786 virtual const char * GetProtoPrefix() const = 0;
00787
00788 protected:
00789 OpalEndPoint & endpoint;
00790 PThread * thread;
00791 };
00792
00793
00794 class OpalTransportIP : public OpalTransport
00795 {
00796 PCLASSINFO(OpalTransportIP, OpalTransport);
00797 public:
00802 OpalTransportIP(
00803 OpalEndPoint & endpoint,
00804 PIPSocket::Address binding,
00805 WORD port
00806 );
00808
00813 virtual OpalTransportAddress GetLocalAddress() const;
00814
00819 virtual PBoolean SetLocalAddress(
00820 const OpalTransportAddress & address
00821 );
00822
00825 virtual OpalTransportAddress GetRemoteAddress() const;
00826
00832 virtual PBoolean SetRemoteAddress(
00833 const OpalTransportAddress & address
00834 );
00835
00837
00838 protected:
00841 virtual const char * GetProtoPrefix() const = 0;
00842
00843 PIPSocket::Address localAddress;
00844 WORD localPort;
00845 PIPSocket::Address remoteAddress;
00846 WORD remotePort;
00847 };
00848
00849
00850 class OpalTransportTCP : public OpalTransportIP
00851 {
00852 PCLASSINFO(OpalTransportTCP, OpalTransportIP);
00853 public:
00858 OpalTransportTCP(
00859 OpalEndPoint & endpoint,
00860 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
00861 WORD port = 0,
00862 PBoolean reuseAddr = PFalse
00863 );
00864 OpalTransportTCP(
00865 OpalEndPoint & endpoint,
00866 PTCPSocket * socket
00867 );
00868
00870 ~OpalTransportTCP();
00872
00877 virtual PBoolean IsReliable() const;
00878
00881 virtual PBoolean IsCompatibleTransport(
00882 const OpalTransportAddress & address
00883 ) const;
00884
00887 virtual PBoolean Connect();
00888
00894 virtual PBoolean ReadPDU(
00895 PBYTEArray & pdu
00896 );
00897
00903 virtual PBoolean WritePDU(
00904 const PBYTEArray & pdu
00905 );
00907
00908
00909 protected:
00912 virtual const char * GetProtoPrefix() const;
00913
00923 virtual PBoolean OnOpen();
00924
00925
00926 PBoolean reuseAddressFlag;
00927 };
00928
00929
00930 class OpalTransportUDP : public OpalTransportIP
00931 {
00932 PCLASSINFO(OpalTransportUDP, OpalTransportIP);
00933 public:
00938 OpalTransportUDP(
00939 OpalEndPoint & endpoint,
00940 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
00941 WORD port = 0,
00942 bool reuseAddr = false,
00943 bool preOpen = false
00944 );
00945
00948 OpalTransportUDP(
00949 OpalEndPoint & endpoint,
00950 const PBYTEArray & preReadPacket,
00951 const PMonitoredSocketsPtr & sockets,
00952 const PString & iface,
00953 PIPSocket::Address remoteAddress,
00954 WORD remotePort
00955 );
00956
00958 ~OpalTransportUDP();
00960
00963 virtual PBoolean Read(
00964 void * buffer,
00965 PINDEX length
00966 );
00968
00973 virtual PBoolean IsReliable() const;
00974
00977 virtual PBoolean IsCompatibleTransport(
00978 const OpalTransportAddress & address
00979 ) const;
00980
00988 virtual PBoolean Connect();
00989
00992 virtual PString GetInterface() const;
00993
01000 virtual bool SetInterface(
01001 const PString & iface
01002 );
01003
01006 virtual OpalTransportAddress GetLocalAddress() const;
01007
01012 virtual PBoolean SetLocalAddress(
01013 const OpalTransportAddress & address
01014 );
01015
01021 virtual PBoolean SetRemoteAddress(
01022 const OpalTransportAddress & address
01023 );
01024
01036 virtual void SetPromiscuous(
01037 PromisciousModes promiscuous
01038 );
01039
01044 virtual OpalTransportAddress GetLastReceivedAddress() const;
01045
01050 virtual PString GetLastReceivedInterface() const;
01051
01057 virtual PBoolean ReadPDU(
01058 PBYTEArray & packet
01059 );
01060
01066 virtual PBoolean WritePDU(
01067 const PBYTEArray & pdu
01068 );
01069
01080 virtual PBoolean WriteConnect(
01081 WriteConnectCallback function,
01082 void * userData
01083 );
01085
01086 protected:
01089 virtual const char * GetProtoPrefix() const;
01090
01091 OpalManager & manager;
01092 PBYTEArray preReadPacket;
01093 };
01094
01095
01097
01098 class OpalInternalTransport : public PObject
01099 {
01100 PCLASSINFO(OpalInternalTransport, PObject);
01101 public:
01102 virtual PString GetHostName(
01103 const OpalTransportAddress & address
01104 ) const;
01105
01106 virtual PBoolean GetIpAndPort(
01107 const OpalTransportAddress & address,
01108 PIPSocket::Address & ip,
01109 WORD & port
01110 ) const;
01111
01112 virtual OpalListener * CreateListener(
01113 const OpalTransportAddress & address,
01114 OpalEndPoint & endpoint,
01115 OpalTransportAddress::BindOptions options
01116 ) const = 0;
01117
01118 virtual OpalTransport * CreateTransport(
01119 const OpalTransportAddress & address,
01120 OpalEndPoint & endpoint,
01121 OpalTransportAddress::BindOptions options
01122 ) const = 0;
01123 };
01124
01125
01127
01128 class OpalInternalIPTransport : public OpalInternalTransport
01129 {
01130 PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport);
01131 public:
01132 virtual PString GetHostName(
01133 const OpalTransportAddress & address
01134 ) const;
01135 virtual PBoolean GetIpAndPort(
01136 const OpalTransportAddress & address,
01137 PIPSocket::Address & ip,
01138 WORD & port
01139 ) const;
01140
01141 static PBoolean GetAdjustedIpAndPort(const OpalTransportAddress & address,
01142 OpalEndPoint & endpoint,
01143 OpalTransportAddress::BindOptions option,
01144 PIPSocket::Address & ip,
01145 WORD & port,
01146 PBoolean & reuseAddr);
01147 };
01148
01149 template <class ListenerType, class TransportType, unsigned AltTypeOption, class AltTypeClass>
01150 class OpalInternalIPTransportTemplate : public OpalInternalIPTransport
01151 {
01152 public:
01153 OpalListener * CreateListener(
01154 const OpalTransportAddress & address,
01155 OpalEndPoint & endpoint,
01156 OpalTransportAddress::BindOptions options
01157 ) const
01158 {
01159 return new ListenerType(endpoint, address, options);
01160 }
01161
01162 OpalTransport * CreateTransport(
01163 const OpalTransportAddress & address,
01164 OpalEndPoint & endpoint,
01165 OpalTransportAddress::BindOptions options
01166 ) const
01167 {
01168 PIPSocket::Address ip;
01169 WORD port;
01170 PBoolean reuseAddr;
01171 if (GetAdjustedIpAndPort(address, endpoint, options, ip, port, reuseAddr)) {
01172 if (options == AltTypeOption)
01173 return new AltTypeClass(endpoint, ip, 0, reuseAddr);
01174 else
01175 return new TransportType(endpoint, ip, 0, reuseAddr);
01176 }
01177 return NULL;
01178 }
01179 };
01180
01181 typedef OpalInternalIPTransportTemplate<OpalListenerTCP, OpalTransportTCP, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPTransport;
01182 typedef OpalInternalIPTransportTemplate<OpalListenerUDP, OpalTransportUDP, OpalTransportAddress::Streamed, OpalTransportTCP> OpalInternalUDPTransport;
01183
01184 #if OPAL_PTLIB_SSL
01185
01186 class PSSLContext;
01187
01188 class OpalListenerTCPS : public OpalListenerTCP
01189 {
01190 PCLASSINFO(OpalListenerTCPS, OpalListenerTCP);
01191 public:
01192 OpalListenerTCPS(
01193 OpalEndPoint & endpoint,
01194 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
01195 WORD port = 0,
01196 PBoolean exclusive = PTrue
01197 );
01198 OpalListenerTCPS(
01199 OpalEndPoint & endpoint,
01200 const OpalTransportAddress & binding,
01201 OpalTransportAddress::BindOptions option
01202 );
01203
01206 ~OpalListenerTCPS();
01207
01208 OpalTransport * Accept(const PTimeInterval & timeout);
01209 const char * GetProtoPrefix() const;
01210
01211 protected:
01212 void Construct();
01213
01214 PSSLContext * sslContext;
01215 };
01216
01217 class OpalTransportTCPS : public OpalTransportTCP
01218 {
01219 PCLASSINFO(OpalTransportTCPS, OpalTransportTCP);
01220 public:
01221 OpalTransportTCPS(
01222 OpalEndPoint & endpoint,
01223 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
01224 WORD port = 0,
01225 PBoolean reuseAddr = PFalse
01226 );
01227 OpalTransportTCPS(
01228 OpalEndPoint & endpoint,
01229 PTCPSocket * socket
01230 );
01231
01233 ~OpalTransportTCPS();
01234
01235 PBoolean IsCompatibleTransport(const OpalTransportAddress & address) const;
01236 PBoolean Connect();
01237 PBoolean OnOpen();
01238 const char * GetProtoPrefix() const;
01239
01240 protected:
01241 PSSLContext * sslContext;
01242 };
01243
01244 typedef OpalInternalIPTransportTemplate<OpalListenerTCPS, OpalTransportTCPS, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPSTransport;
01245
01246
01247 #endif // OPAL_PTLIB_SSL
01248
01249
01250 #endif // __OPAL_TRANSPORT_H
01251
01252
01253