/squid-3.2.0.16/src/acl/FilledChecklist.cc

# · C++ · 215 lines · 161 code · 32 blank · 22 comment · 21 complexity · 02a7ddd5f27ddd9d016a150ce95fc3a0 MD5 · raw file

  1. #include "squid-old.h"
  2. #include "HttpRequest.h"
  3. #include "HttpReply.h"
  4. #include "client_side.h"
  5. #if USE_AUTH
  6. #include "auth/UserRequest.h"
  7. #include "auth/AclProxyAuth.h"
  8. #endif
  9. #include "acl/FilledChecklist.h"
  10. #include "comm/Connection.h"
  11. #include "comm/forward.h"
  12. CBDATA_CLASS_INIT(ACLFilledChecklist);
  13. void
  14. ACLFilledChecklist::checkCallback(allow_t answer)
  15. {
  16. debugs(28, 5, HERE << this << " answer=" << answer);
  17. #if USE_AUTH
  18. /* During reconfigure, we can end up not finishing call
  19. * sequences into the auth code */
  20. if (auth_user_request != NULL) {
  21. /* the filled_checklist lock */
  22. auth_user_request = NULL;
  23. // It might have been connection based
  24. // In the case of sslBump we need to preserve authentication info
  25. // XXX: need to re-evaluate this. ACL tests should not be playing with
  26. // XXX: wider scoped TCP connection state, even if the helper lookup is stuck.
  27. if (conn() && !conn()->switchedToHttps()) {
  28. conn()->auth_user_request = NULL;
  29. }
  30. }
  31. #endif
  32. ACLChecklist::checkCallback(answer); // may delete us
  33. }
  34. void *
  35. ACLFilledChecklist::operator new (size_t size)
  36. {
  37. assert (size == sizeof(ACLFilledChecklist));
  38. CBDATA_INIT_TYPE(ACLFilledChecklist);
  39. ACLFilledChecklist *result = cbdataAlloc(ACLFilledChecklist);
  40. return result;
  41. }
  42. void
  43. ACLFilledChecklist::operator delete (void *address)
  44. {
  45. ACLFilledChecklist *t = static_cast<ACLFilledChecklist *>(address);
  46. cbdataFree(t);
  47. }
  48. ACLFilledChecklist::ACLFilledChecklist() :
  49. dst_peer(NULL),
  50. dst_rdns(NULL),
  51. request (NULL),
  52. reply (NULL),
  53. #if USE_AUTH
  54. auth_user_request (NULL),
  55. #endif
  56. #if SQUID_SNMP
  57. snmp_community(NULL),
  58. #endif
  59. #if USE_SSL
  60. ssl_error(0),
  61. #endif
  62. extacl_entry (NULL),
  63. conn_(NULL),
  64. fd_(-1),
  65. destinationDomainChecked_(false),
  66. sourceDomainChecked_(false)
  67. {
  68. my_addr.SetEmpty();
  69. src_addr.SetEmpty();
  70. dst_addr.SetEmpty();
  71. rfc931[0] = '\0';
  72. }
  73. ACLFilledChecklist::~ACLFilledChecklist()
  74. {
  75. assert (!asyncInProgress());
  76. safe_free(dst_rdns); // created by xstrdup().
  77. if (extacl_entry)
  78. cbdataReferenceDone(extacl_entry);
  79. HTTPMSGUNLOCK(request);
  80. HTTPMSGUNLOCK(reply);
  81. cbdataReferenceDone(conn_);
  82. debugs(28, 4, HERE << "ACLFilledChecklist destroyed " << this);
  83. }
  84. ConnStateData *
  85. ACLFilledChecklist::conn() const
  86. {
  87. return conn_;
  88. }
  89. void
  90. ACLFilledChecklist::conn(ConnStateData *aConn)
  91. {
  92. assert (conn() == NULL);
  93. conn_ = cbdataReference(aConn);
  94. }
  95. int
  96. ACLFilledChecklist::fd() const
  97. {
  98. return (conn_ != NULL && conn_->clientConnection != NULL) ? conn_->clientConnection->fd : fd_;
  99. }
  100. void
  101. ACLFilledChecklist::fd(int aDescriptor)
  102. {
  103. assert(!conn() || conn()->clientConnection == NULL || conn()->clientConnection->fd == aDescriptor);
  104. fd_ = aDescriptor;
  105. }
  106. bool
  107. ACLFilledChecklist::destinationDomainChecked() const
  108. {
  109. return destinationDomainChecked_;
  110. }
  111. void
  112. ACLFilledChecklist::markDestinationDomainChecked()
  113. {
  114. assert (!finished() && !destinationDomainChecked());
  115. destinationDomainChecked_ = true;
  116. }
  117. bool
  118. ACLFilledChecklist::sourceDomainChecked() const
  119. {
  120. return sourceDomainChecked_;
  121. }
  122. void
  123. ACLFilledChecklist::markSourceDomainChecked()
  124. {
  125. assert (!finished() && !sourceDomainChecked());
  126. sourceDomainChecked_ = true;
  127. }
  128. /*
  129. * There are two common ACLFilledChecklist lifecycles paths:
  130. *
  131. * A) Using aclCheckFast(): The caller creates an ACLFilledChecklist object
  132. * on stack and calls aclCheckFast().
  133. *
  134. * B) Using aclNBCheck() and callbacks: The caller allocates an
  135. * ACLFilledChecklist object (via operator new) and passes it to
  136. * aclNBCheck(). Control eventually passes to ACLChecklist::checkCallback(),
  137. * which will invoke the callback function as requested by the
  138. * original caller of aclNBCheck(). This callback function must
  139. * *not* delete the list. After the callback function returns,
  140. * checkCallback() will delete the list (i.e., self).
  141. */
  142. ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_request, const char *ident):
  143. dst_peer(NULL),
  144. dst_rdns(NULL),
  145. request(NULL),
  146. reply(NULL),
  147. #if USE_AUTh
  148. auth_user_request(NULL),
  149. #endif
  150. #if SQUID_SNMP
  151. snmp_community(NULL),
  152. #endif
  153. #if USE_SSL
  154. ssl_error(0),
  155. #endif
  156. extacl_entry (NULL),
  157. conn_(NULL),
  158. fd_(-1),
  159. destinationDomainChecked_(false),
  160. sourceDomainChecked_(false)
  161. {
  162. my_addr.SetEmpty();
  163. src_addr.SetEmpty();
  164. dst_addr.SetEmpty();
  165. rfc931[0] = '\0';
  166. // cbdataReferenceDone() is in either fastCheck() or the destructor
  167. if (A)
  168. accessList = cbdataReference(A);
  169. if (http_request != NULL) {
  170. request = HTTPMSGLOCK(http_request);
  171. #if FOLLOW_X_FORWARDED_FOR
  172. if (Config.onoff.acl_uses_indirect_client)
  173. src_addr = request->indirect_client_addr;
  174. else
  175. #endif /* FOLLOW_X_FORWARDED_FOR */
  176. src_addr = request->client_addr;
  177. my_addr = request->my_addr;
  178. }
  179. #if USE_IDENT
  180. if (ident)
  181. xstrncpy(rfc931, ident, USER_IDENT_SZ);
  182. #endif
  183. }