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 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;
00846 WORD localPort;
00847 PIPSocket::Address remoteAddress;
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