1 /* 2 * upnpcp.h 3 * 4 * UPnP NAT Traversal class. 5 * 6 * h323plus library 7 * 8 * Copyright (c) 2009 ISVO (Asia) Pte. Ltd. 9 * 10 * The contents of this file are subject to the Mozilla Public License 11 * Version 1.1 (the "License"); you may not use this file except in 12 * compliance with the License. You may obtain a copy of the License at 13 * http://www.mozilla.org/MPL/ 14 * 15 * Alternatively, the contents of this file may be used under the terms 16 * of the General Public License (the "GNU License"), in which case the 17 * provisions of GNU License are applicable instead of those 18 * above. If you wish to allow use of your version of this file only 19 * under the terms of the GNU License and not to allow others to use 20 * your version of this file under the MPL, indicate your decision by 21 * deleting the provisions above and replace them with the notice and 22 * other provisions required by the GNU License. If you do not delete 23 * the provisions above, a recipient may use your version of this file 24 * under either the MPL or the GNU License." 25 * 26 * Software distributed under the License is distributed on an "AS IS" 27 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 28 * the License for the specific language governing rights and limitations 29 * under the License. 30 * 31 * 32 * The Initial Developer of the Original Code is ISVO (Asia) Pte. Ltd. 33 * 34 * 35 * Contributor(s): ______________________________________. 36 * 37 * $Id$ 38 * 39 * 40 */ 41 42 #ifndef H_UPNP 43 #define H_UPNP 44 45 #include <ptclib/pnat.h> 46 47 #if _MSC_VER 48 #pragma once 49 #endif 50 51 class H323EndPoint; 52 class UPnPThread; 53 class PNatMethod_UPnP : public H323NatMethod 54 { 55 PCLASSINFO(PNatMethod_UPnP,H323NatMethod); 56 57 public: 58 59 /**@name Construction */ 60 //@{ 61 /** Default Contructor 62 */ 63 PNatMethod_UPnP(); 64 65 /** Deconstructor 66 */ 67 ~PNatMethod_UPnP(); 68 //@} 69 70 /**@name General Functions */ 71 //@{ 72 void AttachEndPoint(H323EndPoint * _ep); 73 74 virtual PBoolean GetExternalAddress( 75 PIPSocket::Address & externalAddress, /// External address of router 76 const PTimeInterval & maxAge = 1000 /// Maximum age for caching 77 ); 78 79 /** CreateSocketPair 80 Create the UDP Socket pair (not used) 81 */ CreateSocketPair(PUDPSocket * &,PUDPSocket * &,const PIPSocket::Address &)82 virtual PBoolean CreateSocketPair( 83 PUDPSocket *&,PUDPSocket *&, 84 const PIPSocket::Address &) { return false; } 85 86 /** CreateSocketPair 87 Create the UDP Socket pair 88 */ 89 virtual PBoolean CreateSocketPair( 90 PUDPSocket * & socket1, 91 PUDPSocket * & socket2, 92 const PIPSocket::Address & binding, 93 void * userData 94 ); 95 96 /** Retreive a random port in the allocated port range 97 */ 98 WORD GetRandomPort(); 99 100 /** isAvailable. 101 Returns whether the Nat Method is ready and available in 102 assisting in NAT Traversal. The principal is function is 103 to allow the EP to detect various methods and if a method 104 is detected then this method is available for NAT traversal 105 The Order of adding to the PNstStrategy determines which method 106 is used 107 */ 108 virtual bool IsAvailable(const PIPSocket::Address & ip); 109 110 void SetAvailable(); 111 112 void SetAvailable(const PString & devName); 113 114 virtual void Activate(bool act); 115 116 PBoolean OpenSocket(PUDPSocket & socket, PortInfo & portInfo, const PIPSocket::Address & binding) const; 117 118 #if PTLIB_VER >= 2130 119 static const char * MethodName(); 120 virtual PCaselessString GetMethodName() const; 121 #elif PTLIB_VER > 2120 GetNatMethodName()122 static PString GetNatMethodName() { return "UPnP"; } GetName()123 virtual PString GetName() const 124 { return GetNatMethodName(); } 125 #else GetNatMethodName()126 static PStringList GetNatMethodName() { return PStringArray("UPnP"); } GetName()127 virtual PString GetName() const 128 { return GetNatMethodName()[0]; } 129 #endif 130 131 // All these are virtual and never used. GetServerAddress(PIPSocket::Address & address,WORD & port)132 virtual bool GetServerAddress( 133 PIPSocket::Address & address, ///< Address of server 134 WORD & port ///< Port server is using. 135 ) const { return false; } 136 GetInterfaceAddress(PIPSocket::Address & internalAddress)137 virtual bool GetInterfaceAddress( 138 PIPSocket::Address & internalAddress 139 ) const { return false; } 140 141 virtual PBoolean CreateSocket( 142 PUDPSocket * & socket, 143 const PIPSocket::Address & binding = PIPSocket::GetDefaultIpAny(), 144 WORD localPort = 0 145 ) { return false; } 146 147 virtual RTPSupportTypes GetRTPSupport( 148 PBoolean force = PFalse ///< Force a new check 149 ); 150 //@} 151 152 void SetExtIPAddress(const PString & newAddr); 153 154 PBoolean OnUPnPAvailable(const PString & devName); 155 156 PBoolean CreateUPnPMap(bool pair, const PString & protocol, const PIPSocket::Address & localIP, 157 const WORD & locPort, PIPSocket::Address & extIP , WORD & extPort, PBoolean force = false); 158 159 void RemoveUPnPMap(WORD port, PBoolean udp = true); 160 161 H323EndPoint * GetEndPoint(); 162 163 #if PTLIB_VER >= 2110 GetServer()164 virtual PString GetServer() const { return PString(); } GetServerAddress(PIPSocketAddressAndPort &)165 virtual bool GetServerAddress(PIPSocketAddressAndPort & ) const { return false; } GetNatType(bool)166 virtual NatTypes GetNatType(bool) { return UnknownNat; } GetNatType(const PTimeInterval &)167 virtual NatTypes GetNatType(const PTimeInterval &) { return UnknownNat; } SetServer(const PString &)168 virtual bool SetServer(const PString &) { return false; } Open(const PIPSocket::Address &)169 virtual bool Open(const PIPSocket::Address &) { return false; } 170 virtual bool CreateSocket(BYTE component,PUDPSocket * & socket, 171 const PIPSocket::Address & binding = PIPSocket::GetDefaultIpAny(),WORD localPort = 0) { return false; } SetCredentials(const PString &,const PString &,const PString &)172 virtual void SetCredentials(const PString &, const PString &, const PString &) {} 173 protected: 174 #if PTLIB_VER < 2130 InternalGetNatType(bool,const PTimeInterval &)175 virtual NatTypes InternalGetNatType(bool, const PTimeInterval &) { return UnknownNat; } 176 #endif 177 #if PTLIB_VER >= 2120 InternalCreateSocket(Component component,PObject * context)178 virtual PNATUDPSocket * InternalCreateSocket(Component component, PObject * context) { return NULL; } InternalUpdate()179 virtual void InternalUpdate() {}; 180 #endif 181 #endif 182 183 protected: 184 185 void SetConnectionSockets(PUDPSocket * data, PUDPSocket * control, 186 H323Connection::SessionInformation * info ); 187 188 private: 189 H323EndPoint* ep; 190 UPnPThread* m_pUPnP; 191 192 PIPSocket::Address m_pExtIP; 193 194 PBoolean m_pShutdown; 195 PBoolean available; 196 PBoolean active; 197 }; 198 199 200 #ifndef _WIN32_WCE 201 #if PTLIB_VER > 260 202 PPLUGIN_STATIC_LOAD(UPnP,PNatMethod); 203 #else 204 PWLIB_STATIC_LOAD_PLUGIN(UPnP,PNatMethod); 205 #endif 206 #endif 207 208 209 class UPnPUDPSocket : public H323UDPSocket 210 { 211 PCLASSINFO(UPnPUDPSocket, H323UDPSocket); 212 public: 213 /**@name Construction/Deconstructor */ 214 //@{ 215 /** create a UDP Socket Fully Nat Supported 216 ready for H323plus to Call. 217 */ 218 UPnPUDPSocket(PNatMethod_UPnP * nat); 219 220 /** Deconstructor to reallocate Socket and remove any exiting 221 allocated NAT ports, 222 */ 223 ~UPnPUDPSocket(); 224 225 virtual PBoolean Close(); 226 227 /** Set Masq Address 228 */ 229 void SetMasqAddress(const PIPSocket::Address & ip, WORD port); 230 231 PBoolean GetLocalAddress(Address & addr); 232 233 PBoolean GetLocalAddress(Address & addr, WORD & port); 234 235 //@} 236 237 protected: 238 PNatMethod_UPnP* natMethod; 239 240 PIPSocket::Address extIP; 241 WORD extPort; 242 243 }; 244 245 #endif // H_UPNP 246 247