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.
525 lines
16 KiB
525 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1998-2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
httpconn.h
|
|
|
|
Abstract:
|
|
|
|
This module contains declarations for manipulation HTTP_CONNECTION
|
|
objects.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 08-Jul-1998
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
/*
|
|
|
|
there is a bit of refcount madness going on. basically, these are the
|
|
object we have.
|
|
|
|
OPAQUE_ID_TABLE
|
|
|
|
|
|
|
|--> UL_INTERNAL_REQUEST
|
|
|
|
|
| o
|
|
| |
|
|
|--> UL_HTTP_CONNECTION
|
|
|
|
|
o
|
|
o
|
|
|
|
|
UL_CONNECTION
|
|
|
|
|
|
there is a circular reference from UL_CONNECTION to UL_HTTP_CONNECTION.
|
|
|
|
the chain that brings down a connection starts with UlConnectionDestroyed
|
|
notifcation which releases the reference from the UL_CONNECTION.
|
|
|
|
at this time the opaque id's are also deleted, releasing their references.
|
|
|
|
when the http_connection refcount hits 0, it releases the reference on the
|
|
UL_CONNECTION and the HTTP_REQUEST's.
|
|
|
|
poof. everyone is gone now.
|
|
|
|
|
|
CODEWORK: think about making hardref's everywhere and adding "letgo"
|
|
terminate methods
|
|
|
|
|
|
*/
|
|
|
|
#ifndef _HTTPCONN_H_
|
|
#define _HTTPCONN_H_
|
|
|
|
|
|
//
|
|
// Zombie connection timer period in seconds. A zombie connection
|
|
// may live; 30 < T < 60 seconds.
|
|
//
|
|
|
|
#define DEFAULT_ZOMBIE_HTTP_CONNECTION_TIMER_PERIOD_IN_SECONDS (30)
|
|
|
|
typedef struct _UL_ZOMBIE_HTTP_CONNECTION_LIST
|
|
{
|
|
LOCKED_LIST_HEAD LockList;
|
|
|
|
//
|
|
// Private timer stuff.
|
|
//
|
|
|
|
KTIMER Timer;
|
|
KDPC DpcObject;
|
|
UL_SPIN_LOCK TimerSpinLock;
|
|
BOOLEAN TimerInitialized;
|
|
UL_WORK_ITEM WorkItem;
|
|
LONG TimerRunning;
|
|
|
|
#ifdef ENABLE_HTTP_CONN_STATS
|
|
//
|
|
// Http connection statistics.
|
|
//
|
|
ULONG MaxZombieCount;
|
|
ULONG TotalCount;
|
|
ULONG TotalZombieCount;
|
|
ULONG TotalZombieRefusal;
|
|
#endif
|
|
|
|
} UL_ZOMBIE_HTTP_CONNECTION_LIST, *PUL_ZOMBIE_HTTP_CONNECTION_LIST;
|
|
|
|
//
|
|
// Refcounted structure to hold the number of conn for each Site.
|
|
// Multiple connections may try to reach to the same entry thru the
|
|
// the corresponding ( means the last request's happening on the connection )
|
|
// cgroup. This entry get allocated when cgroup created with connection
|
|
// limit is enabled.
|
|
//
|
|
|
|
typedef struct _UL_CONNECTION_COUNT_ENTRY {
|
|
|
|
//
|
|
// Signature is UL_CONNECTION_COUNT_ENTRY_POOL_TAG
|
|
//
|
|
|
|
ULONG Signature;
|
|
|
|
//
|
|
// Ref count for this Site Counter Entry
|
|
//
|
|
LONG RefCount;
|
|
|
|
//
|
|
// Current number of connections
|
|
//
|
|
|
|
ULONG CurConnections;
|
|
|
|
//
|
|
// Maximum allowed connections
|
|
//
|
|
|
|
ULONG MaxConnections;
|
|
|
|
} UL_CONNECTION_COUNT_ENTRY, *PUL_CONNECTION_COUNT_ENTRY;
|
|
|
|
#define IS_VALID_CONNECTION_COUNT_ENTRY( entry ) \
|
|
HAS_VALID_SIGNATURE(entry, UL_CONNECTION_COUNT_ENTRY_POOL_TAG)
|
|
|
|
VOID
|
|
UlDereferenceConnectionCountEntry(
|
|
IN PUL_CONNECTION_COUNT_ENTRY pEntry
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
|
|
#define DEREFERENCE_CONNECTION_COUNT_ENTRY( pEntry ) \
|
|
UlDereferenceConnectionCountEntry( \
|
|
(pEntry) \
|
|
REFERENCE_DEBUG_ACTUAL_PARAMS \
|
|
)
|
|
|
|
VOID
|
|
UlReferenceConnectionCountEntry(
|
|
IN PUL_CONNECTION_COUNT_ENTRY pEntry
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
|
|
#define REFERENCE_CONNECTION_COUNT_ENTRY( pEntry ) \
|
|
UlReferenceConnectionCountEntry( \
|
|
(pEntry) \
|
|
REFERENCE_DEBUG_ACTUAL_PARAMS \
|
|
)
|
|
|
|
NTSTATUS
|
|
UlCreateConnectionCountEntry(
|
|
IN OUT PUL_CONFIG_GROUP_OBJECT pConfigGroup,
|
|
IN ULONG MaxConnections
|
|
);
|
|
|
|
ULONG
|
|
UlSetMaxConnections(
|
|
IN OUT PULONG pCurMaxConnection,
|
|
IN ULONG NewMaxConnection
|
|
);
|
|
|
|
ULONG
|
|
UlGetGlobalConnectionLimit(
|
|
VOID
|
|
);
|
|
|
|
NTSTATUS
|
|
UlInitGlobalConnectionLimits(
|
|
VOID
|
|
);
|
|
|
|
BOOLEAN
|
|
UlAcceptConnection(
|
|
IN PULONG pMaxConnection,
|
|
IN OUT PULONG pCurConnection
|
|
);
|
|
|
|
LONG
|
|
UlDecrementConnections(
|
|
IN OUT PULONG pCurConnection
|
|
);
|
|
|
|
BOOLEAN
|
|
UlCheckSiteConnectionLimit(
|
|
IN OUT PUL_HTTP_CONNECTION pConnection,
|
|
IN OUT PUL_URL_CONFIG_GROUP_INFO pConfigInfo
|
|
);
|
|
|
|
BOOLEAN
|
|
UlAcceptGlobalConnection(
|
|
VOID
|
|
);
|
|
|
|
|
|
//
|
|
// function prototypes
|
|
//
|
|
|
|
NTSTATUS
|
|
UlCreateHttpConnection(
|
|
OUT PUL_HTTP_CONNECTION *ppHttpConnection,
|
|
IN PUL_CONNECTION pConnection
|
|
);
|
|
|
|
NTSTATUS
|
|
UlCreateHttpConnectionId(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection
|
|
);
|
|
|
|
VOID
|
|
UlConnectionDestroyedWorker(
|
|
IN PUL_WORK_ITEM pWorkItem
|
|
);
|
|
|
|
NTSTATUS
|
|
UlBindConnectionToProcess(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection,
|
|
IN PUL_APP_POOL_OBJECT pAppPool,
|
|
IN PUL_APP_POOL_PROCESS pProcess
|
|
);
|
|
|
|
PUL_APP_POOL_PROCESS
|
|
UlQueryProcessBinding(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection,
|
|
IN PUL_APP_POOL_OBJECT pAppPool
|
|
);
|
|
|
|
VOID
|
|
UlUnlinkHttpRequest(
|
|
IN PUL_INTERNAL_REQUEST pRequest
|
|
);
|
|
|
|
VOID
|
|
UlCleanupHttpConnection(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection
|
|
);
|
|
|
|
VOID
|
|
UlDeleteHttpConnection(
|
|
IN PUL_WORK_ITEM pWorkItem
|
|
);
|
|
|
|
VOID
|
|
UlReferenceHttpConnection(
|
|
IN PVOID pObject
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
|
|
VOID
|
|
UlDereferenceHttpConnection(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
|
|
#if REFERENCE_DEBUG
|
|
|
|
#define UL_REFERENCE_HTTP_CONNECTION( pconn ) \
|
|
UlReferenceHttpConnection( \
|
|
(pconn) \
|
|
REFERENCE_DEBUG_ACTUAL_PARAMS \
|
|
)
|
|
|
|
#define UL_DEREFERENCE_HTTP_CONNECTION( pconn ) \
|
|
UlDereferenceHttpConnection( \
|
|
(pconn) \
|
|
REFERENCE_DEBUG_ACTUAL_PARAMS \
|
|
)
|
|
|
|
#else // !REFERENCE_DEBUG
|
|
|
|
#define UL_REFERENCE_HTTP_CONNECTION( pconn ) \
|
|
InterlockedIncrement( &( pconn )->RefCount )
|
|
|
|
#define UL_DEREFERENCE_HTTP_CONNECTION( pconn ) \
|
|
if ( InterlockedDecrement( &( pconn )->RefCount ) == 0 ) \
|
|
{ \
|
|
UL_CALL_PASSIVE( \
|
|
&( ( pconn )->WorkItem ), \
|
|
&UlDeleteHttpConnection \
|
|
); \
|
|
} else
|
|
|
|
#endif // !REFERENCE_DEBUG
|
|
|
|
|
|
#define INIT_HTTP_REQUEST(pRequest) \
|
|
do { \
|
|
pRequest->RefCount = 1; \
|
|
\
|
|
pRequest->ParseState = ParseVerbState; \
|
|
\
|
|
InitializeListHead( &pRequest->UnknownHeaderList ); \
|
|
InitializeListHead( &pRequest->IrpHead ); \
|
|
InitializeListHead( &pRequest->ResponseHead ); \
|
|
UlInitializeWorkItem( &pRequest->WorkItem ); \
|
|
\
|
|
pRequest->HeadersAppended = FALSE; \
|
|
\
|
|
pRequest->NextUnknownHeaderIndex = 0; \
|
|
pRequest->UnknownHeaderCount = 0; \
|
|
\
|
|
HTTP_SET_NULL_ID(&pRequest->RequestId); \
|
|
\
|
|
pRequest->RequestIdCopy = pRequest->RequestId; \
|
|
\
|
|
pRequest->HeaderIndex[0] = HttpHeaderRequestMaximum; \
|
|
\
|
|
pRequest->AllocRefBuffers = 1; \
|
|
pRequest->UsedRefBuffers = 0; \
|
|
pRequest->pRefBuffers = pRequest->pInlineRefBuffers; \
|
|
\
|
|
UlInitializeSpinLock( \
|
|
&pRequest->SpinLock, \
|
|
"RequestSpinLock" \
|
|
); \
|
|
\
|
|
pRequest->SendsPending = 0; \
|
|
pRequest->pLogData = NULL; \
|
|
pRequest->pLogDataCopy = NULL; \
|
|
pRequest->LogStatus = STATUS_SUCCESS; \
|
|
\
|
|
UlInitializeUrlInfo(&pRequest->ConfigInfo); \
|
|
\
|
|
RtlZeroMemory( \
|
|
(PUCHAR)pRequest + FIELD_OFFSET(UL_INTERNAL_REQUEST, HeaderValid), \
|
|
sizeof(*pRequest) - FIELD_OFFSET(UL_INTERNAL_REQUEST, HeaderValid) \
|
|
); \
|
|
\
|
|
pRequest->LoadBalancerCapability \
|
|
= HttpLoadBalancerSophisticatedCapability; \
|
|
} while (0, 0)
|
|
|
|
|
|
NTSTATUS
|
|
UlpCreateHttpRequest(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection,
|
|
OUT PUL_INTERNAL_REQUEST *ppRequest
|
|
);
|
|
|
|
VOID
|
|
UlpFreeHttpRequest(
|
|
IN PUL_WORK_ITEM pWorkItem
|
|
);
|
|
|
|
VOID
|
|
UlReferenceHttpRequest(
|
|
IN PVOID pObject
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
|
|
VOID
|
|
UlDereferenceHttpRequest(
|
|
IN PUL_INTERNAL_REQUEST pRequest
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
|
|
|
|
#if REFERENCE_DEBUG
|
|
|
|
#define UL_REFERENCE_INTERNAL_REQUEST( preq ) \
|
|
UlReferenceHttpRequest( \
|
|
(preq) \
|
|
REFERENCE_DEBUG_ACTUAL_PARAMS \
|
|
)
|
|
|
|
#define UL_DEREFERENCE_INTERNAL_REQUEST( preq ) \
|
|
UlDereferenceHttpRequest( \
|
|
(preq) \
|
|
REFERENCE_DEBUG_ACTUAL_PARAMS \
|
|
)
|
|
|
|
#else // !REFERENCE_DEBUG
|
|
|
|
#define UL_REFERENCE_INTERNAL_REQUEST( preq ) \
|
|
InterlockedIncrement( &( preq )->RefCount )
|
|
|
|
#define UL_DEREFERENCE_INTERNAL_REQUEST( preq ) \
|
|
if ( InterlockedDecrement( &( preq )->RefCount ) == 0 ) \
|
|
{ \
|
|
UL_CALL_PASSIVE( \
|
|
&( ( preq )->WorkItem ), \
|
|
&UlpFreeHttpRequest \
|
|
); \
|
|
} else
|
|
|
|
#endif // !REFERENCE_DEBUG
|
|
|
|
|
|
VOID
|
|
UlCancelRequestIo(
|
|
IN PUL_INTERNAL_REQUEST pRequest
|
|
);
|
|
|
|
PUL_REQUEST_BUFFER
|
|
UlCreateRequestBuffer(
|
|
ULONG BufferSize,
|
|
ULONG BufferNumber,
|
|
BOOLEAN UseLookaside
|
|
);
|
|
|
|
VOID
|
|
UlFreeRequestBuffer(
|
|
PUL_REQUEST_BUFFER pBuffer
|
|
);
|
|
|
|
#define UL_REFERENCE_REQUEST_BUFFER( pbuf ) \
|
|
InterlockedIncrement( &( pbuf )->RefCount )
|
|
|
|
#define UL_DEREFERENCE_REQUEST_BUFFER( pbuf ) \
|
|
if ( InterlockedDecrement( &( pbuf )->RefCount ) == 0 ) \
|
|
{ \
|
|
if ((pbuf)->FromLookaside) \
|
|
{ \
|
|
UlPplFreeRequestBuffer( ( pbuf ) ); \
|
|
} \
|
|
else \
|
|
{ \
|
|
UL_FREE_POOL_WITH_SIG( ( pbuf ), UL_REQUEST_BUFFER_POOL_TAG ); \
|
|
} \
|
|
}
|
|
|
|
__inline
|
|
PUL_HTTP_CONNECTION
|
|
UlGetConnectionFromId(
|
|
IN HTTP_CONNECTION_ID ConnectionId
|
|
)
|
|
{
|
|
return (PUL_HTTP_CONNECTION) UlGetObjectFromOpaqueId(
|
|
ConnectionId,
|
|
UlOpaqueIdTypeHttpConnection,
|
|
UlReferenceHttpConnection
|
|
);
|
|
}
|
|
|
|
NTSTATUS
|
|
UlAllocateRequestId(
|
|
IN PUL_INTERNAL_REQUEST pRequest
|
|
);
|
|
|
|
VOID
|
|
UlFreeRequestId(
|
|
IN PUL_INTERNAL_REQUEST pRequest
|
|
);
|
|
|
|
PUL_INTERNAL_REQUEST
|
|
UlGetRequestFromId(
|
|
IN HTTP_REQUEST_ID RequestId,
|
|
IN PUL_APP_POOL_PROCESS pProcess
|
|
);
|
|
|
|
//
|
|
// Zombie connection list stuff
|
|
//
|
|
|
|
NTSTATUS
|
|
UlInitializeHttpConnection(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
UlTerminateHttpConnection(
|
|
VOID
|
|
);
|
|
|
|
typedef
|
|
BOOLEAN
|
|
(*PUL_PURGE_ROUTINE)(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection,
|
|
IN PVOID pPurgeContext
|
|
);
|
|
|
|
VOID
|
|
UlPurgeZombieConnections(
|
|
IN PUL_PURGE_ROUTINE pPurgeRoutine,
|
|
IN PVOID pPurgeContext
|
|
);
|
|
|
|
BOOLEAN
|
|
UlPurgeListeningEndpoint(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection,
|
|
IN PVOID pListeningContext
|
|
);
|
|
|
|
BOOLEAN
|
|
UlPurgeAppPoolProcess(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection,
|
|
IN PVOID pProcessContext
|
|
);
|
|
|
|
VOID
|
|
UlZombieTimerDpcRoutine(
|
|
PKDPC Dpc,
|
|
PVOID DeferredContext,
|
|
PVOID SystemArgument1,
|
|
PVOID SystemArgument2
|
|
);
|
|
|
|
NTSTATUS
|
|
UlLogZombieConnection(
|
|
IN PUL_INTERNAL_REQUEST pRequest,
|
|
IN PUL_HTTP_CONNECTION pHttpConn,
|
|
IN PHTTP_LOG_FIELDS_DATA pUserLogData,
|
|
IN KPROCESSOR_MODE RequestorMode
|
|
);
|
|
|
|
NTSTATUS
|
|
UlDisconnectHttpConnection(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection,
|
|
IN PUL_COMPLETION_ROUTINE pCompletionRoutine,
|
|
IN PVOID pCompletionContext
|
|
);
|
|
|
|
|
|
#endif // _HTTPCONN_H_
|