Repository: trafficserver
Updated Branches:
  refs/heads/master b99b8157b -> 38b4765a2


TS-2722 Eliminate the host lookup state, just use the client IP with 
TSHttpConnect


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/083e21b0
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/083e21b0
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/083e21b0

Branch: refs/heads/master
Commit: 083e21b03063264ecb343abb2d35014e8f80b6a4
Parents: b99b815
Author: Leif Hedstrom <[email protected]>
Authored: Wed Jul 30 14:42:52 2014 -0600
Committer: Leif Hedstrom <[email protected]>
Committed: Fri Aug 15 12:08:34 2014 -0600

----------------------------------------------------------------------
 plugins/experimental/authproxy/authproxy.cc | 135 ++++++-----------------
 1 file changed, 34 insertions(+), 101 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/083e21b0/plugins/experimental/authproxy/authproxy.cc
----------------------------------------------------------------------
diff --git a/plugins/experimental/authproxy/authproxy.cc 
b/plugins/experimental/authproxy/authproxy.cc
index fd6c112..ae20a31 100644
--- a/plugins/experimental/authproxy/authproxy.cc
+++ b/plugins/experimental/authproxy/authproxy.cc
@@ -43,7 +43,9 @@ using std::strlen;
 
 struct AuthRequestContext;
 
-typedef bool(*AuthRequestTransform) (AuthRequestContext* auth, const sockaddr* 
saddr);
+typedef bool(*AuthRequestTransform) (AuthRequestContext* auth);
+
+const static int MAX_HOST_LENGTH = 4096;
 
 // We can operate in global plugin mode or remap plugin mode. If we are in
 // global mode, then we will authorize every request. In remap mode, we will
@@ -56,12 +58,13 @@ static TSCont AuthOsDnsContinuation;
 struct AuthOptions
 {
   char* hostname;
+  int hostname_len;
   int hostport;
   bool force;
   AuthRequestTransform transform;
 
   AuthOptions():
-    hostname(NULL), hostport(8080), force(false), transform(NULL)
+    hostname(NULL), hostname_len(-1), hostport(-1), force(false), 
transform(NULL)
   { }
 
   ~AuthOptions()
@@ -88,7 +91,6 @@ struct StateTransition
 };
 
 static TSEvent StateAuthProxyConnect(AuthRequestContext*, void*);
-static TSEvent StateAuthProxyResolve(AuthRequestContext*, void*);
 static TSEvent StateAuthProxyWriteComplete(AuthRequestContext*, void*);
 static TSEvent StateUnauthorized(AuthRequestContext*, void*);
 static TSEvent StateAuthorized(AuthRequestContext*, void*);
