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
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 #ifndef __OPAL_TRANSPORT_H
00165 #define __OPAL_TRANSPORT_H
00166
00167 #ifdef P_USE_PRAGMA
00168 #pragma interface
00169 #endif
00170
00171 #include <opal/buildopts.h>
00172
00173 #include <ptlib/sockets.h>
00174 #include <ptclib/psockbun.h>
00175
00176
00177 class OpalManager;
00178 class OpalEndPoint;
00179 class OpalListener;
00180 class OpalTransport;
00181 class OpalInternalTransport;
00182
00183
00185
00186 class OpalTransportAddress : public PString
00187 {
00188 PCLASSINFO(OpalTransportAddress, PString);
00189 public:
00192 OpalTransportAddress();
00193 OpalTransportAddress(
00194 const char * address,
00195 WORD port = 0,
00196 const char * proto = NULL
00197 );
00198 OpalTransportAddress(
00199 const PString & address,
00200 WORD port = 0,
00201 const char * proto = NULL
00202 );
00203 OpalTransportAddress(
00204 const PIPSocket::Address & ip,
00205 WORD port,
00206 const char * proto = NULL
00207 );
00209
00214 BOOL IsEquivalent(
00215 const OpalTransportAddress & address
00216 ) const;
00217
00220 BOOL IsCompatible(
00221 const OpalTransportAddress & address
00222 ) const;
00223
00227 BOOL GetIpAddress(PIPSocket::Address & ip) const;
00228
00232 BOOL GetIpAndPort(PIPSocket::Address & ip, WORD & port) const;
00233
00237 virtual PString GetHostName() const;
00238
00239 enum BindOptions {
00240 NoBinding,
00241 HostOnly,
00242 FullTSAP,
00243 Streamed,
00244 Datagram,
00245 NumBindOptions
00246 };
00247
00275 OpalListener * CreateListener(
00276 OpalEndPoint & endpoint,
00277 BindOptions option
00278 ) const;
00279
00307 virtual OpalTransport * CreateTransport(
00308 OpalEndPoint & endpoint,
00309 BindOptions option = HostOnly
00310 ) const;
00312
00313
00314 protected:
00315 void SetInternalTransport(
00316 WORD port,
00317 const char * proto
00318 );
00319
00320 OpalInternalTransport * transport;
00321 };
00322
00323
00324 PDECLARE_ARRAY(OpalTransportAddressArray, OpalTransportAddress)
00325 public:
00326 OpalTransportAddressArray(
00327 const OpalTransportAddress & address
00328 ) { AppendAddress(address); }
00329 OpalTransportAddressArray(
00330 const PStringArray & array
00331 ) { AppendStringCollection(array); }
00332 OpalTransportAddressArray(
00333 const PStringList & list
00334 ) { AppendStringCollection(list); }
00335 OpalTransportAddressArray(
00336 const PSortedStringList & list
00337 ) { AppendStringCollection(list); }
00338
00339 void AppendString(
00340 const char * address
00341 );
00342 void AppendString(
00343 const PString & address
00344 );
00345 void AppendAddress(
00346 const OpalTransportAddress & address
00347 );
00348
00349 protected:
00350 void AppendStringCollection(
00351 const PCollection & coll
00352 );
00353 };
00354
00355
00356
00357
00359
00372 class OpalListener : public PObject
00373 {
00374 PCLASSINFO(OpalListener, PObject);
00375 public:
00380 OpalListener(
00381 OpalEndPoint & endpoint
00382 );
00384
00389 void PrintOn(
00390 ostream & strm
00391 ) const;
00393
00396 enum ThreadMode {
00397 SpawnNewThreadMode,
00398 HandOffThreadMode,
00399 SingleThreadMode
00400 };
00401
00416 virtual BOOL Open(
00417 const PNotifier & acceptHandler,
00418 ThreadMode mode = SpawnNewThreadMode
00419 ) = 0;
00420
00423 virtual BOOL IsOpen() = 0;
00424
00427 virtual void Close() = 0;
00428
00431 virtual OpalTransport * Accept(
00432 const PTimeInterval & timeout
00433 ) = 0;
00434
00437 virtual OpalTransport * CreateTransport(
00438 const OpalTransportAddress & localAddress,
00439 const OpalTransportAddress & remoteAddress
00440 ) const = 0;
00441
00444 virtual OpalTransportAddress GetLocalAddress(
00445 const OpalTransportAddress & preferredAddress = OpalTransportAddress()
00446 ) const = 0;
00447
00451 OpalTransportAddress GetTransportAddress() const { return GetLocalAddress(); }
00452
00455 void CloseWait();
00456
00460 void CleanUpOnTermination() { CloseWait(); }
00462
00463
00464 protected:
00473 PDECLARE_NOTIFIER(PThread, OpalListener, ListenForConnections);
00474 BOOL StartThread(
00475 const PNotifier & acceptHandler,
00476 ThreadMode mode
00477 );
00478
00479 OpalEndPoint & endpoint;
00480 PThread * thread;
00481 PNotifier acceptHandler;
00482 ThreadMode threadMode;
00483 };
00484
00485
00486 PLIST(OpalListenerList, OpalListener);
00487
00488
00491 OpalTransportAddressArray OpalGetInterfaceAddresses(
00492 const OpalListenerList & listeners,
00493 BOOL excludeLocalHost = TRUE,
00494 OpalTransport * associatedTransport = NULL
00496 );
00497
00498 OpalTransportAddressArray OpalGetInterfaceAddresses(
00499 const OpalTransportAddress & addr,
00500 BOOL excludeLocalHost = TRUE,
00501 OpalTransport * associatedTransport = NULL
00503 );
00504
00505
00506 class OpalListenerIP : public OpalListener
00507 {
00508 PCLASSINFO(OpalListenerIP, OpalListener);
00509 public:
00514 OpalListenerIP(
00515 OpalEndPoint & endpoint,
00516 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
00517 WORD port = 0,
00518 BOOL exclusive = TRUE
00519 );
00520 OpalListenerIP(
00521 OpalEndPoint & endpoint,
00522 const OpalTransportAddress & binding,
00523 OpalTransportAddress::BindOptions option
00524 );
00526
00531 virtual OpalTransportAddress GetLocalAddress(
00532 const OpalTransportAddress & preferredAddress = OpalTransportAddress()
00533 ) const;
00535
00538 WORD GetListenerPort() const { return listenerPort; }
00539
00540 virtual const char * GetProtoPrefix() const = 0;
00542
00543
00544 protected:
00545 PIPSocket::Address localAddress;
00546 WORD listenerPort;
00547 BOOL exclusiveListener;
00548 };
00549
00550
00551 class OpalListenerTCP : public OpalListenerIP
00552 {
00553 PCLASSINFO(OpalListenerTCP, OpalListenerIP);
00554 public:
00559 OpalListenerTCP(
00560 OpalEndPoint & endpoint,
00561 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
00562 WORD port = 0,
00563 BOOL exclusive = TRUE
00564 );
00565 OpalListenerTCP(
00566 OpalEndPoint & endpoint,
00567 const OpalTransportAddress & binding,
00568 OpalTransportAddress::BindOptions option
00569 );
00570
00573 ~OpalListenerTCP();
00575
00598 virtual BOOL Open(
00599 const PNotifier & acceptHandler,
00600 ThreadMode mode = SpawnNewThreadMode
00601 );
00602
00605 virtual BOOL IsOpen();
00606
00609 virtual void Close();
00610
00613 virtual OpalTransport * Accept(
00614 const PTimeInterval & timeout
00615 );
00616
00619 virtual OpalTransport * CreateTransport(
00620 const OpalTransportAddress & localAddress,
00621 const OpalTransportAddress & remoteAddress
00622 ) const;
00624
00625
00626 protected:
00627 virtual const char * GetProtoPrefix() const;
00628
00629 PTCPSocket listener;
00630 };
00631
00632
00633 class OpalListenerUDP : public OpalListenerIP
00634 {
00635 PCLASSINFO(OpalListenerUDP, OpalListenerIP);
00636 public:
00641 OpalListenerUDP(
00642 OpalEndPoint & endpoint,
00643 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
00644 WORD port = 0,
00645 BOOL exclusive = TRUE
00646 );
00647 OpalListenerUDP(
00648 OpalEndPoint & endpoint,
00649 const OpalTransportAddress & binding,
00650 OpalTransportAddress::BindOptions option
00651 );
00652
00655 ~OpalListenerUDP();
00657
00680 virtual BOOL Open(
00681 const PNotifier & acceptHandler,
00682 ThreadMode mode = SpawnNewThreadMode
00683 );
00684
00687 virtual BOOL IsOpen();
00688
00691 virtual void Close();
00692
00695 virtual OpalTransport * Accept(
00696 const PTimeInterval & timeout
00697 );
00698
00701 virtual OpalTransport * CreateTransport(
00702 const OpalTransportAddress & localAddress,
00703 const OpalTransportAddress & remoteAddress
00704 ) const;
00706
00707
00708 protected:
00709 virtual const char * GetProtoPrefix() const;
00710
00711 PMonitoredSocketsPtr listenerBundle;
00712 };
00713
00714
00716
00721 class OpalTransport : public PIndirectChannel
00722 {
00723 PCLASSINFO(OpalTransport, PIndirectChannel);
00724 public:
00729 OpalTransport(OpalEndPoint & endpoint);
00730
00733 ~OpalTransport();
00735
00740 void PrintOn(
00741 ostream & strm
00742 ) const;
00744
00749 virtual BOOL IsReliable() const = 0;
00750
00753 virtual PString GetInterface() const;
00754
00757 virtual OpalTransportAddress GetLocalAddress() const = 0;
00758
00763 virtual BOOL SetLocalAddress(
00764 const OpalTransportAddress & address
00765 ) = 0;
00766
00769 virtual OpalTransportAddress GetRemoteAddress() const = 0;
00770
00776 virtual BOOL SetRemoteAddress(
00777 const OpalTransportAddress & address
00778 ) = 0;
00779
00782 virtual BOOL Connect() = 0;
00783
00786 BOOL ConnectTo(
00787 const OpalTransportAddress & address
00788 ) { return SetRemoteAddress(address) && Connect(); }
00789
00796 virtual void EndConnect(
00797 const PString & iface
00798 );
00799
00802 virtual BOOL Close();
00803
00806 void CloseWait();
00807
00811 void CleanUpOnTermination() { CloseWait(); }
00812
00815 virtual BOOL IsCompatibleTransport(
00816 const OpalTransportAddress & address
00817 ) const = 0;
00818
00820 enum PromisciousModes {
00821 AcceptFromRemoteOnly,
00822 AcceptFromAnyAutoSet,
00823 AcceptFromAny,
00824 NumPromisciousModes
00825 };
00826
00837 virtual void SetPromiscuous(
00838 PromisciousModes promiscuous
00839 );
00840
00845 virtual OpalTransportAddress GetLastReceivedAddress() const;
00846
00852 virtual BOOL ReadPDU(
00853 PBYTEArray & packet
00854 ) = 0;
00855
00861 virtual BOOL WritePDU(
00862 const PBYTEArray & pdu
00863 ) = 0;
00864
00865 typedef BOOL (*WriteConnectCallback)(OpalTransport & transport, void * userData);
00866
00879 virtual BOOL WriteConnect(
00880 WriteConnectCallback function,
00881 void * userData
00882 );
00883
00886 virtual void AttachThread(
00887 PThread * thread
00888 );
00889
00892 virtual BOOL IsRunning() const;
00894
00895 OpalEndPoint & GetEndPoint() const { return endpoint; }
00896
00897 virtual void SetReadsPerPDU(int) {}
00898
00899 protected:
00900 OpalEndPoint & endpoint;
00901 PThread * thread;
00902 };
00903
00904
00905 class OpalTransportIP : public OpalTransport
00906 {
00907 PCLASSINFO(OpalTransportIP, OpalTransport);
00908 public:
00913 OpalTransportIP(
00914 OpalEndPoint & endpoint,
00915 PIPSocket::Address binding,
00916 WORD port
00917 );
00919
00924 virtual OpalTransportAddress GetLocalAddress() const;
00925
00930 virtual BOOL SetLocalAddress(
00931 const OpalTransportAddress & address
00932 );
00933
00936 virtual OpalTransportAddress GetRemoteAddress() const;
00937
00943 virtual BOOL SetRemoteAddress(
00944 const OpalTransportAddress & address
00945 );
00946
00948
00949 protected:
00952 virtual const char * GetProtoPrefix() const = 0;
00953
00954 PIPSocket::Address localAddress;
00955 WORD localPort;
00956 PIPSocket::Address remoteAddress;
00957 WORD remotePort;
00958 };
00959
00960
00961 class OpalTransportTCP : public OpalTransportIP
00962 {
00963 PCLASSINFO(OpalTransportTCP, OpalTransportIP);
00964 public:
00969 OpalTransportTCP(
00970 OpalEndPoint & endpoint,
00971 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
00972 WORD port = 0,
00973 BOOL reuseAddr = FALSE
00974 );
00975 OpalTransportTCP(
00976 OpalEndPoint & endpoint,
00977 PTCPSocket * socket
00978 );
00979
00981 ~OpalTransportTCP();
00983
00988 virtual BOOL IsReliable() const;
00989
00992 virtual BOOL IsCompatibleTransport(
00993 const OpalTransportAddress & address
00994 ) const;
00995
00998 virtual BOOL Connect();
00999
01005 virtual BOOL ReadPDU(
01006 PBYTEArray & pdu
01007 );
01008
01014 virtual BOOL WritePDU(
01015 const PBYTEArray & pdu
01016 );
01018
01019
01020 protected:
01023 virtual const char * GetProtoPrefix() const;
01024
01034 virtual BOOL OnOpen();
01035
01036
01037 BOOL reuseAddressFlag;
01038 };
01039
01040
01041 class OpalTransportUDP : public OpalTransportIP
01042 {
01043 PCLASSINFO(OpalTransportUDP, OpalTransportIP);
01044 public:
01049 OpalTransportUDP(
01050 OpalEndPoint & endpoint,
01051 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
01052 WORD port = 0,
01053 BOOL reuseAddr = FALSE
01054 );
01055
01058 OpalTransportUDP(
01059 OpalEndPoint & endpoint,
01060 const PBYTEArray & preReadPacket,
01061 const PMonitoredSocketsPtr & sockets,
01062 const PString & iface,
01063 PIPSocket::Address remoteAddress,
01064 WORD remotePort
01065 );
01066
01068 ~OpalTransportUDP();
01070
01073 virtual BOOL Read(
01074 void * buffer,
01075 PINDEX length
01076 );
01078
01083 virtual BOOL IsReliable() const;
01084
01087 virtual BOOL IsCompatibleTransport(
01088 const OpalTransportAddress & address
01089 ) const;
01090
01098 virtual BOOL Connect();
01099
01107 virtual void EndConnect(
01108 const PString & iface
01109 );
01110
01113 virtual PString GetInterface() const;
01114
01117 virtual OpalTransportAddress GetLocalAddress() const;
01118
01123 virtual BOOL SetLocalAddress(
01124 const OpalTransportAddress & address
01125 );
01126
01132 virtual BOOL SetRemoteAddress(
01133 const OpalTransportAddress & address
01134 );
01135
01147 virtual void SetPromiscuous(
01148 PromisciousModes promiscuous
01149 );
01150
01155 virtual OpalTransportAddress GetLastReceivedAddress() const;
01156
01162 virtual BOOL ReadPDU(
01163 PBYTEArray & packet
01164 );
01165
01171 virtual BOOL WritePDU(
01172 const PBYTEArray & pdu
01173 );
01174
01185 virtual BOOL WriteConnect(
01186 WriteConnectCallback function,
01187 void * userData
01188 );
01190
01191 virtual void SetReadsPerPDU(int v) { readsPerPdu = v; }
01192
01193 protected:
01196 virtual const char * GetProtoPrefix() const;
01197
01198 OpalManager & manager;
01199 PBYTEArray preReadPacket;
01200 int readsPerPdu;
01201 };
01202
01203
01205
01206 class OpalInternalTransport : public PObject
01207 {
01208 PCLASSINFO(OpalInternalTransport, PObject);
01209 public:
01210 virtual PString GetHostName(
01211 const OpalTransportAddress & address
01212 ) const;
01213
01214 virtual BOOL GetIpAndPort(
01215 const OpalTransportAddress & address,
01216 PIPSocket::Address & ip,
01217 WORD & port
01218 ) const;
01219
01220 virtual OpalListener * CreateListener(
01221 const OpalTransportAddress & address,
01222 OpalEndPoint & endpoint,
01223 OpalTransportAddress::BindOptions options
01224 ) const = 0;
01225
01226 virtual OpalTransport * CreateTransport(
01227 const OpalTransportAddress & address,
01228 OpalEndPoint & endpoint,
01229 OpalTransportAddress::BindOptions options
01230 ) const = 0;
01231 };
01232
01233
01235
01236 class OpalInternalIPTransport : public OpalInternalTransport
01237 {
01238 PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport);
01239 public:
01240 virtual PString GetHostName(
01241 const OpalTransportAddress & address
01242 ) const;
01243 virtual BOOL GetIpAndPort(
01244 const OpalTransportAddress & address,
01245 PIPSocket::Address & ip,
01246 WORD & port
01247 ) const;
01248
01249 static BOOL GetAdjustedIpAndPort(const OpalTransportAddress & address,
01250 OpalEndPoint & endpoint,
01251 OpalTransportAddress::BindOptions option,
01252 PIPSocket::Address & ip,
01253 WORD & port,
01254 BOOL & reuseAddr);
01255 };
01256
01257 template <class ListenerType, class TransportType, unsigned AltTypeOption, class AltTypeClass>
01258 class OpalInternalIPTransportTemplate : public OpalInternalIPTransport
01259 {
01260 public:
01261 OpalListener * CreateListener(
01262 const OpalTransportAddress & address,
01263 OpalEndPoint & endpoint,
01264 OpalTransportAddress::BindOptions options
01265 ) const
01266 {
01267 return new ListenerType(endpoint, address, options);
01268 }
01269
01270 OpalTransport * CreateTransport(
01271 const OpalTransportAddress & address,
01272 OpalEndPoint & endpoint,
01273 OpalTransportAddress::BindOptions options
01274 ) const
01275 {
01276 PIPSocket::Address ip;
01277 WORD port;
01278 BOOL reuseAddr;
01279 if (GetAdjustedIpAndPort(address, endpoint, options, ip, port, reuseAddr)) {
01280 if (options == AltTypeOption)
01281 return new AltTypeClass(endpoint, ip, 0, reuseAddr);
01282 else
01283 return new TransportType(endpoint, ip, 0, reuseAddr);
01284 }
01285 return NULL;
01286 }
01287 };
01288
01289 typedef OpalInternalIPTransportTemplate<OpalListenerTCP, OpalTransportTCP, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPTransport;
01290 typedef OpalInternalIPTransportTemplate<OpalListenerUDP, OpalTransportUDP, OpalTransportAddress::Streamed, OpalTransportTCP> OpalInternalUDPTransport;
01291
01292 #if P_SSL
01293
01294 class PSSLContext;
01295
01296 class OpalListenerTCPS : public OpalListenerTCP
01297 {
01298 PCLASSINFO(OpalListenerTCPS, OpalListenerTCP);
01299 public:
01300 OpalListenerTCPS(
01301 OpalEndPoint & endpoint,
01302 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
01303 WORD port = 0,
01304 BOOL exclusive = TRUE
01305 );
01306 OpalListenerTCPS(
01307 OpalEndPoint & endpoint,
01308 const OpalTransportAddress & binding,
01309 OpalTransportAddress::BindOptions option
01310 );
01311
01314 ~OpalListenerTCPS();
01315
01316 OpalTransport * Accept(const PTimeInterval & timeout);
01317 const char * GetProtoPrefix() const;
01318
01319 protected:
01320 void Construct();
01321
01322 PSSLContext * sslContext;
01323 };
01324
01325 class OpalTransportTCPS : public OpalTransportTCP
01326 {
01327 PCLASSINFO(OpalTransportTCPS, OpalTransportTCP);
01328 public:
01329 OpalTransportTCPS(
01330 OpalEndPoint & endpoint,
01331 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(),
01332 WORD port = 0,
01333 BOOL reuseAddr = FALSE
01334 );
01335 OpalTransportTCPS(
01336 OpalEndPoint & endpoint,
01337 PTCPSocket * socket
01338 );
01339
01341 ~OpalTransportTCPS();
01342
01343 BOOL IsCompatibleTransport(const OpalTransportAddress & address) const;
01344 BOOL Connect();
01345 BOOL OnOpen();
01346 const char * GetProtoPrefix() const;
01347
01348 protected:
01349 PSSLContext * sslContext;
01350 };
01351
01352 typedef OpalInternalIPTransportTemplate<OpalListenerTCPS, OpalTransportTCPS, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPSTransport;
01353
01354
01355 #endif // P_SSL
01356
01357
01358 #endif // __OPAL_TRANSPORT_H
01359
01360
01361