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