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.
|
|
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation
//
// FILE
//
// radproxyp.h
//
// SYNOPSIS
//
// Declares classes that are used in the implementation of RadiusProxy, but
// need not be visible to clients.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef RADPROXYP_H
#define RADPROXYP_H
#if _MSC_VER >= 1000
#pragma once
#endif
#include <radpack.h>
#include <radproxy.h>
#include <timerq.h>
///////////////////////////////////////////////////////////////////////////////
//
// CLASS
//
// ProxyContext
//
// DESCRIPTION
//
// Allows a request context to be shared by several Requests only one
// of which will eventually take ownership.
//
///////////////////////////////////////////////////////////////////////////////
class ProxyContext { public: ProxyContext(PVOID p) throw () : context(p) { }
DECLARE_REFERENCE_COUNT();
// Each context has an associated 'primary' server. This is the server that
// will be used for event reporting if no one takes ownership of the
// context.
RemoteServer* getPrimaryServer() const throw() { return primary; } void setPrimaryServer(RemoteServer* server) throw () { primary = server; }
// Take ownership of the context. This will return NULL if someone has beat
// you to it. If the caller is successful, he MUST ensure that
// RadiusProxyClient::onComplete is always invoked exactly once.
PVOID takeOwnership() throw () { return InterlockedExchangePointer(&context, NULL); }
private: PVOID context; RemoteServerPtr primary;
~ProxyContext() throw ();
// Not implemented.
ProxyContext(const ProxyContext&); ProxyContext& operator=(const ProxyContext&); };
typedef ObjectPointer<ProxyContext> ProxyContextPtr;
class RequestStack;
///////////////////////////////////////////////////////////////////////////////
//
// CLASS
//
// Request
//
// DESCRIPTION
//
// Stores the state associated with a pending RADIUS request.
//
///////////////////////////////////////////////////////////////////////////////
class Request : public HashTableEntry, public Timer { public: Request( ProxyContext* context, RemoteServer* destination, BYTE packetCode ) throw ();
//////////
// Various accessors. There is a lot of state associated with a request.
//////////
const BYTE* getAuthenticator() const throw () { return authenticator; }
BYTE getCode() const throw () { return code; }
ProxyContext& getContext() const throw () { return *ctxt; }
// The RADIUS packet identifier for this request.
BYTE getIdentifier() const throw () { return identifier; }
void setPacket(const RadiusPacket& packet);
RadiusPortType getPortType() const throw () { return isAccReq() ? portAuthentication : portAccounting; }
const RemotePort& getPort() const throw () { return port(); }
// The unique ID used to identify this request internally. This is not the
// same as the identifier sent on the wire.
LONG getRequestID() const throw () { return id; }
// Returns the round trip time in hundredths of a second.
ULONG getRoundTripTime() const throw () { return (timeStamp + 50000) / 100000; }
RemoteServer& getServer() const throw () { return *dst; }
const RadiusRawOctets& getUserName() const throw () { return userName.get(); }
// Returns true if the associated RADIUS request is an Access-Request.
bool isAccReq() const throw () { return code == RADIUS_ACCESS_REQUEST; }
//////////
// Set the request authenticator.
//////////
void setAuthenticator(const BYTE* p) throw () { memcpy(authenticator, p, sizeof(authenticator)); }
//////////
// Methods for updating the request state. These events will be
// automatically forwarded to the relevant RemoteServer.
//////////
// Returns 'true' if the server is now newly available.
bool onReceive(BYTE code) throw ();
void onSend() throw () { timeStamp = GetSystemTime64(); dst->onSend(); }
// Returns 'true' if the server is now newly unavailable.
bool onTimeout() throw () { return dst->onTimeout(); }
//////////
// Methods for storing requests in a HashTable and a TimerQueue.
//////////
virtual void AddRef() throw (); virtual void Release() throw ();
virtual void onExpiry() throw ();
virtual const void* getKey() const throw (); virtual bool matches(const void* key) const throw ();
static ULONG WINAPI hash(const void* key) throw ();
private: RemotePort& port() const throw () { return isAccReq() ? dst->authPort : dst->acctPort; }
ProxyContextPtr ctxt; RemoteServerPtr dst; ULONG64 timeStamp; Count refCount; LONG id; // Unique ID stored in proxy state attribute.
BYTE code; // Request code.
BYTE identifier; // Request identifier.
BYTE authenticator[16]; // Request authenticator.
RadiusOctets userName; // RADIUS User-Name
static LONG theNextRequestID;
friend class RequestStack;
// Not implemented.
Request(const Request&); Request& operator=(const Request&); };
typedef ObjectPointer<Request> RequestPtr;
///////////////////////////////////////////////////////////////////////////////
//
// CLASS
//
// RequestStack
//
// DESCRIPTION
//
// Stores a collection of Requests.
//
// Note: A Request can only be in one RequestStack, and it can not be
// simultaneously store in a RequestStack and a HashTable.
//
///////////////////////////////////////////////////////////////////////////////
class RequestStack { public: RequestStack() throw () : head(NULL) { }
~RequestStack() throw () { while (!empty()) { pop(); } }
bool empty() const throw () { return head == NULL; }
RequestPtr pop() throw () { Request* top = head; head = static_cast<Request*>(head->next); return RequestPtr(top, false); }
void push(Request* request) throw () { request->next = head; head = request; request->AddRef(); }
private: Request* head;
// Not implemented.
RequestStack(const RequestStack&); RequestStack& operator=(const RequestStack&); };
///////////////////////////////////////////////////////////////////////////////
//
// CLASS
//
// ServerBinding
//
// DESCRIPTION
//
// Maps an octet string to a remote IP address. Used for server affinity and
// avoidance.
//
///////////////////////////////////////////////////////////////////////////////
class ServerBinding : public CacheEntry { public:
// The server that should be used for routing requests in this session.
RemoteServer& getServer() const throw () { return *server; } void setServer(RemoteServer& newVal) throw () { server = &newVal; }
ServerBinding( const RadiusRawOctets& key, RemoteServer& value ) : state(key), server(&value) { }
// Methods for storing a ServerBinding in a Cache.
virtual void AddRef() throw (); virtual void Release() throw (); virtual const void* getKey() const throw (); virtual bool matches(const void* key) const throw (); static ULONG WINAPI hash(const void* key) throw ();
private: Count refCount; RadiusOctets state; RemoteServerPtr server;
~ServerBinding() throw () { }
// Not implemented.
ServerBinding(const ServerBinding&); ServerBinding& operator=(const ServerBinding&); };
typedef ObjectPointer<ServerBinding> ServerBindingPtr;
#endif // RADPROXYP_H
|