@@ -140,7 +142,6 @@ static const StateTransition StateTableProxyReadHeader[] = {
 
 // State table for sending the request to the auth proxy.
 static const StateTransition StateTableProxyRequest[] = {
-  { TS_EVENT_HOST_LOOKUP, StateAuthProxyConnect, StateTableProxyRequest},
   { TS_EVENT_VCONN_WRITE_COMPLETE, StateAuthProxyWriteComplete, 
StateTableProxyReadHeader },
   { TS_EVENT_ERROR, StateUnauthorized, NULL },
   { TS_EVENT_NONE, NULL, NULL }
@@ -148,7 +149,7 @@ static const StateTransition StateTableProxyRequest[] = {
 
 // Initial state table.
 static const StateTransition StateTableInit[] = {
-  { TS_EVENT_HTTP_OS_DNS, StateAuthProxyResolve, StateTableProxyRequest },
+  { TS_EVENT_HTTP_OS_DNS, StateAuthProxyConnect, StateTableProxyRequest },
   { TS_EVENT_ERROR, StateUnauthorized, NULL },
   { TS_EVENT_NONE, NULL, NULL }
 };
@@ -288,7 +289,7 @@ AuthChainAuthorizationResponse(AuthRequestContext* auth)
 
 // Transform the client request into a HEAD request and write it out.
 static bool
-AuthWriteHeadRequest(AuthRequestContext* auth, const sockaddr* /* saddr 
ATS_UNUSED */ )
+AuthWriteHeadRequest(AuthRequestContext* auth)
 {
   HttpHeader rq;
   TSMBuffer mbuf;
@@ -322,29 +323,20 @@ AuthWriteHeadRequest(AuthRequestContext* auth, const 
sockaddr* /* saddr ATS_UNUS
 // Transform the client request into a form that the auth proxy can consume and
 // write it out.
 static bool
-AuthWriteRedirectedRequest(AuthRequestContext* auth, const sockaddr* saddr)
+AuthWriteRedirectedRequest(AuthRequestContext* auth)
 {
+  const AuthOptions* options = auth->options();
   HttpHeader rq;
   TSMBuffer mbuf;
   TSMLoc mhdr;
   TSMLoc murl;
-  char addrbuf[INET6_ADDRSTRLEN];
-  char hostbuf[INET6_ADDRSTRLEN + sizeof("[]") + sizeof(":65536")];
-  uint16_t hostport;
+  char hostbuf[MAX_HOST_LENGTH + 1];
 
   TSReleaseAssert(TSHttpTxnClientReqGet(auth->txn, &mbuf, &mhdr) == 
TS_SUCCESS);
 
   // First, copy the whole client request to our new auth proxy request.
   TSReleaseAssert(TSHttpHdrCopy(rq.buffer, rq.header, mbuf, mhdr) == 
TS_SUCCESS);
 
-  hostport = SockaddrGetPort(saddr);
-  inet_ntop(saddr->sa_family, SockaddrGetAddress(saddr), addrbuf, 
sizeof(addrbuf));
-  if (saddr->sa_family == PF_INET6) {
-    snprintf(hostbuf, sizeof(hostbuf), "[%s]:%d", addrbuf, hostport);
-  } else {
-    snprintf(hostbuf, sizeof(hostbuf), "%s:%d", addrbuf, hostport);
-  }
-
   // Next, we need to rewrite the client request URL so that the request goes 
to
   // the auth proxy instead of the original request.
   TSReleaseAssert(TSHttpHdrUrlGet(rq.buffer, rq.header, &murl) == TS_SUCCESS);
@@ -353,8 +345,14 @@ AuthWriteRedirectedRequest(AuthRequestContext* auth, const 
sockaddr* saddr)
   // scheme, forcing ATS to go to the Host header. I wonder how HTTPS would
   // work in that case. At any rate, we should add a new header containing
   // the original host so that the auth proxy can examine it.
-  TSUrlHostSet(rq.buffer, murl, addrbuf, -1);
-  TSUrlPortSet(rq.buffer, murl, hostport);
+  TSUrlHostSet(rq.buffer, murl, options->hostname, options->hostname_len);
+  if (-1 != options->hostport) {
+    snprintf(hostbuf, sizeof(hostbuf), "%s:%d", options->hostname, 
options->hostport);
+    TSUrlPortSet(rq.buffer, murl, options->hostport);
+  } else {
+    snprintf(hostbuf, sizeof(hostbuf), "%s", options->hostname);
+  }
+
   TSHandleMLocRelease(rq.buffer, rq.header, murl);
 
   HttpSetMimeHeader(rq.buffer, rq.header, TS_MIME_FIELD_HOST, hostbuf);
@@ -372,86 +370,23 @@ AuthWriteRedirectedRequest(AuthRequestContext* auth, 
const sockaddr* saddr)
 }
 
 static TSEvent
-StateAuthProxyResolve(AuthRequestContext* auth, void*)
-{
-  TSAction lookup;
-  const AuthOptions* options = auth->options();
-
-  // If we are authorizing with a HEAD request we want to send that to the
-  // origin; other requests we want to send to the authorization proxy.
-  if (options->transform == AuthWriteHeadRequest) {
-    char hostname[TS_MAX_HOST_NAME_LEN * 2];
-    TSMBuffer mbuf;
-    TSMLoc mhdr;
-
-    TSReleaseAssert(TSHttpTxnClientReqGet(auth->txn, &mbuf, &mhdr) == 
TS_SUCCESS);
-
-    if (HttpGetOriginHost(mbuf, mhdr, hostname, sizeof(hostname))) {
-      AuthLogDebug("resolving authorization host %s", hostname);
-      lookup = TSHostLookup(auth->cont, hostname, strlen(hostname));
-      TSHandleMLocRelease(mbuf, TS_NULL_MLOC, mhdr);
-    } else {
-      AuthLogError("failed to extract origin host name from client request");
-      TSHandleMLocRelease(mbuf, TS_NULL_MLOC, mhdr);
-      return TS_EVENT_ERROR;
-    }
-
-  } else {
-    AuthLogDebug("resolving authorization proxy host %s", options->hostname);
-    lookup = TSHostLookup(auth->cont, options->hostname, 
strlen(options->hostname));
-  }
-
-  if (TSActionDone(lookup)) {
-    AuthLogDebug("host lookup was executed in line");
-    return TS_EVENT_NONE;
-  }
-
-  return TS_EVENT_CONTINUE;
-}
-
-static TSEvent
 StateAuthProxyConnect(AuthRequestContext* auth, void* edata)
 {
   const AuthOptions* options = auth->options();
-  TSHostLookupResult dns;
-  const sockaddr* saddr;
+  struct sockaddr const* ip = TSHttpTxnClientAddrGet(auth->txn);
 
-  union
-  {
-    sockaddr sa;
-    sockaddr_in sin;
-    sockaddr_in6 sin6;
-    sockaddr_storage storage;
-  } addr;
-
-  dns = (TSHostLookupResult) edata;
-  if (dns == NULL) {
-    AuthLogError("failed to resolve authorization proxy at %s", 
options->hostname);
-    return TS_EVENT_ERROR;
-  }
-  // Copy the resolved address and add the port.
-  saddr = TSHostLookupResultAddrGet(dns);
-  switch (saddr->sa_family) {
-  case PF_INET:
-    memcpy(&addr.sin, saddr, sizeof(sockaddr_in));
-    addr.sin.sin_port = options->hostport;
-    break;
-  case PF_INET6:
-    memcpy(&addr.sin6, saddr, sizeof(sockaddr_in6));
-    addr.sin6.sin6_port = options->hostport;
-    break;
-  }
+  TSReleaseAssert(ip); // We must have a client IP.
 
   auth->is_head = AuthRequestIsHead(auth->txn);
   AuthLogDebug("client request %s a HEAD request", auth->is_head ? "is" : "is 
not");
 
-  auth->vconn = TSHttpConnect(&addr.sa);
+  auth->vconn = TSHttpConnect(ip);
   if (auth->vconn == NULL) {
     return TS_EVENT_ERROR;
   }
   // Transform the client request into an auth proxy request and write it
   // out to the auth proxy vconn.
-  if (!options->transform(auth, &addr.sa)) {
+  if (!options->transform(auth)) {
     return TS_EVENT_ERROR;
   }
   // Start a write and transition to WriteAuthProxyState.
@@ -677,35 +612,29 @@ static int
 AuthProxyGlobalHook(TSCont /* cont ATS_UNUSED */ , TSEvent event, void* edata)
 {
   AuthRequestContext* auth;
-  union
-  {
-    TSHostLookupResult dns;
-    TSHttpTxn txn;
-    void* edata;
-  } ptr;
+  TSHttpTxn txn = (TSHttpTxn)edata;
 
-  ptr.edata = edata;
   AuthLogDebug("handling event=%d edata=%p", (int) event, edata);
 
   switch (event) {
   case TS_EVENT_HTTP_OS_DNS:
     // Ignore internal requests since we generated them.
-    if (TSHttpIsInternalRequest(ptr.txn) == TS_SUCCESS) {
+    if (TSHttpIsInternalRequest(txn) == TS_SUCCESS) {
       // All our internal requests *must* hit the origin since it is the
       // agent that needs to make the authorization decision. We can't
       // allow that to be cached.
-      TSHttpTxnReqCacheableSet(ptr.txn, 0);
+      TSHttpTxnReqCacheableSet(txn, 0);
 
       AuthLogDebug("re-enabling internal transaction");
-      TSHttpTxnReenable(ptr.txn, TS_EVENT_HTTP_CONTINUE);
+      TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE);
       return TS_EVENT_NONE;
     }
     // Hook this request if we are in global authorization mode or if a
     // remap rule tagged it.
-    if (AuthGlobalOptions != NULL || AuthRequestIsTagged(ptr.txn)) {
+    if (AuthGlobalOptions != NULL || AuthRequestIsTagged(txn)) {
       auth = AuthRequestContext::allocate();
       auth->state = StateTableInit;
-      auth->txn = ptr.txn;
+      auth->txn = txn;
       return AuthRequestContext::dispatch(auth->cont, event, edata);
     }
     // fallthru
@@ -733,7 +662,6 @@ AuthParseOptions(int argc, const char** argv)
   AuthOptions* options = AuthNew<AuthOptions>();
 
   options->transform = AuthWriteRedirectedRequest;
-  options->hostname = TSstrdup("127.0.0.1");
 
   // We might parse arguments multiple times if we are loaded as a global
   // plugin and a remap plugin. Reset optind so that getopt_long() does the
@@ -746,7 +674,7 @@ AuthParseOptions(int argc, const char** argv)
     opt = getopt_long(argc, (char* const *) argv, "", longopt, NULL);
     switch (opt) {
     case 'h':
-      TSfree(options->hostname);
+      TSfree(options->hostname); // Probably isn't set, but safe to always free
       options->hostname = TSstrdup(optarg);
       break;
     case 'p':
@@ -773,6 +701,11 @@ AuthParseOptions(int argc, const char** argv)
     }
   }
 
+  if (NULL == options->hostname) {
+    options->hostname = TSstrdup("127.0.0.1");
+  }
+  options->hostname_len = strlen(options->hostname);
+
   return options;
 }
 

Reply via email to