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.

605 lines
17 KiB

  1. /*++
  2. Copyright (c) 2000-2002 Microsoft Corporation
  3. Module Name:
  4. clientconn.h
  5. Abstract:
  6. This file contains the header defintions for the HTTP.SYS client connection
  7. structures
  8. Author:
  9. Henry Sanders (henrysa) 14-Aug-2000
  10. Revision History:
  11. --*/
  12. #ifndef _CLIENTCONN_H_
  13. #define _CLIENTCONN_H_
  14. //
  15. // Forward references.
  16. //
  17. //
  18. // Private constants.
  19. //
  20. #define CLIENT_CONN_TDI_LIST_MAX 30
  21. //
  22. // Private types.
  23. //
  24. //
  25. // Private prototypes.
  26. //
  27. //
  28. // Public constants
  29. //
  30. //
  31. // Public types
  32. //
  33. //
  34. // Connection flags/state. These flags indicate the current state of a
  35. // connection.
  36. //
  37. // Some of these flags may be simply updated directly. Others require
  38. // UlInterlockedCompareExchange() to avoid race conditions.
  39. //
  40. // The following flags may be updated directly:
  41. //
  42. // AcceptPending - SET in the TDI connection handler, just before the
  43. // accept IRP is returned to the transport. RESET only if the accept
  44. // IRP fails.
  45. //
  46. // The following flags must be updated using UlInterlockedCompareExchange():
  47. //
  48. // AcceptComplete - SET in the accept IRP completion handler if the IRP
  49. // completed successfully. Once this flag is set, the connection must
  50. // be either gracefully disconnected or aborted before the connection
  51. // can be closed or reused.
  52. //
  53. // DisconnectPending - SET just before a graceful disconnect IRP is
  54. // issued.
  55. //
  56. // DisconnectComplete - SET in the graceful disconnect IRP completion
  57. // handler.
  58. //
  59. // AbortPending - SET just before an abortive disconnect IRP is issued.
  60. //
  61. // AbortComplete - SET in the abortive disconnect IRP completion handler.
  62. //
  63. // DisconnectIndicated - SET in the TDI disconnect handler for graceful
  64. // disconnects issued by the remote client.
  65. //
  66. // AbortIndicated - SET in the TDI disconnect handler for abortive
  67. // disconnects issued by the remote client.
  68. //
  69. // CleanupPending - SET when cleanup is begun for a connection. This
  70. // is necessary to know when the final reference to the connection
  71. // can be removed.
  72. //
  73. // CODEWORK: We can get rid of the CleanupPending flag. It is
  74. // only set when either a graceful or abortive disconnect is
  75. // issued, and only tested in UlpRemoveFinalReference(). The
  76. // test in UlpRemoveFinalReference() can just test for either
  77. // (DisconnectPending | AbortPending) instead.
  78. //
  79. // FinalReferenceRemoved - SET when the final (i.e. "connected")
  80. // reference is removed from the connection.
  81. // Note that the flags requiring UlInterlockedCompareExchange() are only SET,
  82. // never RESET. This makes the implementation a bit simpler.
  83. //
  84. // And now a few words about connection management, TDI, and other mysteries.
  85. //
  86. // Some of the more annoying "features" of TDI are related to connection
  87. // management and lifetime. Two of the most onerous issues are:
  88. //
  89. // 1. Knowing when a connection object handle can be closed without
  90. // causing an unwanted connection reset.
  91. //
  92. // 2. Knowing when TDI has given its last indiction on a connection
  93. // so that resources can be released, reused, recycled, whatever.
  94. //
  95. // And, of course, this is further complicated by the inherent asynchronous
  96. // nature of the NT I/O architecture and the parallelism of SMP systems.
  97. //
  98. // There are a few points worth keeping in mind while reading/modifying this
  99. // source code or writing clients of this code:
  100. //
  101. // 1. As soon as an accept IRP is returned from the TDI connection
  102. // handler to the transport, the TDI client must be prepared for
  103. // any incoming indications, including data receive and disconnect.
  104. // In other words, incoming data & disconnect may occur *before* the
  105. // accept IRP actually completes.
  106. //
  107. // 2. A connection is considered "in use" until either both sides have
  108. // gracefully disconnected OR either side has aborted the connection.
  109. // Closing an "in use" connection will usually result in an abortive
  110. // disconnect.
  111. //
  112. // 3. The various flavors of disconnect (initiated by the local server,
  113. // initiated by the remote client, graceful, abortive, etc) may occur
  114. // in any order
  115. //
  116. typedef enum _UC_CONNECTION_STATE
  117. {
  118. /* 0 */ UcConnectStateConnectCleanup,
  119. /* 1 */ UcConnectStateConnectCleanupBegin,
  120. /* 2 */ UcConnectStateConnectIdle,
  121. /* 3 */ UcConnectStateConnectPending,
  122. /* 4 */ UcConnectStateIssueFilterClose, // we send a FIN
  123. /* 5 */ UcConnectStateIssueFilterDisconnect, // we recv a FIN
  124. /* 6 */ UcConnectStateConnectComplete,
  125. /* 7 */ UcConnectStateProxySslConnect,
  126. /* 8 */ UcConnectStateProxySslConnectComplete,
  127. /* 9 */ UcConnectStatePerformingSslHandshake,
  128. /* a */ UcConnectStateConnectReady,
  129. /* b */ UcConnectStateDisconnectIndicatedPending,
  130. /* c */ UcConnectStateDisconnectPending,
  131. /* d */ UcConnectStateDisconnectComplete,
  132. /* e */ UcConnectStateAbortPending
  133. } UC_CONNECTION_STATE;
  134. typedef enum _UC_CONNECTION_WORKER_TYPE
  135. {
  136. UcConnectionPassive,
  137. UcConnectionWorkItem
  138. } UC_CONNECTION_WORKER_TYPE, *PUC_CONNECTION_WORKER_TYPE;
  139. //
  140. // The states of SSL state machine
  141. //
  142. // Informal description:
  143. //
  144. // NoSslState - Every connection is initialized to this state.
  145. //
  146. // ConnectionDelivered - Ssl connection was delivered to the filter by
  147. // completing its accept irp
  148. //
  149. // ServerCertReceived - Certificate was attached to this connection
  150. //
  151. // ValidatingServerCert - Waiting for app's approval of the certificate
  152. //
  153. // HandshakeComplete - OK to send request on this connection
  154. //
  155. typedef enum _UC_SSL_CONNECTION_STATE
  156. {
  157. UcSslStateNoSslState,
  158. UcSslStateConnectionDelivered,
  159. UcSslStateServerCertReceived,
  160. UcSslStateValidatingServerCert,
  161. UcSslStateHandshakeComplete,
  162. UcSslStateConnMaximum
  163. } UC_SSL_CONNECTION_STATE;
  164. //
  165. // This wraps the TDI address object & Connection objects.
  166. //
  167. typedef struct _UC_TDI_OBJECTS
  168. {
  169. LIST_ENTRY Linkage;
  170. UX_TDI_OBJECT ConnectionObject;
  171. UX_TDI_OBJECT AddressObject;
  172. TDI_CONNECTION_INFORMATION TdiInfo;
  173. USHORT ConnectionType; // either TDI_ADDRESS_TYPE_IP or
  174. // TDI_ADDRESS_TYPE_IP6
  175. PIRP pIrp;
  176. UL_IRP_CONTEXT IrpContext;
  177. PUC_CLIENT_CONNECTION pConnection;
  178. } UC_TDI_OBJECTS, *PUC_TDI_OBJECTS;
  179. //
  180. // The structure that represents a TCP connection to us. This
  181. // is a wrapper for the UX_TDI_OBJECT plus some associated state.
  182. //
  183. typedef struct _UC_CLIENT_CONNECTION
  184. {
  185. ULONG Signature; // Structure signature
  186. UL_SPIN_LOCK SpinLock;
  187. ULONG ConnectionIndex; // What is the index of this
  188. // connection on servinfo
  189. LIST_ENTRY PendingRequestList; // List of unsent requests.
  190. LIST_ENTRY SentRequestList; // List of sent but
  191. // uncompleted requests
  192. LIST_ENTRY ProcessedRequestList; // List of requests
  193. // for which we have
  194. // completly processed
  195. // the response.
  196. //
  197. // A back pointer to the server information structure on which this
  198. // connection is linked. We don't explictly reference the server
  199. // information using REFERENCE_SERVER_INFORMATION. This is because
  200. // the server information is implictly referenced by requests, in the
  201. // following fashion. The server information structure is explictly
  202. // referenced by the file object, and the file object won't go away and
  203. // dereference the server information until we complete a cleanup IRP. We
  204. // won't complete the cleanup IRP until all outstanding requests on the
  205. // file object have been completed. Therefore the server information
  206. // pointer in this structure is guaranteed to be valid *only as long as
  207. // there are pending requests queued on this structure*.
  208. //
  209. PUC_PROCESS_SERVER_INFORMATION pServerInfo;
  210. LONG RefCount;
  211. UC_CONNECTION_STATE ConnectionState;
  212. UC_SSL_CONNECTION_STATE SslState;
  213. NTSTATUS ConnectionStatus;
  214. ULONG Flags;
  215. struct {
  216. PUCHAR pBuffer;
  217. ULONG BytesWritten;
  218. ULONG BytesAvailable;
  219. ULONG BytesAllocated;
  220. } MergeIndication;
  221. #if REFERENCE_DEBUG
  222. //
  223. // Private Reference trace log.
  224. //
  225. PTRACE_LOG pTraceLog;
  226. #endif // REFERENCE_DEBUG
  227. PUC_TDI_OBJECTS pTdiObjects;
  228. //
  229. // TDI wants us to pass a TRANSPORT_ADDRESS structure. Make sure that
  230. // we have a structure that can hold a IP4 or IP6 address.
  231. //
  232. union
  233. {
  234. TA_IP_ADDRESS V4Address;
  235. TA_IP6_ADDRESS V6Address;
  236. TRANSPORT_ADDRESS GenericTransportAddress;
  237. } RemoteAddress;
  238. //
  239. // Thread work item for deferred actions.
  240. //
  241. BOOLEAN bWorkItemQueued;
  242. UL_WORK_ITEM WorkItem;
  243. //
  244. // Pointer to a event that will get set when the client
  245. // ref drops to 0.
  246. //
  247. PKEVENT pEvent;
  248. UX_FILTER_CONNECTION FilterInfo;
  249. HTTP_SSL_SERVER_CERT_INFO ServerCertInfo;
  250. LONG NextAddressCount;
  251. PTA_ADDRESS pNextAddress;
  252. } UC_CLIENT_CONNECTION, *PUC_CLIENT_CONNECTION;
  253. #define UC_CLIENT_CONNECTION_SIGNATURE MAKE_SIGNATURE('HCON')
  254. #define UC_CLIENT_CONNECTION_SIGNATURE_X MAKE_FREE_SIGNATURE(\
  255. UC_CLIENT_CONNECTION_SIGNATURE)
  256. #define DEFAULT_REMOTE_ADDR_SIZE MAX(TDI_ADDRESS_LENGTH_IP, \
  257. TDI_ADDRESS_LENGTH_IP6)
  258. #define UC_IS_VALID_CLIENT_CONNECTION(pConnection) \
  259. HAS_VALID_SIGNATURE(pConnection, UC_CLIENT_CONNECTION_SIGNATURE)
  260. #define REFERENCE_CLIENT_CONNECTION(s) \
  261. UcReferenceClientConnection( \
  262. (s) \
  263. REFERENCE_DEBUG_ACTUAL_PARAMS \
  264. )
  265. #define DEREFERENCE_CLIENT_CONNECTION(s) \
  266. UcDereferenceClientConnection( \
  267. (s) \
  268. REFERENCE_DEBUG_ACTUAL_PARAMS \
  269. )
  270. #define UC_CLOSE_CONNECTION(pConn, Abortive, Status) \
  271. do \
  272. { \
  273. UC_WRITE_TRACE_LOG( \
  274. g_pUcTraceLog, \
  275. UC_ACTION_CONNECTION_CLOSE, \
  276. (pConn), \
  277. UlongToPtr(Abortive), \
  278. UlongToPtr((pConn)->ConnectionState), \
  279. UlongToPtr((pConn)->Flags) \
  280. ); \
  281. \
  282. UcCloseConnection((pConn), (Abortive), NULL, NULL, Status); \
  283. } while(FALSE, FALSE)
  284. #define CLIENT_CONN_FLAG_SEND_BUSY 0x00000002
  285. #define CLIENT_CONN_FLAG_FILTER_CLEANUP 0x00000004
  286. #define CLIENT_CONN_FLAG_TDI_ALLOCATE 0x00000008
  287. #define CLIENT_CONN_FLAG_CONNECT_READY 0x00000010
  288. #define CLIENT_CONN_FLAG_ABORT_RECEIVED 0x00000020
  289. #define CLIENT_CONN_FLAG_ABORT_PENDING 0x00000040
  290. #define CLIENT_CONN_FLAG_DISCONNECT_RECEIVED 0x00000080
  291. #define CLIENT_CONN_FLAG_PROXY_SSL_CONNECTION 0x00000100
  292. #define CLIENT_CONN_FLAG_DISCONNECT_COMPLETE 0x00000200
  293. #define CLIENT_CONN_FLAG_ABORT_COMPLETE 0x00000400
  294. #define CLIENT_CONN_FLAG_CONNECT_COMPLETE 0x00000800
  295. #define CLIENT_CONN_FLAG_CLEANUP_PENDED 0x00001000
  296. #define CLIENT_CONN_FLAG_FILTER_CLOSED 0x00002000
  297. #define CLIENT_CONN_FLAG_RECV_BUSY 0x00008000
  298. //
  299. // Private prototypes.
  300. //
  301. NTSTATUS
  302. UcpOpenTdiObjects(
  303. IN PUC_TDI_OBJECTS pTdiObjects
  304. );
  305. NTSTATUS
  306. UcpAllocateTdiObject(
  307. OUT PUC_TDI_OBJECTS *ppTdiObjects,
  308. IN USHORT AddressType
  309. );
  310. VOID
  311. UcpFreeTdiObject(
  312. IN PUC_TDI_OBJECTS pTdiObjects
  313. );
  314. PUC_TDI_OBJECTS
  315. UcpPopTdiObject(
  316. IN USHORT AddressType
  317. );
  318. VOID
  319. UcpPushTdiObject(
  320. IN PUC_TDI_OBJECTS pTdiObjects,
  321. IN USHORT AddressType
  322. );
  323. NTSTATUS
  324. UcpCleanupConnection(
  325. IN PUC_CLIENT_CONNECTION pConnection,
  326. IN KIRQL OldIrql,
  327. IN BOOLEAN Final
  328. );
  329. VOID
  330. UcpCancelPendingRequest(
  331. PDEVICE_OBJECT pDeviceObject,
  332. PIRP Irp
  333. );
  334. VOID
  335. UcpCancelConnectingRequest(
  336. PDEVICE_OBJECT pDeviceObject,
  337. PIRP Irp
  338. );
  339. NTSTATUS
  340. UcpInitializeConnection(
  341. IN PUC_CLIENT_CONNECTION pConnection,
  342. IN PUC_PROCESS_SERVER_INFORMATION pInfo
  343. );
  344. NTSTATUS
  345. UcpAssociateClientConnection(
  346. IN PUC_CLIENT_CONNECTION pUcConnection
  347. );
  348. VOID
  349. UcpTerminateClientConnectionsHelper(
  350. IN USHORT AddressType
  351. );
  352. VOID
  353. UcpRestartEntityMdlSend(
  354. IN PVOID pCompletionContext,
  355. IN NTSTATUS Status,
  356. IN ULONG_PTR Information
  357. );
  358. VOID
  359. UcCancelConnectingRequest(
  360. PDEVICE_OBJECT pDeviceObject,
  361. PIRP Irp
  362. );
  363. VOID
  364. UcpConnectionStateMachineWorker(
  365. IN PUL_WORK_ITEM pWorkItem
  366. );
  367. BOOLEAN
  368. UcpCompareServerCert(
  369. IN PUC_CLIENT_CONNECTION pConnection
  370. );
  371. PUC_HTTP_REQUEST
  372. UcpFindRequestToFail(
  373. IN PUC_CLIENT_CONNECTION pConnection
  374. );
  375. //
  376. // Public prototypes
  377. //
  378. NTSTATUS
  379. UcInitializeClientConnections(
  380. VOID
  381. );
  382. VOID
  383. UcTerminateClientConnections(
  384. VOID
  385. );
  386. NTSTATUS
  387. UcOpenClientConnection(
  388. IN PUC_PROCESS_SERVER_INFORMATION pServInfo,
  389. OUT PUC_CLIENT_CONNECTION *pUcConnection
  390. );
  391. VOID
  392. UcReferenceClientConnection(
  393. PVOID pObject
  394. REFERENCE_DEBUG_FORMAL_PARAMS
  395. );
  396. VOID
  397. UcDereferenceClientConnection(
  398. PVOID pObject
  399. REFERENCE_DEBUG_FORMAL_PARAMS
  400. );
  401. NTSTATUS
  402. UcSendRequestOnConnection(
  403. PUC_CLIENT_CONNECTION pConnection,
  404. PUC_HTTP_REQUEST pRequest,
  405. KIRQL OldIrql
  406. );
  407. VOID
  408. UcIssueRequests(
  409. PUC_CLIENT_CONNECTION pConnection,
  410. KIRQL OldIrql
  411. );
  412. BOOLEAN
  413. UcIssueEntities(
  414. PUC_HTTP_REQUEST pRequest,
  415. PUC_CLIENT_CONNECTION pConnection,
  416. PKIRQL OldIrql
  417. );
  418. VOID
  419. UcCleanupConnection(
  420. IN PUC_CLIENT_CONNECTION pConnection,
  421. IN NTSTATUS Status
  422. );
  423. NTSTATUS
  424. UcSendEntityBody(
  425. IN PUC_HTTP_REQUEST pRequest,
  426. IN PUC_HTTP_SEND_ENTITY_BODY pEntity,
  427. IN PIRP pIrp,
  428. IN PIO_STACK_LOCATION pIrpSp,
  429. OUT PBOOLEAN bDontFail,
  430. IN BOOLEAN bLast
  431. );
  432. VOID
  433. UcKickOffConnectionStateMachine(
  434. IN PUC_CLIENT_CONNECTION pConnection,
  435. IN KIRQL OldIrql,
  436. IN UC_CONNECTION_WORKER_TYPE WorkerType
  437. );
  438. ULONG
  439. UcGenerateHttpRawConnectionInfo(
  440. IN PVOID pContext,
  441. IN PUCHAR pKernelBuffer,
  442. IN PVOID pUserBuffer,
  443. IN ULONG OutLength,
  444. IN PUCHAR pBuffer,
  445. IN ULONG InitialLength
  446. );
  447. ULONG
  448. UcComputeHttpRawConnectionLength(
  449. IN PVOID pConnectionContext
  450. );
  451. VOID
  452. UcServerCertificateInstalled(
  453. IN PVOID pConnectionContext,
  454. IN NTSTATUS Status
  455. );
  456. VOID
  457. UcConnectionStateMachine(
  458. IN PUC_CLIENT_CONNECTION pConnection,
  459. IN KIRQL OldIrql
  460. );
  461. VOID
  462. UcRestartClientConnect(
  463. IN PUC_CLIENT_CONNECTION pConnection,
  464. IN NTSTATUS Status
  465. );
  466. VOID
  467. UcRestartMdlSend(
  468. IN PVOID pCompletionContext,
  469. IN NTSTATUS Status,
  470. IN ULONG_PTR Information
  471. );
  472. VOID
  473. UcCancelSentRequest(
  474. PDEVICE_OBJECT pDeviceObject,
  475. PIRP Irp
  476. );
  477. VOID
  478. UcClearConnectionBusyFlag(
  479. IN PUC_CLIENT_CONNECTION pConnection,
  480. IN ULONG Flag,
  481. IN KIRQL OldIrql,
  482. IN BOOLEAN bCloseConnection
  483. );
  484. BOOLEAN
  485. UcpCheckForPipelining(
  486. IN PUC_CLIENT_CONNECTION pConnection
  487. );
  488. NTSTATUS
  489. UcAddServerCertInfoToConnection(
  490. IN PUX_FILTER_CONNECTION pConnection,
  491. IN PHTTP_SSL_SERVER_CERT_INFO pServerCert
  492. );
  493. #endif