Source code of Windows XP (NT5)
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.

296 lines
7.2 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. RadiusPortType getPortType() const throw ()
  96. { return isAccReq() ? portAuthentication : portAccounting; }
  97. const RemotePort& getPort() const throw ()
  98. { return port(); }
  99. // The unique ID used to identify this request internally. This is not the
  100. // same as the identifier sent on the wire.
  101. LONG getRequestID() const throw ()
  102. { return id; }
  103. // Returns the round trip time in hundredths of a second.
  104. ULONG getRoundTripTime() const throw ()
  105. { return (timeStamp + 50000) / 100000; }
  106. RemoteServer& getServer() const throw ()
  107. { return *dst; }
  108. // Returns true if the associated RADIUS request is an Access-Request.
  109. bool isAccReq() const throw ()
  110. { return code == RADIUS_ACCESS_REQUEST; }
  111. //////////
  112. // Set the request authenticator.
  113. //////////
  114. void setAuthenticator(const BYTE* p) throw ()
  115. { memcpy(authenticator, p, sizeof(authenticator)); }
  116. //////////
  117. // Methods for updating the request state. These events will be
  118. // automatically forwarded to the relevant RemoteServer.
  119. //////////
  120. // Returns 'true' if the server is now newly available.
  121. bool onReceive() throw ();
  122. void onSend() throw ()
  123. { timeStamp = GetSystemTime64(); }
  124. // Returns 'true' if the server is now newly unavailable.
  125. bool onTimeout() throw ()
  126. { return dst->onTimeout(); }
  127. //////////
  128. // Methods for storing requests in a HashTable and a TimerQueue.
  129. //////////
  130. virtual void AddRef() throw ();
  131. virtual void Release() throw ();
  132. virtual void onExpiry() throw ();
  133. virtual const void* getKey() const throw ();
  134. virtual bool matches(const void* key) const throw ();
  135. static ULONG WINAPI hash(const void* key) throw ();
  136. private:
  137. RemotePort& port() const throw ()
  138. { return isAccReq() ? dst->authPort : dst->acctPort; }
  139. ProxyContextPtr ctxt;
  140. RemoteServerPtr dst;
  141. ULONG64 timeStamp;
  142. Count refCount;
  143. LONG id; // Unique ID stored in proxy state attribute.
  144. BYTE code; // Request code.
  145. BYTE identifier; // Request identifier.
  146. BYTE authenticator[16]; // Request authenticator.
  147. static LONG theNextRequestID;
  148. friend class RequestStack;
  149. // Not implemented.
  150. Request(const Request&);
  151. Request& operator=(const Request&);
  152. };
  153. typedef ObjectPointer<Request> RequestPtr;
  154. ///////////////////////////////////////////////////////////////////////////////
  155. //
  156. // CLASS
  157. //
  158. // RequestStack
  159. //
  160. // DESCRIPTION
  161. //
  162. // Stores a collection of Requests.
  163. //
  164. // Note: A Request can only be in one RequestStack, and it can not be
  165. // simultaneously store in a RequestStack and a HashTable.
  166. //
  167. ///////////////////////////////////////////////////////////////////////////////
  168. class RequestStack
  169. {
  170. public:
  171. RequestStack() throw ()
  172. : head(NULL)
  173. { }
  174. ~RequestStack() throw ()
  175. {
  176. while (!empty()) { pop(); }
  177. }
  178. bool empty() const throw ()
  179. { return head == NULL; }
  180. RequestPtr pop() throw ()
  181. {
  182. Request* top = head;
  183. head = static_cast<Request*>(head->next);
  184. return RequestPtr(top, false);
  185. }
  186. void push(Request* request) throw ()
  187. {
  188. request->next = head;
  189. head = request;
  190. request->AddRef();
  191. }
  192. private:
  193. Request* head;
  194. // Not implemented.
  195. RequestStack(const RequestStack&);
  196. RequestStack& operator=(const RequestStack&);
  197. };
  198. ///////////////////////////////////////////////////////////////////////////////
  199. //
  200. // CLASS
  201. //
  202. // Session
  203. //
  204. // DESCRIPTION
  205. //
  206. // Maps a RADIUS state attribute to a remote IP address.
  207. //
  208. ///////////////////////////////////////////////////////////////////////////////
  209. class Session : public CacheEntry
  210. {
  211. public:
  212. // The server that should be used for routing requests in this session.
  213. RemoteServer& getServer() const throw ()
  214. { return *server; }
  215. void setServer(RemoteServer& newVal) throw ()
  216. { server = &newVal; }
  217. Session(
  218. RadiusRawOctets& key,
  219. RemoteServer& value
  220. )
  221. : state(key),
  222. server(&value)
  223. { }
  224. // Methods for storing a Session in a Cache.
  225. virtual void AddRef() throw ();
  226. virtual void Release() throw ();
  227. virtual const void* getKey() const throw ();
  228. virtual bool matches(const void* key) const throw ();
  229. static ULONG WINAPI hash(const void* key) throw ();
  230. private:
  231. Count refCount;
  232. RadiusOctets state;
  233. RemoteServerPtr server;
  234. ~Session() throw () { }
  235. // Not implemented.
  236. Session(const Session&);
  237. Session& operator=(const Session&);
  238. };
  239. typedef ObjectPointer<Session> SessionPtr;
  240. #endif // RADPROXYP_H