OPAL Version 3.10.2
|
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: 26231 $ 00032 * $Author: rjongbloed $ 00033 * $Date: 2011-07-19 21:23:34 -0500 (Tue, 19 Jul 2011) $ 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 00149 class OpalTransportAddress : public PCaselessString 00150 { 00151 PCLASSINFO(OpalTransportAddress, PCaselessString); 00152 public: 00155 OpalTransportAddress(); 00156 OpalTransportAddress( 00157 const char * address, 00158 WORD port = 0, 00159 const char * proto = NULL 00160 ); 00161 OpalTransportAddress( 00162 const PString & address, 00163 WORD port = 0, 00164 const char * proto = NULL 00165 ); 00166 OpalTransportAddress( 00167 const PIPSocket::Address & ip, 00168 WORD port, 00169 const char * proto = NULL 00170 ); 00172 00180 PBoolean IsEquivalent( 00181 const OpalTransportAddress & address, 00182 bool wildcards = false 00183 ) const; 00184 00187 PBoolean IsCompatible( 00188 const OpalTransportAddress & address 00189 ) const; 00190 00193 PCaselessString GetProto(bool withDollar = false) const { return Left(Find('$')+(withDollar?1:0)); } 00194 00198 PBoolean GetIpAddress(PIPSocket::Address & ip) const; 00199 00203 PBoolean GetIpAndPort(PIPSocket::Address & ip, WORD & port) const; 00204 PBoolean GetIpAndPort(PIPSocketAddressAndPort & ipPort) const; 00205 00209 virtual PString GetHostName() const; 00210 00211 enum BindOptions { 00212 NoBinding, 00213 HostOnly, 00214 FullTSAP, 00215 Streamed, 00216 Datagram, 00217 RouteInterface, 00218 NumBindOptions 00219 }; 00220 00252 OpalListener * CreateListener( 00253 OpalEndPoint & endpoint, 00254 BindOptions option 00255 ) const; 00256 00284 virtual OpalTransport * CreateTransport( 00285 OpalEndPoint & endpoint, 00286 BindOptions option = HostOnly 00287 ) const; 00289 00290 00291 protected: 00292 void SetInternalTransport( 00293 WORD port, 00294 const char * proto 00295 ); 00296 00297 OpalInternalTransport * transport; 00298 }; 00299 00300 00301 PDECLARE_ARRAY(OpalTransportAddressArray, OpalTransportAddress) 00302 public: 00303 OpalTransportAddressArray( 00304 const OpalTransportAddress & address 00305 ) { AppendAddress(address); } 00306 OpalTransportAddressArray( 00307 const PStringArray & array 00308 ) { AppendStringCollection(array); } 00309 OpalTransportAddressArray( 00310 const PStringList & list 00311 ) { AppendStringCollection(list); } 00312 OpalTransportAddressArray( 00313 const PSortedStringList & list 00314 ) { AppendStringCollection(list); } 00315 00316 void AppendString( 00317 const char * address 00318 ); 00319 void AppendString( 00320 const PString & address 00321 ); 00322 void AppendAddress( 00323 const OpalTransportAddress & address 00324 ); 00325 00326 protected: 00327 void AppendStringCollection( 00328 const PCollection & coll 00329 ); 00330 }; 00331 00332 00333 00334 00336 00349 class OpalListener : public PObject 00350 { 00351 PCLASSINFO(OpalListener, PObject); 00352 public: 00357 OpalListener( 00358 OpalEndPoint & endpoint 00359 ); 00361 00366 void PrintOn( 00367 ostream & strm 00368 ) const; 00370 00373 enum ThreadMode { 00374 SpawnNewThreadMode, 00375 HandOffThreadMode, 00376 SingleThreadMode 00377 }; 00378 00393 virtual PBoolean Open( 00394 const PNotifier & acceptHandler, 00395 ThreadMode mode = SpawnNewThreadMode 00396 ) = 0; 00397 00400 virtual PBoolean IsOpen() = 0; 00401 00404 virtual void Close() = 0; 00405 00408 virtual OpalTransport * Accept( 00409 const PTimeInterval & timeout 00410 ) = 0; 00411 00414 virtual OpalTransport * CreateTransport( 00415 const OpalTransportAddress & localAddress, 00416 const OpalTransportAddress & remoteAddress 00417 ) const = 0; 00418 00424 virtual OpalTransportAddress GetLocalAddress( 00425 const OpalTransportAddress & remoteAddress = OpalTransportAddress() 00426 ) const = 0; 00427 00430 void CloseWait(); 00431 00435 void CleanUpOnTermination() { CloseWait(); } 00437 00438 00439 protected: 00448 PDECLARE_NOTIFIER(PThread, OpalListener, ListenForConnections); 00449 PBoolean StartThread( 00450 const PNotifier & acceptHandler, 00451 ThreadMode mode 00452 ); 00453 00454 OpalEndPoint & endpoint; 00455 PThread * thread; 00456 PNotifier acceptHandler; 00457 ThreadMode threadMode; 00458 }; 00459 00460 00461 PLIST(OpalListenerList, OpalListener); 00462 00463 00464 class OpalListenerIP : public OpalListener 00465 { 00466 PCLASSINFO(OpalListenerIP, OpalListener); 00467 public: 00472 OpalListenerIP( 00473 OpalEndPoint & endpoint, 00474 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 00475 WORD port = 0, 00476 PBoolean exclusive = true 00477 ); 00478 OpalListenerIP( 00479 OpalEndPoint & endpoint, 00480 const OpalTransportAddress & binding, 00481 OpalTransportAddress::BindOptions option 00482 ); 00484 00492 virtual OpalTransportAddress GetLocalAddress( 00493 const OpalTransportAddress & remoteAddress = OpalTransportAddress() 00494 ) const; 00496 00499 WORD GetListenerPort() const { return listenerPort; } 00500 00501 virtual const char * GetProtoPrefix() const = 0; 00503 00504 00505 protected: 00506 PIPSocket::Address localAddress; 00507 WORD listenerPort; 00508 PBoolean exclusiveListener; 00509 }; 00510 00511 00512 class OpalListenerTCP : public OpalListenerIP 00513 { 00514 PCLASSINFO(OpalListenerTCP, OpalListenerIP); 00515 public: 00520 OpalListenerTCP( 00521 OpalEndPoint & endpoint, 00522 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 00523 WORD port = 0, 00524 PBoolean exclusive = true 00525 ); 00526 OpalListenerTCP( 00527 OpalEndPoint & endpoint, 00528 const OpalTransportAddress & binding, 00529 OpalTransportAddress::BindOptions option 00530 ); 00531 00534 ~OpalListenerTCP(); 00536 00559 virtual PBoolean Open( 00560 const PNotifier & acceptHandler, 00561 ThreadMode mode = SpawnNewThreadMode 00562 ); 00563 00566 virtual PBoolean IsOpen(); 00567 00570 virtual void Close(); 00571 00574 virtual OpalTransport * Accept( 00575 const PTimeInterval & timeout 00576 ); 00577 00580 virtual OpalTransport * CreateTransport( 00581 const OpalTransportAddress & localAddress, 00582 const OpalTransportAddress & remoteAddress 00583 ) const; 00585 00586 00587 protected: 00588 virtual const char * GetProtoPrefix() const; 00589 00590 PTCPSocket listener; 00591 }; 00592 00593 00594 class OpalListenerUDP : public OpalListenerIP 00595 { 00596 PCLASSINFO(OpalListenerUDP, OpalListenerIP); 00597 public: 00602 OpalListenerUDP( 00603 OpalEndPoint & endpoint, 00604 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 00605 WORD port = 0, 00606 PBoolean exclusive = true 00607 ); 00608 OpalListenerUDP( 00609 OpalEndPoint & endpoint, 00610 const OpalTransportAddress & binding, 00611 OpalTransportAddress::BindOptions option 00612 ); 00613 00616 ~OpalListenerUDP(); 00618 00641 virtual PBoolean Open( 00642 const PNotifier & acceptHandler, 00643 ThreadMode mode = SpawnNewThreadMode 00644 ); 00645 00648 virtual PBoolean IsOpen(); 00649 00652 virtual void Close(); 00653 00656 virtual OpalTransport * Accept( 00657 const PTimeInterval & timeout 00658 ); 00659 00662 virtual OpalTransport * CreateTransport( 00663 const OpalTransportAddress & localAddress, 00664 const OpalTransportAddress & remoteAddress 00665 ) const; 00666 00672 virtual OpalTransportAddress GetLocalAddress( 00673 const OpalTransportAddress & remoteAddress = OpalTransportAddress() 00674 ) const; 00676 00681 void SetBufferSize( 00682 PINDEX size 00683 ) { m_bufferSize = size; } 00685 00686 00687 protected: 00688 virtual const char * GetProtoPrefix() const; 00689 00690 PMonitoredSocketsPtr listenerBundle; 00691 PINDEX m_bufferSize; 00692 }; 00693 00694 00696 00701 class OpalTransport : public PIndirectChannel 00702 { 00703 PCLASSINFO(OpalTransport, PIndirectChannel); 00704 public: 00709 OpalTransport(OpalEndPoint & endpoint); 00710 00713 ~OpalTransport(); 00715 00720 void PrintOn( 00721 ostream & strm 00722 ) const; 00724 00729 virtual PBoolean IsReliable() const = 0; 00730 00737 virtual PString GetInterface() const; 00738 00745 virtual bool SetInterface( 00746 const PString & iface 00747 ); 00748 00751 virtual OpalTransportAddress GetLocalAddress( 00752 bool allowNAT = true 00753 ) const = 0; 00754 00759 virtual PBoolean SetLocalAddress( 00760 const OpalTransportAddress & address 00761 ) = 0; 00762 00765 virtual OpalTransportAddress GetRemoteAddress() const = 0; 00766 00772 virtual PBoolean SetRemoteAddress( 00773 const OpalTransportAddress & address 00774 ) = 0; 00775 00778 virtual PBoolean Connect() = 0; 00779 00782 PBoolean ConnectTo( 00783 const OpalTransportAddress & address 00784 ) { return SetRemoteAddress(address) && Connect(); } 00785 00788 virtual PBoolean Close(); 00789 00792 void CloseWait(); 00793 00797 void CleanUpOnTermination() { CloseWait(); } 00798 00801 virtual PBoolean IsCompatibleTransport( 00802 const OpalTransportAddress & address 00803 ) const = 0; 00804 00806 enum PromisciousModes { 00807 AcceptFromRemoteOnly, 00808 AcceptFromAnyAutoSet, 00809 AcceptFromAny, 00810 NumPromisciousModes 00811 }; 00812 00823 virtual void SetPromiscuous( 00824 PromisciousModes promiscuous 00825 ); 00826 00831 virtual OpalTransportAddress GetLastReceivedAddress() const; 00832 00837 virtual PString GetLastReceivedInterface() const; 00838 00848 virtual PBoolean ReadPDU( 00849 PBYTEArray & packet 00850 ) = 0; 00851 00857 virtual PBoolean WritePDU( 00858 const PBYTEArray & pdu 00859 ) = 0; 00860 00861 typedef PBoolean (*WriteConnectCallback)(OpalTransport & transport, void * userData); 00862 00875 virtual PBoolean WriteConnect( 00876 WriteConnectCallback function, 00877 void * userData 00878 ); 00879 00882 virtual void AttachThread( 00883 PThread * thread 00884 ); 00885 00888 virtual PBoolean IsRunning() const; 00890 00891 OpalEndPoint & GetEndPoint() const { return endpoint; } 00892 00895 virtual const char * GetProtoPrefix() const = 0; 00896 00897 PMutex & GetWriteMutex() { return m_writeMutex; } 00898 00899 protected: 00900 OpalEndPoint & endpoint; 00901 PThread * thread; 00902 PMutex m_writeMutex; 00903 }; 00904 00905 00906 class OpalTransportIP : public OpalTransport 00907 { 00908 PCLASSINFO(OpalTransportIP, OpalTransport); 00909 public: 00914 OpalTransportIP( 00915 OpalEndPoint & endpoint, 00916 PIPSocket::Address binding, 00917 WORD port 00918 ); 00920 00925 virtual OpalTransportAddress GetLocalAddress( 00926 bool allowNAT = true 00927 ) const; 00928 00933 virtual PBoolean SetLocalAddress( 00934 const OpalTransportAddress & address 00935 ); 00936 00939 virtual OpalTransportAddress GetRemoteAddress() const; 00940 00946 virtual PBoolean SetRemoteAddress( 00947 const OpalTransportAddress & address 00948 ); 00949 00951 00952 protected: 00955 virtual const char * GetProtoPrefix() const = 0; 00956 00957 PIPSocket::Address localAddress; // Address of the local interface 00958 WORD localPort; 00959 PIPSocket::Address remoteAddress; // Address of the remote host 00960 WORD remotePort; 00961 }; 00962 00963 00964 class OpalTransportTCP : public OpalTransportIP 00965 { 00966 PCLASSINFO(OpalTransportTCP, OpalTransportIP); 00967 public: 00972 OpalTransportTCP( 00973 OpalEndPoint & endpoint, 00974 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 00975 WORD port = 0, 00976 PBoolean reuseAddr = false 00977 ); 00978 OpalTransportTCP( 00979 OpalEndPoint & endpoint, 00980 PTCPSocket * socket 00981 ); 00982 00984 ~OpalTransportTCP(); 00986 00991 virtual PBoolean IsReliable() const; 00992 00995 virtual PBoolean IsCompatibleTransport( 00996 const OpalTransportAddress & address 00997 ) const; 00998 01001 virtual PBoolean Connect(); 01002 01012 virtual PBoolean ReadPDU( 01013 PBYTEArray & pdu 01014 ); 01015 01021 virtual PBoolean WritePDU( 01022 const PBYTEArray & pdu 01023 ); 01025 01026 01027 protected: 01030 virtual const char * GetProtoPrefix() const; 01031 01041 virtual PBoolean OnOpen(); 01042 01043 01044 PBoolean reuseAddressFlag; 01045 }; 01046 01047 01048 class OpalTransportUDP : public OpalTransportIP 01049 { 01050 PCLASSINFO(OpalTransportUDP, OpalTransportIP); 01051 public: 01056 OpalTransportUDP( 01057 OpalEndPoint & endpoint, 01058 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 01059 WORD port = 0, 01060 bool reuseAddr = false, 01061 bool preOpen = false 01062 ); 01063 01066 OpalTransportUDP( 01067 OpalEndPoint & endpoint, 01068 const PMonitoredSocketsPtr & sockets, 01069 const PString & iface 01070 ); 01071 01073 ~OpalTransportUDP(); 01075 01078 virtual PBoolean Read( 01079 void * buffer, 01080 PINDEX length 01081 ); 01083 01088 virtual PBoolean IsReliable() const; 01089 01092 virtual PBoolean IsCompatibleTransport( 01093 const OpalTransportAddress & address 01094 ) const; 01095 01103 virtual PBoolean Connect(); 01104 01107 virtual PString GetInterface() const; 01108 01115 virtual bool SetInterface( 01116 const PString & iface 01117 ); 01118 01121 virtual OpalTransportAddress GetLocalAddress( 01122 bool allowNAT = true 01123 ) const; 01124 01129 virtual PBoolean SetLocalAddress( 01130 const OpalTransportAddress & address 01131 ); 01132 01138 virtual PBoolean SetRemoteAddress( 01139 const OpalTransportAddress & address 01140 ); 01141 01153 virtual void SetPromiscuous( 01154 PromisciousModes promiscuous 01155 ); 01156 01161 virtual OpalTransportAddress GetLastReceivedAddress() const; 01162 01167 virtual PString GetLastReceivedInterface() const; 01168 01178 virtual PBoolean ReadPDU( 01179 PBYTEArray & packet 01180 ); 01181 01187 virtual PBoolean WritePDU( 01188 const PBYTEArray & pdu 01189 ); 01190 01201 virtual PBoolean WriteConnect( 01202 WriteConnectCallback function, 01203 void * userData 01204 ); 01205 01208 void SetBufferSize( 01209 PINDEX size 01210 ) { m_bufferSize = size; } 01212 01213 protected: 01216 virtual const char * GetProtoPrefix() const; 01217 01218 OpalManager & manager; 01219 PINDEX m_bufferSize; 01220 PBYTEArray m_preReadPacket; 01221 bool m_preReadOK; 01222 01223 friend class OpalListenerUDP; 01224 }; 01225 01226 01228 01229 class OpalInternalTransport : public PObject 01230 { 01231 PCLASSINFO(OpalInternalTransport, PObject); 01232 public: 01233 virtual PString GetHostName( 01234 const OpalTransportAddress & address 01235 ) const; 01236 01237 virtual PBoolean GetIpAndPort( 01238 const OpalTransportAddress & address, 01239 PIPSocket::Address & ip, 01240 WORD & port 01241 ) const; 01242 01243 virtual OpalListener * CreateListener( 01244 const OpalTransportAddress & address, 01245 OpalEndPoint & endpoint, 01246 OpalTransportAddress::BindOptions options 01247 ) const = 0; 01248 01249 virtual OpalTransport * CreateTransport( 01250 const OpalTransportAddress & address, 01251 OpalEndPoint & endpoint, 01252 OpalTransportAddress::BindOptions options 01253 ) const = 0; 01254 }; 01255 01256 01258 01259 class OpalInternalIPTransport : public OpalInternalTransport 01260 { 01261 PCLASSINFO(OpalInternalIPTransport, OpalInternalTransport); 01262 public: 01263 virtual PString GetHostName( 01264 const OpalTransportAddress & address 01265 ) const; 01266 virtual PBoolean GetIpAndPort( 01267 const OpalTransportAddress & address, 01268 PIPSocket::Address & ip, 01269 WORD & port 01270 ) const; 01271 01272 static PBoolean GetAdjustedIpAndPort(const OpalTransportAddress & address, 01273 OpalEndPoint & endpoint, 01274 OpalTransportAddress::BindOptions option, 01275 PIPSocket::Address & ip, 01276 WORD & port, 01277 PBoolean & reuseAddr); 01278 }; 01279 01280 template <class ListenerType, class TransportType, unsigned AltTypeOption, class AltTypeClass> 01281 class OpalInternalIPTransportTemplate : public OpalInternalIPTransport 01282 { 01283 public: 01284 OpalListener * CreateListener( 01285 const OpalTransportAddress & address, 01286 OpalEndPoint & endpoint, 01287 OpalTransportAddress::BindOptions options 01288 ) const 01289 { 01290 return new ListenerType(endpoint, address, options); 01291 } 01292 01293 OpalTransport * CreateTransport( 01294 const OpalTransportAddress & address, 01295 OpalEndPoint & endpoint, 01296 OpalTransportAddress::BindOptions options 01297 ) const 01298 { 01299 PIPSocket::Address ip; 01300 WORD port; 01301 PBoolean reuseAddr; 01302 if (GetAdjustedIpAndPort(address, endpoint, options, ip, port, reuseAddr)) { 01303 if (options == AltTypeOption) 01304 return new AltTypeClass(endpoint, ip, 0, reuseAddr); 01305 else 01306 return new TransportType(endpoint, ip, 0, reuseAddr); 01307 } 01308 return NULL; 01309 } 01310 }; 01311 01312 typedef OpalInternalIPTransportTemplate<OpalListenerTCP, OpalTransportTCP, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPTransport; 01313 typedef OpalInternalIPTransportTemplate<OpalListenerUDP, OpalTransportUDP, OpalTransportAddress::Streamed, OpalTransportTCP> OpalInternalUDPTransport; 01314 01315 #if OPAL_PTLIB_SSL 01316 01317 class PSSLContext; 01318 01319 class OpalListenerTCPS : public OpalListenerTCP 01320 { 01321 PCLASSINFO(OpalListenerTCPS, OpalListenerTCP); 01322 public: 01323 OpalListenerTCPS( 01324 OpalEndPoint & endpoint, 01325 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 01326 WORD port = 0, 01327 PBoolean exclusive = true 01328 ); 01329 OpalListenerTCPS( 01330 OpalEndPoint & endpoint, 01331 const OpalTransportAddress & binding, 01332 OpalTransportAddress::BindOptions option 01333 ); 01334 01337 ~OpalListenerTCPS(); 01338 01339 OpalTransport * Accept(const PTimeInterval & timeout); 01340 const char * GetProtoPrefix() const; 01341 01342 protected: 01343 void Construct(); 01344 01345 PSSLContext * sslContext; 01346 }; 01347 01348 class OpalTransportTCPS : public OpalTransportTCP 01349 { 01350 PCLASSINFO(OpalTransportTCPS, OpalTransportTCP); 01351 public: 01352 OpalTransportTCPS( 01353 OpalEndPoint & endpoint, 01354 PIPSocket::Address binding = PIPSocket::GetDefaultIpAny(), 01355 WORD port = 0, 01356 PBoolean reuseAddr = false 01357 ); 01358 OpalTransportTCPS( 01359 OpalEndPoint & endpoint, 01360 PTCPSocket * socket 01361 ); 01362 01364 ~OpalTransportTCPS(); 01365 01366 PBoolean IsCompatibleTransport(const OpalTransportAddress & address) const; 01367 PBoolean Connect(); 01368 PBoolean OnOpen(); 01369 const char * GetProtoPrefix() const; 01370 01371 protected: 01372 PSSLContext * sslContext; 01373 }; 01374 01375 typedef OpalInternalIPTransportTemplate<OpalListenerTCPS, OpalTransportTCPS, OpalTransportAddress::Datagram, OpalTransportUDP> OpalInternalTCPSTransport; 01376 01377 01378 #endif // OPAL_PTLIB_SSL 01379 01380 01381 #endif // OPAL_OPAL_TRANSPORT_H 01382 01383 01384 // End of File ///////////////////////////////////////////////////////////////