Leaked source code of windows server 2003
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.

618 lines
13 KiB

  1. #ifndef _RAWCONNECTION_HXX_
  2. #define _RAWCONNECTION_HXX_
  3. #include <streamfilt.h>
  4. #include "w3filter.hxx"
  5. #define RAW_CONNECTION_SIGNATURE (DWORD)'NOCR'
  6. #define RAW_CONNECTION_SIGNATURE_FREE (DWORD)'nocr'
  7. class RAW_CONNECTION_HASH;
  8. class W3_CONNECTION;
  9. class RAW_CONNECTION
  10. {
  11. public:
  12. RAW_CONNECTION(
  13. CONNECTION_INFO * pConnectionInfo
  14. );
  15. virtual ~RAW_CONNECTION();
  16. static
  17. HRESULT
  18. Initialize(
  19. VOID
  20. );
  21. static
  22. VOID
  23. Terminate(
  24. VOID
  25. );
  26. static
  27. HRESULT
  28. StartListening(
  29. VOID
  30. );
  31. static
  32. HRESULT
  33. StopListening(
  34. VOID
  35. );
  36. static
  37. HRESULT
  38. GetConnection(
  39. CONNECTION_INFO * pConnectionInfo,
  40. RAW_CONNECTION ** ppRawConnection
  41. );
  42. static
  43. HRESULT
  44. FindConnection(
  45. HTTP_RAW_CONNECTION_ID ConnectionId,
  46. RAW_CONNECTION ** ppRawConnection
  47. );
  48. static
  49. BOOL
  50. WINAPI
  51. RawFilterServerSupportFunction(
  52. HTTP_FILTER_CONTEXT * pfc,
  53. enum SF_REQ_TYPE SupportFunction,
  54. void * pData,
  55. ULONG_PTR ul,
  56. ULONG_PTR ul2
  57. );
  58. static
  59. BOOL
  60. WINAPI
  61. RawFilterGetServerVariable(
  62. HTTP_FILTER_CONTEXT * pfc,
  63. LPSTR lpszVariableName,
  64. LPVOID lpvBuffer,
  65. LPDWORD lpdwSize
  66. );
  67. static
  68. BOOL
  69. WINAPI
  70. RawFilterWriteClient(
  71. HTTP_FILTER_CONTEXT * pfc,
  72. LPVOID Buffer,
  73. LPDWORD lpdwBytes,
  74. DWORD dwReserved
  75. );
  76. static
  77. VOID *
  78. WINAPI
  79. RawFilterAllocateMemory(
  80. HTTP_FILTER_CONTEXT * pfc,
  81. DWORD cbSize,
  82. DWORD dwReserved
  83. );
  84. static
  85. BOOL
  86. WINAPI
  87. RawFilterAddResponseHeaders(
  88. HTTP_FILTER_CONTEXT * pfc,
  89. LPSTR lpszHeaders,
  90. DWORD dwReserved
  91. );
  92. static
  93. HRESULT
  94. ProcessRawRead(
  95. RAW_STREAM_INFO * pRawStreamInfo,
  96. PVOID pvContext,
  97. BOOL * pfReadMore,
  98. BOOL * pfComplete,
  99. DWORD * pcbNextReadSize
  100. );
  101. static
  102. VOID
  103. ReleaseContext(
  104. PVOID pvContext
  105. );
  106. static
  107. HRESULT
  108. ProcessRawWrite(
  109. RAW_STREAM_INFO * pRawStreamInfo,
  110. PVOID pvContext,
  111. BOOL * pfComplete
  112. );
  113. static
  114. HRESULT
  115. ProcessNewConnection(
  116. CONNECTION_INFO * pConnectionInfo,
  117. PVOID * ppvContext
  118. );
  119. static
  120. VOID
  121. ProcessConnectionClose(
  122. VOID * pvContext
  123. );
  124. HRESULT
  125. NotifyRawReadFilters(
  126. RAW_STREAM_INFO * pRawStreamInfo,
  127. BOOL * pfReadMore,
  128. BOOL * pfComplete
  129. );
  130. HRESULT
  131. NotifyRawWriteFilters(
  132. RAW_STREAM_INFO * pRawStreamInfo,
  133. BOOL * pfComplete,
  134. DWORD dwStartFilter
  135. );
  136. VOID
  137. EnableSkip(
  138. VOID
  139. )
  140. {
  141. _skipLock.WriteLock();
  142. _fSkipAtAll = TRUE;
  143. _skipLock.WriteUnlock();
  144. }
  145. VOID
  146. AddSkippedData(
  147. ULARGE_INTEGER liData
  148. );
  149. BOOL
  150. DetermineSkippedData(
  151. DWORD cbData,
  152. DWORD * pcbOffset
  153. );
  154. HRESULT
  155. SendResponseHeader(
  156. CHAR * pszStatus,
  157. CHAR * pszAdditionalHeaders,
  158. HTTP_FILTER_CONTEXT * pfc
  159. );
  160. HRESULT
  161. NotifyEndOfNetSessionFilters(
  162. VOID
  163. );
  164. VOID
  165. CopyAllocatedFilterMemory(
  166. W3_FILTER_CONTEXT * pFilterContext
  167. );
  168. PVOID
  169. AllocateFilterMemory(
  170. DWORD cbSize
  171. )
  172. {
  173. FILTER_POOL_ITEM * pPoolItem;
  174. pPoolItem = FILTER_POOL_ITEM::CreateMemPoolItem( cbSize );
  175. if ( pPoolItem != NULL )
  176. {
  177. InsertHeadList( &_PoolHead, &(pPoolItem->_ListEntry) );
  178. return pPoolItem->_pvData;
  179. }
  180. return NULL;
  181. }
  182. BOOL
  183. CheckSignature(
  184. VOID
  185. ) const
  186. {
  187. return _dwSignature == RAW_CONNECTION_SIGNATURE;
  188. }
  189. HTTP_RAW_CONNECTION_ID
  190. QueryRawConnectionId(
  191. VOID
  192. ) const
  193. {
  194. return _RawConnectionId;
  195. }
  196. HTTP_RAW_CONNECTION_ID *
  197. QueryRawConnectionIdKey(
  198. VOID
  199. ) const
  200. {
  201. return (HTTP_RAW_CONNECTION_ID*) &_RawConnectionId;
  202. }
  203. W3_MAIN_CONTEXT *
  204. GetAndReferenceMainContext(
  205. VOID
  206. )
  207. {
  208. W3_MAIN_CONTEXT * pMainContext;
  209. _lock.WriteLock();
  210. pMainContext = _pMainContext;
  211. if ( pMainContext != NULL )
  212. {
  213. pMainContext->ReferenceMainContext();
  214. }
  215. _lock.WriteUnlock();
  216. return pMainContext;
  217. }
  218. VOID
  219. SetMainContext(
  220. W3_MAIN_CONTEXT * pNewContext
  221. )
  222. {
  223. _lock.WriteLock();
  224. if ( _pMainContext != NULL )
  225. {
  226. _pMainContext->DereferenceMainContext();
  227. }
  228. if ( pNewContext != NULL )
  229. {
  230. pNewContext->ReferenceMainContext();
  231. }
  232. _pMainContext = pNewContext;
  233. _lock.WriteUnlock();
  234. }
  235. HRESULT
  236. DisableNotification(
  237. DWORD dwNotification
  238. );
  239. HRESULT
  240. AddResponseHeaders(
  241. LPSTR pszAddResponseHeaders
  242. )
  243. {
  244. return _strAddResponseHeaders.Append( pszAddResponseHeaders );
  245. }
  246. HRESULT
  247. AddDenialHeaders(
  248. LPSTR pszAddDenialHeaders
  249. )
  250. {
  251. return _strAddDenialHeaders.Append( pszAddDenialHeaders );
  252. }
  253. VOID
  254. ReferenceRawConnection(
  255. VOID
  256. )
  257. {
  258. LONG cRefs;
  259. cRefs = InterlockedIncrement( &_cRefs );
  260. if ( sm_pTraceLog != NULL )
  261. {
  262. WriteRefTraceLog( sm_pTraceLog,
  263. cRefs,
  264. this );
  265. }
  266. }
  267. VOID
  268. DereferenceRawConnection(
  269. VOID
  270. )
  271. {
  272. LONG cRefs;
  273. cRefs = InterlockedDecrement( &_cRefs );
  274. if ( sm_pTraceLog != NULL )
  275. {
  276. WriteRefTraceLog( sm_pTraceLog,
  277. cRefs,
  278. this );
  279. }
  280. if ( cRefs == 0 )
  281. {
  282. delete this;
  283. }
  284. }
  285. DWORD
  286. QueryNextReadSize(
  287. VOID
  288. ) const
  289. {
  290. return _cbNextReadSize;
  291. }
  292. VOID
  293. SetNextReadSize(
  294. DWORD cbNextReadSize
  295. )
  296. {
  297. _cbNextReadSize = cbNextReadSize;
  298. }
  299. //
  300. // A bunch of functions which need to gate their execution on whether
  301. // or not we have an associated W3_CONNECTION with the this raw connection
  302. //
  303. FILTER_LIST *
  304. QueryFilterList(
  305. VOID
  306. );
  307. BOOL
  308. QueryNotificationChanged(
  309. VOID
  310. );
  311. BOOL
  312. QueryRawConnectionNotificationChanged(
  313. VOID
  314. );
  315. BOOL
  316. IsDisableNotificationNeeded(
  317. DWORD dwFilter,
  318. DWORD dwNotification
  319. );
  320. BOOL
  321. IsRawConnectionDisableNotificationNeeded(
  322. DWORD dwFilter,
  323. DWORD dwNotification
  324. );
  325. PVOID
  326. QueryClientContext(
  327. DWORD dwFilter
  328. );
  329. VOID
  330. SetClientContext(
  331. DWORD dwFilter,
  332. PVOID pvContext
  333. );
  334. VOID
  335. SetLocalClientContext(
  336. DWORD dwFilter,
  337. PVOID pvContext
  338. );
  339. VOID
  340. CopyContextPointers(
  341. W3_FILTER_CONTEXT * pFilterContext
  342. );
  343. HRESULT
  344. CopyHeaders(
  345. W3_FILTER_CONTEXT * pFilterContext
  346. );
  347. HRESULT
  348. GetLimitedServerVariables(
  349. LPSTR pszVariableName,
  350. PVOID pvBuffer,
  351. PDWORD pdwSize
  352. );
  353. static
  354. HRESULT
  355. AssociateW3Connection(
  356. HTTP_RAW_CONNECTION_ID rawConnectionId,
  357. W3_CONNECTION * pW3Connection
  358. );
  359. static
  360. BOOL
  361. QueryDoReadRawFiltering(
  362. VOID
  363. )
  364. {
  365. return sm_fNotifyRawReadData;
  366. }
  367. private:
  368. DWORD _dwSignature;
  369. LONG _cRefs;
  370. //
  371. // Filter opaque contexts
  372. //
  373. PVOID _rgContexts[ MAX_FILTERS ];
  374. //
  375. // List of pool items allocated by client. These pool items will be
  376. // migrated to the W3_FILTER_CONNECTION_CONTEXT when possible
  377. //
  378. LIST_ENTRY _PoolHead;
  379. //
  380. // The filter descriptor passed to filters
  381. //
  382. HTTP_FILTER_CONTEXT _hfc;
  383. //
  384. // Current filter. This is used to handle WriteClient()s from
  385. // read/write raw data filters
  386. //
  387. DWORD _dwCurrentFilter;
  388. //
  389. // A function/context to call back into stream filter
  390. //
  391. PFN_SEND_DATA_BACK _pfnSendDataBack;
  392. PVOID _pvStreamContext;
  393. //
  394. // Local/remote socket address info
  395. // AF_INET[6], SOCKADDR_IN[6]
  396. //
  397. USHORT _LocalAddressType;
  398. USHORT _RemoteAddressType;
  399. SockAddress _SockLocalAddress;
  400. SockAddress _SockRemoteAddress;
  401. //
  402. // Raw connection id
  403. //
  404. HTTP_RAW_CONNECTION_ID _RawConnectionId;
  405. //
  406. // A response object which is needed if a raw read notification sends
  407. // a response and then expects a send-response notification.
  408. // (triple AAARRRRGGGGHH)
  409. //
  410. W3_RESPONSE _response;
  411. //
  412. // Main context which applies to this connection. There may be several
  413. // during the life of this connection
  414. //
  415. W3_MAIN_CONTEXT * _pMainContext;
  416. //
  417. // Synchronize retrieval of main contexts
  418. //
  419. CSpinLock _lock;
  420. //
  421. // While we haven't associated with a WP request, we need to keep track
  422. // of our own additional response/denial headers
  423. //
  424. STRA _strAddDenialHeaders;
  425. STRA _strAddResponseHeaders;
  426. //
  427. // Next read size (0 means use default size)
  428. //
  429. DWORD _cbNextReadSize;
  430. //
  431. // Disable notifications
  432. //
  433. BOOL _fNotificationsDisabled;
  434. BUFFER _BuffSecureArray;
  435. BUFFER _BuffNonSecureArray;
  436. DWORD _dwSecureNotifications;
  437. DWORD _dwNonSecureNotifications;
  438. //
  439. // For backward compat mode, keep track of whether the worker process
  440. // is handling the given connection by keeping tracking of bytes sent
  441. //
  442. ULARGE_INTEGER _liWorkerProcessData;
  443. BOOL _fSkipAtAll;
  444. CSpinLock _skipLock;
  445. static RAW_CONNECTION_HASH * sm_pRawConnectionHash;
  446. static BOOL sm_fNotifyRawReadData;
  447. static PTRACE_LOG sm_pTraceLog;
  448. };
  449. //
  450. // RAW_CONNECTION_HASH
  451. //
  452. class RAW_CONNECTION_HASH
  453. : public CTypedHashTable<
  454. RAW_CONNECTION_HASH,
  455. RAW_CONNECTION,
  456. ULONGLONG *
  457. >
  458. {
  459. public:
  460. RAW_CONNECTION_HASH()
  461. : CTypedHashTable< RAW_CONNECTION_HASH,
  462. RAW_CONNECTION,
  463. ULONGLONG * > ( "RAW_CONNECTION_HASH" )
  464. {
  465. }
  466. static
  467. ULONGLONG *
  468. ExtractKey(
  469. const RAW_CONNECTION * pRawConnection
  470. )
  471. {
  472. return pRawConnection->QueryRawConnectionIdKey();
  473. }
  474. static
  475. DWORD
  476. CalcKeyHash(
  477. ULONGLONG * ullKey
  478. )
  479. {
  480. return HashBlob( ullKey, sizeof( ULONGLONG ) );
  481. }
  482. static
  483. bool
  484. EqualKeys(
  485. ULONGLONG * ullKey1,
  486. ULONGLONG * ullKey2
  487. )
  488. {
  489. return *ullKey1 == *ullKey2;
  490. }
  491. static
  492. void
  493. AddRefRecord(
  494. RAW_CONNECTION * pEntry,
  495. int nIncr
  496. )
  497. {
  498. if ( nIncr == +1 )
  499. {
  500. pEntry->ReferenceRawConnection();
  501. }
  502. else if ( nIncr == -1 )
  503. {
  504. pEntry->DereferenceRawConnection();
  505. }
  506. }
  507. };
  508. #endif