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.

303 lines
7.8 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) Microsoft Corporation
  4. //
  5. // FILE
  6. //
  7. // radproxyp.h
  8. //
  9. // SYNOPSIS
  10. //
  11. // Declares classes that are used in the implementation of RadiusProxy, but
  12. // need not be visible to clients.
  13. //
  14. ///////////////////////////////////////////////////////////////////////////////
  15. #ifndef RADPROXYP_H
  16. #define RADPROXYP_H
  17. #if _MSC_VER >= 1000
  18. #pragma once
  19. #endif
  20. #include <radpack.h>
  21. #include <radproxy.h>
  22. #include <timerq.h>
  23. ///////////////////////////////////////////////////////////////////////////////
  24. //
  25. // CLASS
  26. //
  27. // ProxyContext
  28. //
  29. // DESCRIPTION
  30. //
  31. // Allows a request context to be shared by several Requests only one
  32. // of which will eventually take ownership.
  33. //
  34. ///////////////////////////////////////////////////////////////////////////////
  35. class ProxyContext
  36. {
  37. public:
  38. ProxyContext(PVOID p) throw ()
  39. : context(p)
  40. { }
  41. DECLARE_REFERENCE_COUNT();
  42. // Each context has an associated 'primary' server. This is the server that
  43. // will be used for event reporting if no one takes ownership of the
  44. // context.
  45. RemoteServer* getPrimaryServer() const throw()
  46. { return primary; }
  47. void setPrimaryServer(RemoteServer* server) throw ()
  48. { primary = server; }
  49. // Take ownership of the context. This will return NULL if someone has beat
  50. // you to it. If the caller is successful, he MUST ensure that
  51. // RadiusProxyClient::onComplete is always invoked exactly once.
  52. PVOID takeOwnership() throw ()
  53. { return InterlockedExchangePointer(&context, NULL); }
  54. private:
  55. PVOID context;
  56. RemoteServerPtr primary;
  57. ~ProxyContext() throw ();
  58. // Not implemented.
  59. ProxyContext(const ProxyContext&);
  60. ProxyContext& operator=(const ProxyContext&);
  61. };
  62. typedef ObjectPointer<ProxyContext> ProxyContextPtr;
  63. class RequestStack;
  64. ///////////////////////////////////////////////////////////////////////////////
  65. //
  66. // CLASS
  67. //
  68. // Request
  69. //
  70. // DESCRIPTION
  71. //
  72. // Stores the state associated with a pending RADIUS request.
  73. //
  74. ///////////////////////////////////////////////////////////////////////////////
  75. class Request : public HashTableEntry, public Timer
  76. {
  77. public:
  78. Request(
  79. ProxyContext* context,
  80. RemoteServer* destination,
  81. BYTE packetCode
  82. ) throw ();
  83. //////////
  84. // Various accessors. There is a lot of state associated with a request.
  85. //////////
  86. const BYTE* getAuthenticator() const throw ()
  87. { return authenticator; }
  88. BYTE getCode() const throw ()
  89. { return code; }
  90. ProxyContext& getContext() const throw ()
  91. { return *ctxt; }
  92. // The RADIUS packet identifier for this request.
  93. BYTE getIdentifier() const throw ()
  94. { return identifier; }
  95. void setPacket(const RadiusPacket& packet);
  96. RadiusPortType getPortType() const throw ()
  97. { return isAccReq() ? portAuthentication : portAccounting; }
  98. const RemotePort& getPort() const throw ()
  99. { return port(); }
  100. // The unique ID used to identify this request internally. This is not the
  101. // same as the identifier sent on the wire.
  102. LONG getRequestID() const throw ()
  103. { return id; }
  104. // Returns the round trip time in hundredths of a second.
  105. ULONG getRoundTripTime() const throw ()
  106. { return (timeStamp + 50000) / 100000; }
  107. RemoteServer& getServer() const throw ()
  108. { return *dst; }
  109. const RadiusRawOctets& getUserName() const throw ()
  110. { return userName.get(); }
  111. // Returns true if the associated RADIUS request is an Access-Request.
  112. bool isAccReq() const throw ()
  113. { return code == RADIUS_ACCESS_REQUEST; }
  114. //////////
  115. // Set the request authenticator.
  116. //////////
  117. void setAuthenticator(const BYTE* p) throw ()
  118. { memcpy(authenticator, p, sizeof(authenticator)); }
  119. //////////
  120. // Methods for updating the request state. These events will be
  121. // automatically forwarded to the relevant RemoteServer.
  122. //////////
  123. // Returns 'true' if the server is now newly available.
  124. bool onReceive(BYTE code) throw ();
  125. void onSend() throw ()
  126. { timeStamp = GetSystemTime64(); dst->onSend(); }
  127. // Returns 'true' if the server is now newly unavailable.
  128. bool onTimeout() throw ()
  129. { return dst->onTimeout(); }
  130. //////////
  131. // Methods for storing requests in a HashTable and a TimerQueue.
  132. //////////
  133. virtual void AddRef() throw ();
  134. virtual void Release() throw ();
  135. virtual void onExpiry() throw ();
  136. virtual const void* getKey() const throw ();
  137. virtual bool matches(const void* key) const throw ();
  138. static ULONG WINAPI hash(const void* key) throw ();
  139. private:
  140. RemotePort& port() const throw ()
  141. { return isAccReq() ? dst->authPort : dst->acctPort; }
  142. ProxyContextPtr ctxt;
  143. RemoteServerPtr dst;
  144. ULONG64 timeStamp;
  145. Count refCount;
  146. LONG id; // Unique ID stored in proxy state attribute.
  147. BYTE code; // Request code.
  148. BYTE identifier; // Request identifier.
  149. BYTE authenticator[16]; // Request authenticator.
  150. RadiusOctets userName; // RADIUS User-Name
  151. static LONG theNextRequestID;
  152. friend class RequestStack;
  153. // Not implemented.
  154. Request(const Request&);
  155. Request& operator=(const Request&);
  156. };
  157. typedef ObjectPointer<Request> RequestPtr;
  158. ///////////////////////////////////////////////////////////////////////////////
  159. //
  160. // CLASS
  161. //
  162. // RequestStack
  163. //
  164. // DESCRIPTION
  165. //
  166. // Stores a collection of Requests.
  167. //
  168. // Note: A Request can only be in one RequestStack, and it can not be
  169. // simultaneously store in a RequestStack and a HashTable.
  170. //
  171. ///////////////////////////////////////////////////////////////////////////////
  172. class RequestStack
  173. {
  174. public:
  175. RequestStack() throw ()
  176. : head(NULL)
  177. { }
  178. ~RequestStack() throw ()
  179. {
  180. while (!empty()) { pop(); }
  181. }
  182. bool empty() const throw ()
  183. { return head == NULL; }
  184. RequestPtr pop() throw ()
  185. {
  186. Request* top = head;
  187. head = static_cast<Request*>(head->next);
  188. return RequestPtr(top, false);
  189. }
  190. void push(Request* request) throw ()
  191. {
  192. request->next = head;
  193. head = request;
  194. request->AddRef();
  195. }
  196. private:
  197. Request* head;
  198. // Not implemented.
  199. RequestStack(const RequestStack&);
  200. RequestStack& operator=(const RequestStack&);
  201. };
  202. ///////////////////////////////////////////////////////////////////////////////
  203. //
  204. // CLASS
  205. //
  206. // ServerBinding
  207. //
  208. // DESCRIPTION
  209. //
  210. // Maps an octet string to a remote IP address. Used for server affinity and
  211. // avoidance.
  212. //
  213. ///////////////////////////////////////////////////////////////////////////////
  214. class ServerBinding : public CacheEntry
  215. {
  216. public:
  217. // The server that should be used for routing requests in this session.
  218. RemoteServer& getServer() const throw ()
  219. { return *server; }
  220. void setServer(RemoteServer& newVal) throw ()
  221. { server = &newVal; }
  222. ServerBinding(
  223. const RadiusRawOctets& key,
  224. RemoteServer& value
  225. )
  226. : state(key),
  227. server(&value)
  228. { }
  229. // Methods for storing a ServerBinding in a Cache.
  230. virtual void AddRef() throw ();
  231. virtual void Release() throw ();
  232. virtual const void* getKey() const throw ();
  233. virtual bool matches(const void* key) const throw ();
  234. static ULONG WINAPI hash(const void* key) throw ();
  235. private:
  236. Count refCount;
  237. RadiusOctets state;
  238. RemoteServerPtr server;
  239. ~ServerBinding() throw () { }
  240. // Not implemented.
  241. ServerBinding(const ServerBinding&);
  242. ServerBinding& operator=(const ServerBinding&);
  243. };
  244. typedef ObjectPointer<ServerBinding> ServerBindingPtr;
  245. #endif // RADPROXYP_H