Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

338 lines
12 KiB

  1. /***************************************************************************
  2. *
  3. * Copyright (C) 2001-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dpnhpastintfobj.h
  6. *
  7. * Content: Header for DPNHPAST main interface object class.
  8. *
  9. * History:
  10. * Date By Reason
  11. * ======== ======== =========
  12. * 04/16/01 VanceO Split DPNATHLP into DPNHUPNP and DPNHPAST.
  13. *
  14. ***************************************************************************/
  15. //=============================================================================
  16. // Defines
  17. //=============================================================================
  18. #define NETWORKBYTEORDER_INADDR_LOOPBACK 0x0100007f
  19. //=============================================================================
  20. // Macros
  21. //=============================================================================
  22. #define NATHELPPAST_FROM_BILINK(b) (CONTAINING_OBJECT(b, CNATHelpPAST, m_blList))
  23. //=============================================================================
  24. // Typedefs
  25. //=============================================================================
  26. class CNATHelpPAST;
  27. //=============================================================================
  28. // Object flags
  29. //=============================================================================
  30. #define NATHELPPASTOBJ_NOTCREATEDWITHCOM 0x0001 // object was created through non-COM DirectPlayNATHelpCreate function
  31. #define NATHELPPASTOBJ_INITIALIZED 0x0002 // object has been initialized
  32. #define NATHELPPASTOBJ_USEPASTICS 0x0004 // PAST can be used for ICS NAT traversal
  33. #define NATHELPPASTOBJ_USEPASTPFW 0x0008 // PAST can be used for opening Personal Firewall
  34. #define NATHELPPASTOBJ_WINSOCK1 0x0010 // only WinSock 1 functionality is available
  35. #define NATHELPPASTOBJ_DEVICECHANGED 0x0020 // short lived flag that overrides min update server status interval when a device is added or removed
  36. #define NATHELPPASTOBJ_ADDRESSESCHANGED 0x0040 // flag indicating that server status changed since the last time the user checked
  37. #define NATHELPPASTOBJ_PORTREGISTERED 0x0080 // short lived flag that allows remote gateway check when a port has been registered
  38. //=============================================================================
  39. // Structures
  40. //=============================================================================
  41. typedef struct _PAST_RESPONSE_INFO
  42. {
  43. CHAR cVersion;
  44. CHAR cMsgType;
  45. DWORD dwClientID;
  46. DWORD dwMsgID;
  47. DWORD dwBindID;
  48. DWORD dwLeaseTime;
  49. CHAR cTunnelType;
  50. CHAR cPASTMethod;
  51. DWORD dwLocalAddressV4;
  52. CHAR cNumLocalPorts;
  53. WORD awLocalPorts[DPNH_MAX_SIMULTANEOUS_PORTS];
  54. DWORD dwRemoteAddressV4;
  55. CHAR cNumRemotePorts;
  56. WORD awRemotePorts[DPNH_MAX_SIMULTANEOUS_PORTS];
  57. WORD wError;
  58. } PAST_RESPONSE_INFO, * PPAST_RESPONSE_INFO;
  59. //=============================================================================
  60. // WinSock function definitions left out by winsock2.h
  61. //=============================================================================
  62. typedef INT (WSAAPI * LPFN___WSAFDISSET) (SOCKET, fd_set FAR *);
  63. //=============================================================================
  64. // IPHLPAPI function prototypes
  65. //=============================================================================
  66. typedef DWORD (WINAPI *PFN_GETADAPTERSINFO) (PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
  67. typedef DWORD (WINAPI *PFN_GETIPFORWARDTABLE) (PMIB_IPFORWARDTABLE pIpForwardTable, PULONG pdwSize, BOOL bOrder);
  68. typedef DWORD (WINAPI *PFN_GETBESTROUTE) (DWORD dwDestAddr, DWORD dwSourceAddr, PMIB_IPFORWARDROW pBestRoute);
  69. //=============================================================================
  70. // Main interface object class
  71. //=============================================================================
  72. class CNATHelpPAST : public IDirectPlayNATHelp
  73. {
  74. public:
  75. CNATHelpPAST(const BOOL fNotCreatedWithCOM); // constructor
  76. ~CNATHelpPAST(void); // destructor
  77. STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
  78. STDMETHODIMP_(ULONG) AddRef(void);
  79. STDMETHODIMP_(ULONG) Release(void);
  80. STDMETHODIMP Initialize(const DWORD dwFlags);
  81. STDMETHODIMP Close(const DWORD dwFlags);
  82. STDMETHODIMP GetCaps(DPNHCAPS * const pdpnhcaps,
  83. const DWORD dwFlags);
  84. STDMETHODIMP RegisterPorts(const SOCKADDR * const aLocalAddresses,
  85. const DWORD dwAddressesSize,
  86. const DWORD dwNumAddresses,
  87. const DWORD dwLeaseTime,
  88. DPNHHANDLE * const phRegisteredPorts,
  89. const DWORD dwFlags);
  90. STDMETHODIMP GetRegisteredAddresses(const DPNHHANDLE hRegisteredPorts,
  91. SOCKADDR * const paPublicAddresses,
  92. DWORD * const pdwPublicAddressesSize,
  93. DWORD * const pdwAddressTypeFlags,
  94. DWORD * const pdwLeaseTimeRemaining,
  95. const DWORD dwFlags);
  96. STDMETHODIMP DeregisterPorts(const DPNHHANDLE hRegisteredPorts,
  97. const DWORD dwFlags);
  98. STDMETHODIMP QueryAddress(const SOCKADDR * const pSourceAddress,
  99. const SOCKADDR * const pQueryAddress,
  100. SOCKADDR * const pResponseAddress,
  101. const int iAddressesSize,
  102. const DWORD dwFlags);
  103. STDMETHODIMP SetAlertEvent(const HANDLE hEvent, const DWORD dwFlags);
  104. STDMETHODIMP SetAlertIOCompletionPort(const HANDLE hIOCompletionPort,
  105. const DWORD dwCompletionKey,
  106. const DWORD dwNumConcurrentThreads,
  107. const DWORD dwFlags);
  108. STDMETHODIMP ExtendRegisteredPortsLease(const DPNHHANDLE hRegisteredPorts,
  109. const DWORD dwLeaseTime,
  110. const DWORD dwFlags);
  111. HRESULT InitializeObject(void);
  112. void UninitializeObject(void);
  113. CBilink m_blList; // list of all the NATHelper instances in existence
  114. private:
  115. BYTE m_Sig[4]; // debugging signature ('NATH')
  116. LONG m_lRefCount; // reference count for this object
  117. DWORD m_dwFlags; // flags for this object
  118. DNCRITICAL_SECTION m_csLock; // lock preventing simultaneous usage
  119. DWORD m_dwLockThreadID; // ID of thread currently holding the lock
  120. HANDLE m_hAlertEvent; // handle to alert event, if any
  121. HANDLE m_hAlertIOCompletionPort; // handle to alert I/O completion port, if any
  122. DWORD m_dwAlertCompletionKey; // alert completion key to use, if any
  123. CBilink m_blDevices; // list of all IP capable devices
  124. CBilink m_blRegisteredPorts; // list of all the ports registered (may or may not be mapped with a PAST server)
  125. CBilink m_blUnownedPorts; // list of all the registered ports which could not be associated with specific devices
  126. DWORD m_dwLastUpdateServerStatusTime; // last time the server status was updated
  127. DWORD m_dwNextPollInterval; // next GetCaps poll interval to use
  128. DWORD m_dwNumLeases; // number of registered ports which have successfully been leased
  129. DWORD m_dwEarliestLeaseExpirationTime; // time when first registered port lease expires, if there are any
  130. HMODULE m_hIpHlpApiDLL; // handle to iphlpapi.dll, if available
  131. PFN_GETADAPTERSINFO m_pfnGetAdaptersInfo; // pointer to GetAdaptersInfo function
  132. PFN_GETIPFORWARDTABLE m_pfnGetIpForwardTable; // pointer to GetIpForwardTable function
  133. PFN_GETBESTROUTE m_pfnGetBestRoute; // pointer to GetBestRoute function
  134. SOCKET m_sIoctls; // socket being used to submit Ioctls (WinSock2 only) and used for PAST address change checks
  135. WORD m_wIoctlSocketPort; // port of bound Ioctl socket, for PAST address change checks, in network byte order
  136. WSAOVERLAPPED * m_polAddressListChange; // pointer overlapped structure for address list change WSAIoctl call
  137. HMODULE m_hWinSockDLL; // handle to wsock32.dll or ws2_32.dll
  138. LPFN_WSASTARTUP m_pfnWSAStartup; // pointer to WSAStartup function
  139. LPFN_WSACLEANUP m_pfnWSACleanup; // pointer to WSACleanup function
  140. LPFN_WSAGETLASTERROR m_pfnWSAGetLastError; // pointer to WSAGetLastError function
  141. LPFN_SOCKET m_pfnsocket; // pointer to socket function
  142. LPFN_CLOSESOCKET m_pfnclosesocket; // pointer to closesocket function
  143. LPFN_BIND m_pfnbind; // pointer to bind function
  144. LPFN_SETSOCKOPT m_pfnsetsockopt; // pointer to setsockopt function
  145. LPFN_GETSOCKNAME m_pfngetsockname; // pointer to getsockname function
  146. LPFN_SELECT m_pfnselect; // pointer to select function
  147. LPFN___WSAFDISSET m_pfn__WSAFDIsSet; // pointer to __WSAFDIsSet function
  148. LPFN_RECVFROM m_pfnrecvfrom; // pointer to recvfrom function
  149. LPFN_SENDTO m_pfnsendto; // pointer to sendto function
  150. LPFN_GETHOSTNAME m_pfngethostname; // pointer to gethostname function
  151. LPFN_GETHOSTBYNAME m_pfngethostbyname; // pointer to gethostbyname function
  152. LPFN_INET_ADDR m_pfninet_addr; // pointer to inet_addr function
  153. LPFN_WSASOCKETA m_pfnWSASocketA; // pointer to WSASocket function
  154. LPFN_WSAIOCTL m_pfnWSAIoctl; // WinSock2 only, pointer to WSAIoctl function
  155. LPFN_WSAGETOVERLAPPEDRESULT m_pfnWSAGetOverlappedResult; // WinSock2 only, pointer to WSAGetOverlappedResult function
  156. #ifdef DBG
  157. DWORD m_dwNumDeviceAdds; // how many times devices were added
  158. DWORD m_dwNumDeviceRemoves; // how many times devices were removed
  159. DWORD m_dwNumServerFailures; // how many times a UPnP gateway device or PAST server returned a failure or stopped responding and had to be removed
  160. #endif // DBG
  161. inline BOOL IsValidObject(void)
  162. {
  163. if ((this == NULL) || (IsBadWritePtr(this, sizeof(CNATHelpPAST))))
  164. {
  165. return FALSE;
  166. }
  167. if (*((DWORD*) (&this->m_Sig)) != 0x4854414E) // 0x48 0x54 0x41 0x4E = 'HTAN' = 'NATH' in Intel order
  168. {
  169. return FALSE;
  170. }
  171. return TRUE;
  172. };
  173. inline void ResetNextPollInterval(void)
  174. {
  175. //
  176. // Reading this DWORD should be atomic, so no need to hold the
  177. // globals lock.
  178. //
  179. this->m_dwNextPollInterval = g_dwNoActiveNotifyPollInterval;
  180. };
  181. HRESULT TakeLock(void);
  182. void DropLock(void);
  183. HRESULT LoadWinSockFunctionPointers(void);
  184. HRESULT CheckForNewDevices(BOOL * const pfFoundNewDevices);
  185. HRESULT CheckForLocalPASTServerAndRegister(CDevice * const pDevice);
  186. void RemoveAllItems(void);
  187. CDevice * FindMatchingDevice(const SOCKADDR_IN * const psaddrinMatch,
  188. const BOOL fMatchRegPort);
  189. HRESULT RegisterWithLocalPASTServer(CDevice * const pDevice);
  190. HRESULT DeregisterWithPASTServer(CDevice * const pDevice,
  191. const BOOL fRemote);
  192. HRESULT ExtendAllExpiringLeases(void);
  193. HRESULT UpdateServerStatus(void);
  194. HRESULT AssignOrListenPASTPort(CRegisteredPort * const pRegisteredPort,
  195. const BOOL fRemote);
  196. HRESULT FreePASTPort(CRegisteredPort * const pRegisteredPort,
  197. const BOOL fRemote);
  198. HRESULT InternalPASTQueryAddress(CDevice * const pDevice,
  199. const SOCKADDR_IN * const psaddrinQueryAddress,
  200. SOCKADDR_IN * const psaddrinResponseAddress,
  201. const DWORD dwFlags,
  202. const BOOL fRemote);
  203. HRESULT ExtendPASTLease(CRegisteredPort * const pRegisteredPort,
  204. const BOOL fRemote);
  205. HRESULT UpdatePASTPublicAddressValidity(CDevice * const pDevice,
  206. const BOOL fRemote);
  207. HRESULT RegisterAllPortsWithPAST(CDevice * const pDevice,
  208. const BOOL fRemote);
  209. HRESULT RegisterPreviouslyUnownedPortsWithDevice(CDevice * const pDevice,
  210. const BOOL fWildcardToo);
  211. HRESULT ExchangeAndParsePAST(const SOCKET sSocket,
  212. const SOCKADDR * const psaddrServerAddress,
  213. const int iAddressesSize,
  214. const char * const pcRequestBuffer,
  215. const int iRequestBufferSize,
  216. const DWORD dwMsgID,
  217. DWORD * const ptuRetry,
  218. PAST_RESPONSE_INFO * const pRespInfo);
  219. HRESULT RegisterMultipleDevicesWithRemotePAST(CBilink * pSourceList,
  220. CDevice ** ppFirstDeviceWithRemoteServer);
  221. HRESULT ParsePASTMessage(const char * const pcMsg,
  222. const int iMsgSize,
  223. PAST_RESPONSE_INFO * const pRespInfo);
  224. HRESULT RequestLocalAddressListChangeNotification(void);
  225. SOCKET CreatePASTSocket(SOCKADDR_IN * const psaddrinAddress);
  226. BOOL GetAddressToReachGateway(CDevice * const pDevice,
  227. IN_ADDR * const pinaddr);
  228. BOOL IsAddressLocal(CDevice * const pDevice,
  229. const SOCKADDR_IN * const psaddrinAddress);
  230. void ClearDevicesPASTServer(CDevice * const pDevice,
  231. const BOOL fRemote);
  232. void ClearAllPASTServerRegisteredPorts(CDevice * const pDevice,
  233. const BOOL fRemote);
  234. void ExpireOldCachedMappings(void);
  235. static void RemoveAllPASTCachedMappings(CDevice * const pDevice,
  236. const BOOL fRemote);
  237. #ifdef DBG
  238. void DebugPrintCurrentStatus(void);
  239. #endif // DBG
  240. };