You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2010/09/03 04:54:35 UTC

svn commit: r992187 - in /trafficserver/traffic/trunk: ./ iocore/cluster/ iocore/net/ libinktomi++/ proxy/ proxy/hdrs/ proxy/http2/ proxy/http2/remap/ proxy/mgmt2/

Author: amc
Date: Fri Sep  3 02:54:34 2010
New Revision: 992187

URL: http://svn.apache.org/viewvc?rev=992187&view=rev
Log:
This is a merge from the ts-291 branch. It is an update to implement
forward transparency. See TS-291 for details.

Modified:
    trafficserver/traffic/trunk/   (props changed)
    trafficserver/traffic/trunk/configure.ac
    trafficserver/traffic/trunk/iocore/cluster/ClusterConfig.cc
    trafficserver/traffic/trunk/iocore/net/I_NetProcessor.h
    trafficserver/traffic/trunk/iocore/net/I_NetVConnection.h
    trafficserver/traffic/trunk/iocore/net/P_Connection.h
    trafficserver/traffic/trunk/iocore/net/P_UnixNetProcessor.h
    trafficserver/traffic/trunk/iocore/net/UnixConnection.cc
    trafficserver/traffic/trunk/iocore/net/UnixNetAccept.cc
    trafficserver/traffic/trunk/iocore/net/UnixNetProcessor.cc
    trafficserver/traffic/trunk/libinktomi++/ink_config.h.in
    trafficserver/traffic/trunk/proxy/Main.h
    trafficserver/traffic/trunk/proxy/SocksProxy.cc
    trafficserver/traffic/trunk/proxy/hdrs/HTTP.cc
    trafficserver/traffic/trunk/proxy/hdrs/HTTP.h
    trafficserver/traffic/trunk/proxy/http2/HttpConfig.cc
    trafficserver/traffic/trunk/proxy/http2/HttpConfig.h
    trafficserver/traffic/trunk/proxy/http2/HttpProxyServerMain.cc
    trafficserver/traffic/trunk/proxy/http2/HttpSM.cc
    trafficserver/traffic/trunk/proxy/http2/HttpTransact.cc
    trafficserver/traffic/trunk/proxy/http2/HttpTransact.h
    trafficserver/traffic/trunk/proxy/http2/remap/RemapProcessor.cc
    trafficserver/traffic/trunk/proxy/mgmt2/LocalManager.cc

Propchange: trafficserver/traffic/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Sep  3 02:54:34 2010
@@ -1 +1,2 @@
 /incubator/trafficserver/traffic/branches/dev:891823-915885
+/trafficserver/traffic/branches/ts-291:965529-991993

Modified: trafficserver/traffic/trunk/configure.ac
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/configure.ac?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/configure.ac (original)
+++ trafficserver/traffic/trunk/configure.ac Fri Sep  3 02:54:34 2010
@@ -339,6 +339,25 @@ AC_ARG_ENABLE([ccache],
 AC_MSG_RESULT([$enable_ccache])
 
 #
+# Use TPROXY for connection transparency.
+#
+AC_MSG_CHECKING([whether to enable TPROXY based transparency])
+AC_ARG_ENABLE([tproxy],
+  [AS_HELP_STRING([--enable-tproxy[[=ARG]]],
+                  [Use TPROXY to enable connection transparency.
+                   'auto' or omitted for local system default,
+		   'no' to disable,
+		   'force' to use built in default,
+		   number to use as IP_TRANSPARENT sockopt.
+		   [default=auto]
+		  ])
+  ],
+  [],
+  [enable_tproxy="auto"]
+)
+AC_MSG_RESULT([$enable_tproxy])
+
+#
 # Installation directories
 # For each var the following is evaluated
 # foo      Standard variable  eg. ${prefix}/foo
@@ -980,6 +999,90 @@ if test "x${enable_posix_cap}" = "xyes";
   )
 fi
 
+#
+# Configure sockopt value for TPROXY. Look at the enable flag.
+# Value 'no' means user forced disable, don't check anything else.
+#       'auto' means user didn't say, so silently enable/disable
+#              based on success.
+#       A numeric value means enable, don't check, use that value.
+#       Anything else means user forced, fail if value not found
+#       in header file.
+# We can't just include linux/in.h because it's incompatible with
+# netinet/in.h.
+# Verify the file exists (is readable), scan for the value we need,
+# if found export the value and enable use of the value.
+#
+ip_transparent=0
+use_tproxy=0
+tproxy_header=/usr/include/linux/in.h
+tproxy_usage_enable="
+    --enable-tproxy Enable the feature and validate."
+tproxy_usage_default="
+    --enable-tproxy=force Enable using default sockopt value, no validation."
+tproxy_usage_numeric="
+    --enable-tproxy=X where X is numeric
+                      Enable, use X for sockopt value, no validation."
+tproxy_usage_disable="
+    --disable-tproxy Disable feature, no validation."
+proxy_usage="$tproxy_usage_enable$tproxy_usage_default$tproxy_usage_numeric$tproxy_usage_disable"
+
+AS_IF([test "x$enable_tproxy" != "xno"], [
+  AS_IF([test "x${enable_posix_cap}" != "xyes"], [
+    AC_MSG_FAILURE([TPROXY feature requires POSIX capabilities.])
+  ],[
+    AC_MSG_CHECKING([for TPROXY sockopt IP_TRANSPARENT])
+    AS_CASE("$enable_tproxy",
+      [[[0-9]][[0-9]]*], [
+	ip_transparent=$enable_tproxy
+	use_tproxy=1
+	AC_MSG_RESULT([forced to $ip_transparent])
+      ],
+      [force], [
+	ip_transparent=19
+	use_tproxy=1
+	AC_MSG_RESULT([forced to $ip_transparent])
+      ],
+      [yes], [
+        AS_IF([test -r $tproxy_header], [
+	  ip_transparent=`$AWK "/^#define[ \t]+IP_TRANSPARENT[ \t]+[0-9]+/{print \\$3}" $tproxy_header`
+	  AS_IF([test "x$ip_transparent" != "x"], [
+	    use_tproxy=1
+	    AC_MSG_RESULT([set to $ip_transparent])
+	  ],[
+	    ip_transparent=0
+	    AC_MSG_RESULT([failed])
+	    AC_MSG_FAILURE([tproxy feature enabled but the sockopt value was not found in $tproxy_header. Try one of$tproxy_usage_default$tproxy_usage_numeric$tproxy_usage_disable])
+	  ])
+	],[
+	  AC_MSG_RESULT([failed])
+	  AC_MSG_FAILURE([tproxy feature enabled but the header file $tproxy_header was not readable. Try one of$tproxy_usage_default$tproxy_usage_numeric$tproxy_usage_disable])
+	])
+      ],
+      # same as 'yes' but silent fail.
+      [auto], [
+        AS_IF([test -r $tproxy_header], [
+	  ip_transparent=`gawk "/^#define[ \t]+IP_TRANSPARENT[ \t]+[0-9]+/{print \\$3}" $tproxy_header`
+	  AS_IF([test "x$ip_transparent" != "x"], [
+	    use_tproxy=1
+	    AC_MSG_RESULT([set to $ip_transparent])
+	  ],[
+	    AC_MSG_RESULT([no])
+	  ])
+	],[
+	  AC_MSG_RESULT([no])
+	])
+      ],
+      [
+	AC_MSG_RESULT([failed])
+	AC_MSG_FAILURE([Invalid argument to feature tproxy.$tproxy_usage])
+      ]
+    )
+  ])
+])
+
+AC_SUBST(use_tproxy)
+AC_SUBST(ip_transparent)
+
 ATS_CHECK_DEFAULT_IFACE
 ATS_CHECK_GETHOSTBYNAME_R_STYLE
 

Modified: trafficserver/traffic/trunk/iocore/cluster/ClusterConfig.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/cluster/ClusterConfig.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/cluster/ClusterConfig.cc (original)
+++ trafficserver/traffic/trunk/iocore/cluster/ClusterConfig.cc Fri Sep  3 02:54:34 2010
@@ -102,9 +102,14 @@ ClusterAccept::ClusterAcceptEvent(int ev
           accept_action->cancel();
           accept_action = 0;
         }
-        accept_action = netProcessor.main_accept(this, NO_FD, cluster_port,
+	NetProcessor::AcceptOptions opt;
+	opt.recv_bufsize = socket_recv_bufsize;
+	opt.send_bufsize = socket_send_bufsize;
+	opt.etype = ET_CLUSTER;
+	opt.port = cluster_port;
+        accept_action = netProcessor.main_accept(this, NO_FD,
                                                  NULL, NULL,
-                                                 false, socket_recv_bufsize, socket_send_bufsize, ET_CLUSTER);
+                                                 false, opt);
         if (!accept_action) {
           Warning("Unable to accept cluster connections on port: %d", cluster_port);
         } else {

Modified: trafficserver/traffic/trunk/iocore/net/I_NetProcessor.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/net/I_NetProcessor.h?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/net/I_NetProcessor.h (original)
+++ trafficserver/traffic/trunk/iocore/net/I_NetProcessor.h Fri Sep  3 02:54:34 2010
@@ -41,6 +41,50 @@ class NetVCOptions;
 class NetProcessor:public Processor
 {
 public:
+  /** Options for @c accept.
+   */
+  struct AcceptOptions {
+    typedef AcceptOptions self; ///< Self reference type.
+
+    /// Port on which to listen.
+    /// 0 => don't care, which is useful if the socket is already bound.
+    int port;
+    /// Communication domain (default: AF_INET)
+    int domain;
+    /// Event type to generate on accept.
+    EventType etype;
+    /** If @c true, the continuation is called back with
+	@c NET_EVENT_ACCEPT_SUCCEED,
+	or @c NET_EVENT_ACCEPT_FAILED on success and failure resp.
+    */
+    bool f_callback_on_open;
+
+    /// Socket receive buffer size.
+    /// 0 => OS default.
+    int recv_bufsize;
+    /// Socket transmit buffer size.
+    /// 0 => OS default.
+    int send_bufsize;
+    /// Socket options for @c sockopt.
+    /// 0 => do not set options.
+    unsigned long sockopt_flags;
+    /// Transparency on related connection to origin server.
+    bool f_outbound_transparent;
+    /** Transparency on client (user agent) connection.
+	@internal This is irrelevant at a socket level (since inbound
+	transparency must be set up when the listen socket is created)
+	but it's critical that the connection handling logic knows
+	whether the inbound (client / user agent) connection is
+	transparent.
+    */
+    bool f_inbound_transparent;
+
+    /// Default constructor.
+    /// Instance is constructed with default values.
+    AcceptOptions() { this->reset(); }
+    /// Reset all values to defaults.
+    self& reset();
+  };
 
   /**
     Accept connections on a port.
@@ -133,7 +177,7 @@ public:
       port becomes free immediately.
 
   */
-  virtual Action *main_accept(Continuation * cont, SOCKET listen_socket_in, int port, sockaddr * bound_sockaddr = NULL, int *bound_sockaddr_size = NULL, bool accept_only = false, int recv_bufsize = 0, int send_bufsize = 0, unsigned long sockopt_flag = 0, EventType etype = ET_NET, bool callback_on_open = false  // TBD for NT
+  virtual Action *main_accept(Continuation * cont, SOCKET listen_socket_in, sockaddr * bound_sockaddr = NULL, int *bound_sockaddr_size = NULL, bool accept_only = false, AcceptOptions const& opt = DEFAULT_ACCEPT_OPTIONS
     );
 
   /**
@@ -224,6 +268,9 @@ public:
   /* shared by regular netprocessor and ssl netprocessor */
   static socks_conf_struct *socks_conf_stuff;
 
+  /// Default options instance.
+  static AcceptOptions const DEFAULT_ACCEPT_OPTIONS;
+
 private:
 
   /** @note Not implemented. */
@@ -235,6 +282,7 @@ private:
 
   NetProcessor(const NetProcessor &);
   NetProcessor & operator =(const NetProcessor &);
+
 };
 
 

Modified: trafficserver/traffic/trunk/iocore/net/I_NetVConnection.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/net/I_NetVConnection.h?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/net/I_NetVConnection.h (original)
+++ trafficserver/traffic/trunk/iocore/net/I_NetVConnection.h Fri Sep  3 02:54:34 2010
@@ -73,12 +73,13 @@ struct NetVCOptions {
 
       @note The difference between @c INTF_ADDR and @c FOREIGN_ADDR is
       whether transparency is enabled on the socket. It is the
-      client's responsibility to set this correct based on whether the
+      client's responsibility to set this correctly based on whether the
       address in @a local_addr is associated with an interface on the
       local system, or is owned by a foreign system.  A binding style
       of @c ANY_ADDR causes the value in @a local_addr to be ignored.
 
       @see local_addr
+      @see addr_binding
    */
   enum addr_bind_style {
     ANY_ADDR, ///< Bind to any available local address (don't care, default).
@@ -88,7 +89,7 @@ struct NetVCOptions {
 
   /// The set of ways in which the local port should be bound.
   enum port_bind_style {
-    ANY_PORT, ///< Bind to any available local port (dont' care, default).
+    ANY_PORT, ///< Bind to any available local port (don't care, default).
     FIXED_PORT ///< Bind to the port in @a local_port.
   };
 
@@ -438,6 +439,24 @@ public:
     is_internal_request = val;
   }
 
+  /// Get the transparency state.
+  bool get_is_transparent() const {
+    return is_transparent;
+  }
+  /// Set the transparency state.
+  void set_is_transparent(bool state = true) {
+    is_transparent = state;
+  }
+
+  /// Get the current flag state.
+  bool get_is_other_side_transparent() const {
+    return is_other_side_transparent;
+  }
+  /// Set the flag to @a value.
+  void set_is_other_side_transparent(bool value = true) {
+    is_other_side_transparent = value;
+  }
+
 #if ATS_USE_DETAILED_LOG
   void loggingInit()
   {
@@ -499,6 +518,13 @@ protected:
   int got_remote_addr;
 
   bool is_internal_request;
+  /// Set if this connection is transparent.
+  bool is_transparent;
+  /// Set if the paired connection is (should be) transparent.
+  /// @internal Currently only used on client side connections
+  /// to track whether the origin server connection should
+  /// be transparent.
+  bool is_other_side_transparent;
 };
 
 inline
@@ -511,7 +537,8 @@ NetVConnection::NetVConnection():
 #endif
   got_local_addr(0),
   got_remote_addr(0),
-  is_internal_request(false)
+  is_internal_request(false),
+  is_other_side_transparent(false)
 {
   memset(&local_addr, 0, sizeof(local_addr));
   memset(&remote_addr, 0, sizeof(remote_addr));

Modified: trafficserver/traffic/trunk/iocore/net/P_Connection.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/net/P_Connection.h?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/net/P_Connection.h (original)
+++ trafficserver/traffic/trunk/iocore/net/P_Connection.h Fri Sep  3 02:54:34 2010
@@ -162,6 +162,11 @@ struct Server: public Connection
   //
   unsigned int accept_ip;
 
+  /// If set, transparently connect to origin server for requests.
+  bool f_outbound_transparent;
+  /// If set, the related incoming connect was transparent.
+  bool f_inbound_transparent;
+
   //
   // Use this call for the main proxy accept
   //
@@ -178,7 +183,11 @@ struct Server: public Connection
   int listen(int port, bool non_blocking = false, int recv_bufsize = 0, int send_bufsize = 0);
   int setup_fd_for_listen(bool non_blocking = false, int recv_bufsize = 0, int send_bufsize = 0);
 
-  Server():Connection(), accept_ip(INADDR_ANY) { }
+  Server()
+    : Connection()
+    , accept_ip(INADDR_ANY)
+    , f_outbound_transparent(false)
+  { }
 };
 
 #endif /*_Connection_h*/

Modified: trafficserver/traffic/trunk/iocore/net/P_UnixNetProcessor.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/net/P_UnixNetProcessor.h?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/net/P_UnixNetProcessor.h (original)
+++ trafficserver/traffic/trunk/iocore/net/P_UnixNetProcessor.h Fri Sep  3 02:54:34 2010
@@ -39,16 +39,13 @@ public:
 
   virtual Action * accept_internal(Continuation * cont,
                                    int fd,
-                                   int port,
                                    sockaddr * bound_sockaddr = NULL,
                                    int *bound_sockaddr_size = NULL,
                                    bool frequent_accept = true,
                                    AcceptFunctionPtr fn = net_accept,
-                                   int recv_bufsize = 0,
-                                   int send_bufsize = 0,
-                                   unsigned long sockopt_flags = 0,
                                    unsigned int accept_ip = INADDR_ANY,
-                                   bool callback_on_open = false, EventType etype = ET_NET);
+				   AcceptOptions const& opt = DEFAULT_ACCEPT_OPTIONS
+				   );
 
 
   Action *connect_re_internal(Continuation * cont,

Modified: trafficserver/traffic/trunk/iocore/net/UnixConnection.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/net/UnixConnection.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/net/UnixConnection.cc (original)
+++ trafficserver/traffic/trunk/iocore/net/UnixConnection.cc Fri Sep  3 02:54:34 2010
@@ -280,9 +280,16 @@ Connection::open(NetVCOptions const& opt
   }
 
   if (NetVCOptions::FOREIGN_ADDR == opt.addr_binding && local_addr) {
+    static char const * const DEBUG_TEXT = "::open setsockopt() IP_TRANSPARENT";
     int value = 1;
-    res = safe_setsockopt(fd, SOL_SOCKET, IP_TRANSPARENT, reinterpret_cast<char*>(&value), sizeof(value));
-    if (-1 == res) return -errno;
+    if (-1 == safe_setsockopt(fd, SOL_IP, ATS_IP_TRANSPARENT,
+			      reinterpret_cast<char*>(&value), sizeof(value)
+			      )) {
+      NetDebug("socket", "%s - fail %d:%s", DEBUG_TEXT, errno, strerror(errno));
+      return -errno;
+    } else {
+      NetDebug("socket", "%s set", DEBUG_TEXT);
+    }
   }
 
   // Local address/port.

Modified: trafficserver/traffic/trunk/iocore/net/UnixNetAccept.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/net/UnixNetAccept.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/net/UnixNetAccept.cc (original)
+++ trafficserver/traffic/trunk/iocore/net/UnixNetAccept.cc Fri Sep  3 02:54:34 2010
@@ -127,6 +127,12 @@ net_accept(NetAccept * na, void *ep, boo
     vc->accept_port = ntohs(na->server.sa.sin_port);
     vc->mutex = new_ProxyMutex();
     vc->action_ = *na->action_;
+    vc->set_is_transparent(na->server.f_inbound_transparent);
+    vc->set_is_other_side_transparent(na->server.f_outbound_transparent);
+    Debug("http_tproxy", "Marking accepted %sconnection on %x as%s outbound transparent.\n",
+	  na->server.f_inbound_transparent ? "transparent " : "",
+	  na, na->server.f_outbound_transparent ? "" : " not"
+	  );
     vc->closed  = 0;
     SET_CONTINUATION_HANDLER(vc, (NetVConnHandler) & UnixNetVConnection::acceptEvent);
 
@@ -341,6 +347,12 @@ NetAccept::do_blocking_accept(NetAccept 
     vc->ip = vc->con.sa.sin_addr.s_addr;
     vc->port = ntohs(vc->con.sa.sin_port);
     vc->accept_port = ntohs(server.sa.sin_port);
+    vc->set_is_transparent(master_na->server.f_inbound_transparent);
+    vc->set_is_other_side_transparent(master_na->server.f_outbound_transparent);
+    Debug("http_tproxy", "Marking accepted %sconnect on %x as%s outbound transparent.\n",
+	  master_na->server.f_inbound_transparent ? "transparent " : "",
+	  master_na, master_na->server.f_outbound_transparent ? "" : " not"
+	  );
     vc->mutex = new_ProxyMutex();
     vc->action_ = *action_;
     SET_CONTINUATION_HANDLER(vc, (NetVConnHandler) & UnixNetVConnection::acceptEvent);
@@ -485,6 +497,12 @@ NetAccept::acceptFastEvent(int event, vo
     vc->ip = vc->con.sa.sin_addr.s_addr;
     vc->port = ntohs(vc->con.sa.sin_port);
     vc->accept_port = ntohs(server.sa.sin_port);
+    vc->set_is_transparent(server.f_inbound_transparent);
+    vc->set_is_other_side_transparent(server.f_outbound_transparent);
+    Debug("http_tproxy", "Marking fast accepted %sconnection on as%s outbound transparent.\n",
+	  server.f_inbound_transparent ? "transparent " : "",
+	  server.f_outbound_transparent ? "" : " not"
+	  );
     vc->mutex = new_ProxyMutex();
     vc->thread = e->ethread;
 

Modified: trafficserver/traffic/trunk/iocore/net/UnixNetProcessor.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/net/UnixNetProcessor.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/net/UnixNetProcessor.cc (original)
+++ trafficserver/traffic/trunk/iocore/net/UnixNetProcessor.cc Fri Sep  3 02:54:34 2010
@@ -31,6 +31,23 @@
 // Globals
 int use_accept_thread = 0;
 
+NetProcessor::AcceptOptions const NetProcessor::DEFAULT_ACCEPT_OPTIONS;
+
+NetProcessor::AcceptOptions&
+NetProcessor::AcceptOptions::reset()
+{
+  port = 0;
+  domain = AF_INET;
+  etype = ET_NET;
+  f_callback_on_open = false;
+  recv_bufsize = 0;
+  send_bufsize = 0;
+  sockopt_flags = 0;
+  f_outbound_transparent = false;
+  f_inbound_transparent = false;
+  return *this;
+}
+
 
 int net_connection_number = 1;
 unsigned int
@@ -62,37 +79,46 @@ NetProcessor::accept(Continuation * cont
   (void) accept_only;           // NT only
   (void) bound_sockaddr;        // NT only
   (void) bound_sockaddr_size;   // NT only
-  NetDebug("iocore_net_processor", "NetProcessor::accept - port %d,recv_bufsize %d, send_bufsize %d, sockopt 0x%0lX",
-        port, recv_bufsize, send_bufsize, sockopt_flags);
-  return ((UnixNetProcessor *) this)->accept_internal(cont, NO_FD, port,
+  NetDebug("iocore_net_processor",
+	   "NetProcessor::accept - port %d,recv_bufsize %d, send_bufsize %d, sockopt 0x%0lX",
+	   port, recv_bufsize, send_bufsize, sockopt_flags
+	   );
+
+  AcceptOptions opt;
+  opt.port = port;
+  opt.etype = etype;
+  opt.f_callback_on_open = callback_on_open;
+  opt.recv_bufsize = recv_bufsize;
+  opt.send_bufsize = send_bufsize;
+  opt.sockopt_flags = opt.sockopt_flags;
+  return ((UnixNetProcessor *) this)->accept_internal(cont, NO_FD,
                                                       bound_sockaddr,
                                                       bound_sockaddr_size,
                                                       frequent_accept,
                                                       net_accept,
-                                                      recv_bufsize, send_bufsize, sockopt_flags,
-                                                      accept_ip, callback_on_open, etype);
+                                                      accept_ip,
+						      opt
+						      );
 }
 
 Action *
-NetProcessor::main_accept(Continuation * cont, SOCKET fd, int port,
+NetProcessor::main_accept(Continuation * cont, SOCKET fd,
                           sockaddr * bound_sockaddr, int *bound_sockaddr_size,
                           bool accept_only,
-                          int recv_bufsize, int send_bufsize, unsigned long sockopt_flags,
-                          EventType etype, bool callback_on_open)
+			  AcceptOptions const& opt
+			  )
 {
   (void) accept_only;           // NT only
   NetDebug("iocore_net_processor", "NetProcessor::main_accept - port %d,recv_bufsize %d, send_bufsize %d, sockopt 0x%0lX",
-        port, recv_bufsize, send_bufsize, sockopt_flags);
-  return ((UnixNetProcessor *) this)->accept_internal(cont, fd, port,
+        opt.port, opt.recv_bufsize, opt.send_bufsize, opt.sockopt_flags);
+  return ((UnixNetProcessor *) this)->accept_internal(cont, fd,
                                                       bound_sockaddr,
                                                       bound_sockaddr_size,
                                                       true,
                                                       net_accept,
-                                                      recv_bufsize,
-                                                      send_bufsize,
-                                                      sockopt_flags,
                                                       ((UnixNetProcessor *) this)->incoming_ip_to_bind_saddr,
-                                                      callback_on_open, etype);
+						      opt
+						      );
 }
 
 
@@ -100,34 +126,36 @@ NetProcessor::main_accept(Continuation *
 Action *
 UnixNetProcessor::accept_internal(Continuation * cont,
                                   int fd,
-                                  int port,
                                   struct sockaddr * bound_sockaddr,
                                   int *bound_sockaddr_size,
                                   bool frequent_accept,
                                   AcceptFunction fn,
-                                  int recv_bufsize,
-                                  int send_bufsize,
-                                  unsigned long sockopt_flags,
-                                  unsigned int accept_ip, bool callback_on_open, EventType etype)
+                                  unsigned int accept_ip,
+				  AcceptOptions const& opt
+				  )
 {
-  setEtype(etype);
+  EventType et = opt.etype; // setEtype requires non-const ref.
+  setEtype(et);
   NetAccept *na = createNetAccept();
 
   EThread *thread = this_ethread();
   ProxyMutex *mutex = thread->mutex;
   NET_INCREMENT_DYN_STAT(net_accepts_currently_open_stat);
-  na->port = port;
+  na->port = opt.port;
   na->accept_fn = fn;
   na->server.fd = fd;
   na->server.accept_ip = accept_ip;
+  na->server.f_outbound_transparent = opt.f_outbound_transparent;
+  na->server.f_inbound_transparent = opt.f_inbound_transparent;
+  if (opt.f_outbound_transparent) Debug("http_tproxy", "Marking accept server %x on port %d as outbound transparent.\n", na, opt.port);
   na->action_ = NEW(new NetAcceptAction());
   *na->action_ = cont;
   na->action_->server = &na->server;
-  na->callback_on_open = callback_on_open;
-  na->recv_bufsize = recv_bufsize;
-  na->send_bufsize = send_bufsize;
-  na->sockopt_flags = sockopt_flags;
-  na->etype = etype;
+  na->callback_on_open = opt.f_callback_on_open;
+  na->recv_bufsize = opt.recv_bufsize;
+  na->send_bufsize = opt.send_bufsize;
+  na->sockopt_flags = opt.sockopt_flags;
+  na->etype = opt.etype;
   if (na->callback_on_open)
     na->mutex = cont->mutex;
   if (frequent_accept) { // true

Modified: trafficserver/traffic/trunk/libinktomi++/ink_config.h.in
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/libinktomi%2B%2B/ink_config.h.in?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/libinktomi++/ink_config.h.in (original)
+++ trafficserver/traffic/trunk/libinktomi++/ink_config.h.in Fri Sep  3 02:54:34 2010
@@ -111,12 +111,14 @@
 #define ATS_USE_PORT                    @use_port@
 #define ATS_USE_POSIX_CAP               @use_posix_cap@
 #define ATS_USE_DETAILED_LOG            @has_detailed_log@
+#define ATS_USE_TPROXY                  @use_tproxy@
 
 /* OS API definitions */
 #define GETHOSTBYNAME_R_HOSTENT_DATA    @gethostbyname_r_hostent_data@
 #define GETHOSTBYNAME_R_GLIBC2          @gethostbyname_r_glibc2@
 #define NEED_UNION_SEMUN                @need_union_semun@
 #define SIZEOF_VOID_POINTER             @ac_cv_sizeof_voidp@
+#define ATS_IP_TRANSPARENT              @ip_transparent@
 
 /* API */
 #define ATS_IS_MICRO_BUILD              @is_micro_build@

Modified: trafficserver/traffic/trunk/proxy/Main.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/Main.h?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/Main.h (original)
+++ trafficserver/traffic/trunk/proxy/Main.h Fri Sep  3 02:54:34 2010
@@ -125,6 +125,10 @@ struct HttpOtherPortEntry
 {
   int port;
   HttpPortTypes type;
+  /// Set if outbound connections (to origin servers) are transparent.
+  bool f_outbound_transparent;
+  /// Set if inbound connects (from client) are/were transparent.
+  bool f_inbound_transparent;
 };
 extern HttpOtherPortEntry *http_other_port_array;
 

Modified: trafficserver/traffic/trunk/proxy/SocksProxy.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/SocksProxy.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/SocksProxy.cc (original)
+++ trafficserver/traffic/trunk/proxy/SocksProxy.cc Fri Sep  3 02:54:34 2010
@@ -521,7 +521,9 @@ void
 start_SocksProxy(int port)
 {
   Debug("SocksProxy", "Accepting SocksProxy connections on port %d\n", port);
-  netProcessor.main_accept(NEW(new SocksAccepter), NO_FD, port);
+  NetProcessor::AcceptOptions opt;
+  opt.port = port;
+  netProcessor.main_accept(NEW(new SocksAccepter), NO_FD, 0, 0, false, opt);
 
   socksproxy_stat_block = RecAllocateRawStatBlock(socksproxy_stat_count);
 

Modified: trafficserver/traffic/trunk/proxy/hdrs/HTTP.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/hdrs/HTTP.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/hdrs/HTTP.cc (original)
+++ trafficserver/traffic/trunk/proxy/hdrs/HTTP.cc Fri Sep  3 02:54:34 2010
@@ -1469,6 +1469,53 @@ http_parse_te(const char *buf, int len, 
   return val;
 }
 
+void
+HTTPHdr::_fill_target_cache() const
+{
+  URL* url = this->url_get();
+  m_target_in_url = false;
+  m_port_in_header = false;
+  // Check in the URL first, then the HOST field.
+  if (0 != (m_host = url->host_get(&m_host_length))) {
+    m_target_in_url = true;
+    m_port = url->port_get();
+    m_port_in_header = 0 != url->port_get_raw();
+  } else if (0 != (m_host = const_cast<HTTPHdr*>(this)->value_get(MIME_FIELD_HOST, MIME_LEN_HOST, &m_host_length))) {
+    // Check for port in the host.
+    char const* colon = static_cast<char const*>(memchr(m_host, ':', m_host_length));
+    
+    if (colon) {
+      m_host_length = colon - m_host; // Length of just the host in the value.
+      m_port = 0;
+      for ( ++colon ; is_digit(*colon) ; ++colon )
+	m_port = m_port * 10 + *colon - '0';
+      m_port_in_header = 0 != m_port;
+    }
+    m_port = url_canonicalize_port(this->type_get(), m_port);
+  } else {
+    m_host_length = 0; // reset in case any earlier check corrupted it
+  }
+  m_target_cached = true;
+}
+
+void
+HTTPHdr::set_url_target_from_host_field(URL* url) {
+  this->_test_and_fill_target_cache();
+
+  if (!url) {
+    // Use local cached URL and don't copy if the target
+    // is already there.
+    if (!m_target_in_url && m_host_length) {
+      m_url_cached.host_set(m_host, m_host_length);
+      if (m_port_in_header) m_url_cached.port_set(m_port);
+      m_target_in_url = true; // it's there now.
+    }
+  } else {
+    url->host_set(m_host, m_host_length);
+    if (m_port_in_header) url->port_set(m_port);
+  }
+}
+
 /***********************************************************************
  *                                                                     *
  *                        M A R S H A L I N G                          *

Modified: trafficserver/traffic/trunk/proxy/hdrs/HTTP.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/hdrs/HTTP.h?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/hdrs/HTTP.h (original)
+++ trafficserver/traffic/trunk/proxy/hdrs/HTTP.h Fri Sep  3 02:54:34 2010
@@ -511,7 +511,7 @@ public:
   void set(HTTPVersion ver);
   void set(int ver_major, int ver_minor);
 
-    HTTPVersion & operator =(const HTTPVersion & hv);
+  HTTPVersion & operator =(const HTTPVersion & hv);
   int operator ==(const HTTPVersion & hv);
   int operator !=(const HTTPVersion & hv);
   int operator >(const HTTPVersion & hv);
@@ -529,10 +529,21 @@ class HTTPHdr:public MIMEHdr
 {
 public:
   HTTPHdrImpl * m_http;
-  URL m_url_cached;
+  // This is all cached data and so is mutable.
+  mutable URL m_url_cached;
+  mutable int m_host_length; ///< Length of hostname.
+  mutable char const* m_host; ///< Hostname.
+  mutable int m_port; ///< Target port.
+  mutable bool m_target_cached; ///< Whether host name and port are cached.
+  mutable bool m_target_in_url; ///< Whether host name and port are in the URL.
+  /// Set if the port was effectively specified in the header.
+  /// @c true if the target (in the URL or the HOST field) also specified
+  /// a port. That is, @c true if whatever source had the target host
+  /// also had a port, @c false otherwise.
+  mutable bool m_port_in_header;
 
-    HTTPHdr();
-   ~HTTPHdr();
+  HTTPHdr();
+  ~HTTPHdr();
 
   int valid() const;
 
@@ -559,13 +570,48 @@ public:
 
   URL *url_create(URL * url);
 
-  URL *url_get();
+  URL *url_get() const;
   URL *url_get(URL * url);
 
   void url_set(URL * url);
   void url_set_as_server_url(URL * url);
   void url_set(const char *str, int length);
 
+  /** Get the target host name.
+      The length is returned in @a length if non-NULL.
+      @note The results are cached so this is fast after the first call.
+      @return A pointer to the host name.
+  */
+  char const* host_get(int* length = 0);
+
+  /** Get the target port.
+      If the target port is not found then it is adjusted to the
+      default port for the URL type.
+      @note The results are cached so this is fast after the first call.
+      @return The canonicalized target port.
+  */
+  int port_get();
+
+  /// Check location of target host.
+  /// @return @c true if the host was in the URL, @c false otherwise.
+  /// @note This returns @c false if the host is missing.
+  bool is_target_in_url() const;
+
+  /// Check if a port was specified in the target.
+  /// @return @c true if the port was part of the target.
+  bool is_port_in_header() const;
+
+  /// If the target is in the fields and not the URL, copy it to the @a url.
+  /// If @a url is @c NULL the cached URL in this header is used.
+  /// @note In the default case the copy is avoided if the cached URL already
+  /// has the target. If @a url is non @c NULL the copy is always performed.
+  void set_url_target_from_host_field(URL* url = 0);
+
+  /// Mark the target cache as invalid.
+  /// @internal Ugly but too many places currently that touch the
+  /// header internals, they must be able to do this.
+  void mark_target_dirty();
+
   HTTPStatus status_get();
   void status_set(HTTPStatus status);
 
@@ -580,13 +626,25 @@ public:
 
 public:
   // Utility routines
-    bool is_cache_control_set(const char *cc_directive_wks);
+  bool is_cache_control_set(const char *cc_directive_wks);
   bool is_pragma_no_cache_set();
 
+protected:
+  /** Load the target cache.
+      @see m_host, m_port, m_target_in_url
+  */
+  void _fill_target_cache() const;
+  /** Test the cache and fill it if necessary.
+      @internal In contrast to @c _fill_target_cache, this method
+      is inline and checks whether the cache is already filled.
+      @ _fill_target_cache @b always does a cache fill.
+  */
+  void _test_and_fill_target_cache() const;
+
 private:
   // No gratuitous copies!
-    HTTPHdr(const HTTPHdr & m);
-    HTTPHdr & operator =(const HTTPHdr & m);
+  HTTPHdr(const HTTPHdr & m);
+  HTTPHdr & operator =(const HTTPHdr & m);
 };
 
 
@@ -703,7 +761,10 @@ HTTPVersion::operator <=(const HTTPVersi
   -------------------------------------------------------------------------*/
 
 inline HTTPHdr::HTTPHdr()
-:MIMEHdr(), m_http(NULL), m_url_cached()
+  : MIMEHdr()
+  , m_http(NULL)
+  , m_url_cached()
+  , m_target_cached(false)
 {
 }
 
@@ -821,6 +882,63 @@ HTTPHdr::length_get()
 /*-------------------------------------------------------------------------
   -------------------------------------------------------------------------*/
 
+inline void
+HTTPHdr::_test_and_fill_target_cache() const {
+  if (!m_target_cached) this->_fill_target_cache();
+}
+
+/*-------------------------------------------------------------------------
+  -------------------------------------------------------------------------*/
+
+inline char const*
+HTTPHdr::host_get(int* length)
+{
+  this->_test_and_fill_target_cache();
+  if (length) *length = m_host_length;
+  return m_host;
+}
+
+/*-------------------------------------------------------------------------
+  -------------------------------------------------------------------------*/
+
+inline int
+HTTPHdr::port_get()
+{
+  this->_test_and_fill_target_cache();
+  return m_port;
+}
+
+/*-------------------------------------------------------------------------
+  -------------------------------------------------------------------------*/
+
+inline bool
+HTTPHdr::is_target_in_url() const
+{
+  this->_test_and_fill_target_cache();
+  return m_target_in_url;
+}
+
+/*-------------------------------------------------------------------------
+  -------------------------------------------------------------------------*/
+
+inline bool
+HTTPHdr::is_port_in_header() const
+{
+  this->_test_and_fill_target_cache();
+  return m_port_in_header;
+}
+
+/*-------------------------------------------------------------------------
+  -------------------------------------------------------------------------*/
+
+inline void
+HTTPHdr::mark_target_dirty()
+{
+  m_target_cached = false;
+}
+/*-------------------------------------------------------------------------
+  -------------------------------------------------------------------------*/
+
 inline HTTPType
 http_hdr_type_get(HTTPHdrImpl * hh)
 {
@@ -920,7 +1038,7 @@ HTTPHdr::url_create(URL * u)
   -------------------------------------------------------------------------*/
 
 inline URL *
-HTTPHdr::url_get()
+HTTPHdr::url_get() const
 {
   ink_debug_assert(valid());
   ink_debug_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);

Modified: trafficserver/traffic/trunk/proxy/http2/HttpConfig.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http2/HttpConfig.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http2/HttpConfig.cc (original)
+++ trafficserver/traffic/trunk/proxy/http2/HttpConfig.cc Fri Sep  3 02:54:34 2010
@@ -1303,6 +1303,26 @@ HttpConfig::startup()
 
   HttpEstablishStaticConfigLongLong(c.post_copy_size, "proxy.config.http.post_copy_size");
 
+  // Transparency flag.
+  char buffer[10];
+  if (REC_ERR_OKAY ==  RecGetRecordString("proxy.config.http.transparent",
+					  buffer, sizeof(buffer))) {
+    if (0 == strcasecmp("both", buffer) ||
+	0 == strcasecmp("on", buffer) ||
+	0 == strcasecmp("enable", buffer)) {
+      c.client_transparency_enabled = true;
+      c.server_transparency_enabled = true;
+    } else if (0 == strcasecmp("server", buffer)) {
+      c.server_transparency_enabled = true;
+      c.client_transparency_enabled = false;
+    } else if (0 == strcasecmp("client", buffer)) {
+      c.server_transparency_enabled = false;
+      c.client_transparency_enabled = true;
+    } else {
+      c.server_transparency_enabled = false;
+      c.client_transparency_enabled = false;
+    }
+  }
 
   // Cluster time delta gets it own callback since it needs
   //  to use ink_atomic_swap

Modified: trafficserver/traffic/trunk/proxy/http2/HttpConfig.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http2/HttpConfig.h?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http2/HttpConfig.h (original)
+++ trafficserver/traffic/trunk/proxy/http2/HttpConfig.h Fri Sep  3 02:54:34 2010
@@ -611,7 +611,11 @@ public:
   //////////////////
   // Transparency //
   //////////////////
-  MgmtInt transparency_enabled;
+  MgmtInt transparency_enabled; ///< @b OBSOLETE
+  /// Accept connections on foreign addresses.
+  bool client_transparency_enabled;
+  /// Use client address to connect to origin server.
+  bool server_transparency_enabled;
 
   ///////////////////
   // reverse proxy //

Modified: trafficserver/traffic/trunk/proxy/http2/HttpProxyServerMain.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http2/HttpProxyServerMain.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http2/HttpProxyServerMain.cc (original)
+++ trafficserver/traffic/trunk/proxy/http2/HttpProxyServerMain.cc Fri Sep  3 02:54:34 2010
@@ -81,31 +81,64 @@ struct DumpStats: public Continuation
   }
 };
 
-HttpPortTypes
-get_connection_attributes(char *attr)
-{
-  HttpPortTypes attributes = SERVER_PORT_DEFAULT;
-  if (attr) {
-    if (strlen(attr) > 1) {
-      Warning("too many port attributes: '%s'", attr);
-    } else {
-      switch (*attr) {
-      case 'C':
-        attributes = SERVER_PORT_COMPRESSED;
-        break;
-      case 'X':
-        attributes = SERVER_PORT_DEFAULT;
-        break;
-      case 'T':
-        attributes = SERVER_PORT_BLIND_TUNNEL;
-        break;
-      default:
-        Warning("unknown port attribute '%s'", attr);
-        break;
-      }
+
+struct Attributes {
+  HttpPortTypes type;
+  int domain;
+  bool f_outbound_transparent;
+  bool f_inbound_transparent;
+
+  Attributes()
+    : type(SERVER_PORT_DEFAULT)
+    , domain(AF_INET)
+    , f_outbound_transparent(false)
+    , f_inbound_transparent(false)
+  {}
+};
+
+void get_connection_attributes(const char *attr, Attributes *result) {
+  int attr_len;
+
+  result->type = SERVER_PORT_DEFAULT;
+  result->domain = AF_INET;
+
+  if (!attr ) return;
+
+  attr_len = strlen(attr);
+
+  if (attr_len > 2) {
+    Warning("too many port attributes: '%s'", attr);
+    return;
+  } else if (attr_len <= 0) {
+    return;
+  }
+
+  switch (*attr) {
+  case 'C': result->type = SERVER_PORT_COMPRESSED; break;
+  case '<':
+    result->f_outbound_transparent = true;
+    result->type = SERVER_PORT_DEFAULT;
+    break;
+  case '=':
+    result->f_outbound_transparent = true;
+    result->f_inbound_transparent = true;
+    result->type = SERVER_PORT_DEFAULT;
+    break;
+  case '>':
+    result->f_inbound_transparent = true;
+    result->type = SERVER_PORT_DEFAULT;
+    break;
+  case 'X': result->type = SERVER_PORT_DEFAULT; break;
+  case 'T': result->type = SERVER_PORT_BLIND_TUNNEL; break;
+  default: Warning("unknown port attribute '%s'", attr); break;
+  }
+
+  if (attr_len >= 2) {
+    switch (*(attr + 1)) {
+    case '6': result->domain = AF_INET6; break;
+    default: result->domain = AF_INET;
     }
   }
-  return attributes;
 }
 
 
@@ -154,7 +187,12 @@ parse_http_server_other_ports()
     }
 
     additional_ports_array[accept_index].port = port;
-    additional_ports_array[accept_index].type = get_connection_attributes(attr_str);
+
+    Attributes attr;
+    get_connection_attributes(attr_str, &attr);
+    additional_ports_array[accept_index].type = attr.type;
+    additional_ports_array[accept_index].f_outbound_transparent = attr.f_outbound_transparent;
+    additional_ports_array[accept_index].f_inbound_transparent = attr.f_inbound_transparent;
 
     accept_index++;
   }
@@ -238,30 +276,40 @@ start_HttpProxyServer(int fd, int port, 
   ///////////////////////////////////
   // start accepting connections   //
   ///////////////////////////////////
-  int sock_recv_buffer_size_in = 0;
-  int sock_send_buffer_size_in = 0;
-  unsigned long sock_option_flag_in = 0;
   char *attr_string = 0;
-  static HttpPortTypes attr = SERVER_PORT_DEFAULT;
+  static HttpPortTypes type = SERVER_PORT_DEFAULT;
+  NetProcessor::AcceptOptions opt;
+  opt.port = port;
 
   if (!called_once) {
     // function can be called several times : do memory allocation once
     REC_ReadConfigStringAlloc(attr_string, "proxy.config.http.server_port_attr");
-    REC_ReadConfigInteger(sock_recv_buffer_size_in, "proxy.config.net.sock_recv_buffer_size_in");
-    REC_ReadConfigInteger(sock_send_buffer_size_in, "proxy.config.net.sock_send_buffer_size_in");
-    REC_ReadConfigInteger(sock_option_flag_in, "proxy.config.net.sock_option_flag_in");
+    REC_ReadConfigInteger(opt.recv_bufsize, "proxy.config.net.sock_recv_buffer_size_in");
+    REC_ReadConfigInteger(opt.send_bufsize, "proxy.config.net.sock_send_buffer_size_in");
+    REC_ReadConfigInteger(opt.sockopt_flags, "proxy.config.net.sock_option_flag_in");
 
     // deprecated configuration options - bcall 4/25/07
     // these should be removed in the future
-    if (sock_recv_buffer_size_in == 0 && sock_send_buffer_size_in == 0 && sock_option_flag_in == 0) {
-      REC_ReadConfigInteger(sock_recv_buffer_size_in, "proxy.config.net.sock_recv_buffer_size");
-      REC_ReadConfigInteger(sock_send_buffer_size_in, "proxy.config.net.sock_send_buffer_size");
-      REC_ReadConfigInteger(sock_option_flag_in, "proxy.config.net.sock_option_flag");
+    if (opt.recv_bufsize == 0 && opt.send_bufsize == 0 && opt.sockopt_flags == 0) {
+      REC_ReadConfigInteger(opt.recv_bufsize, "proxy.config.net.sock_recv_buffer_size");
+      REC_ReadConfigInteger(opt.send_bufsize, "proxy.config.net.sock_send_buffer_size");
+      REC_ReadConfigInteger(opt.sockopt_flags, "proxy.config.net.sock_option_flag");
     }
     // end of deprecated config options
 
     if (attr_string) {
-      attr = get_connection_attributes(attr_string);
+      Attributes attr;
+      get_connection_attributes(attr_string, &attr);
+      type = attr.type;
+      opt.domain = attr.domain;
+      Debug("http_tproxy", "Primary listen socket transparency is %s\n",
+	    attr.f_inbound_transparent &&  attr.f_outbound_transparent ? "bidirectional"
+	      : attr.f_inbound_transparent ? "inbound"
+	        : attr.f_outbound_transparent ? "outbound"
+                  : "off"
+	    );
+      opt.f_outbound_transparent = attr.f_outbound_transparent;
+      opt.f_inbound_transparent = attr.f_inbound_transparent;
       xfree(attr_string);
     }
     called_once = true;
@@ -269,8 +317,7 @@ start_HttpProxyServer(int fd, int port, 
       for (int i = 0; http_port_attr_array[i].fd != NO_FD; i++) {
         HttpPortEntry & e = http_port_attr_array[i];
         if (e.fd)
-          netProcessor.main_accept(NEW(new HttpAccept(e.type)), e.fd, 0, NULL, NULL, false,
-                                   sock_recv_buffer_size_in, sock_send_buffer_size_in, sock_option_flag_in);
+          netProcessor.main_accept(NEW(new HttpAccept(e.type)), e.fd, NULL, NULL, false, opt);
       }
     } else {
       // If traffic_server wasn't started with -A, get the list
@@ -279,33 +326,42 @@ start_HttpProxyServer(int fd, int port, 
     }
   }
   if (!http_port_attr_array) {
-    netProcessor.main_accept(NEW(new HttpAccept(attr)), fd, port, NULL, NULL, false,
-                             sock_recv_buffer_size_in, sock_send_buffer_size_in, sock_option_flag_in);
+    netProcessor.main_accept(NEW(new HttpAccept(type)), fd,  NULL, NULL, false,
+                             opt);
 
     if (http_other_port_array) {
       for (int i = 0; http_other_port_array[i].port != -1; i++) {
         HttpOtherPortEntry & e = http_other_port_array[i];
         if ((e.port<1) || (e.port> 65535))
           Warning("additional port out of range ignored: %d", e.port);
-        else
-          netProcessor.main_accept(NEW(new HttpAccept(e.type)), fd, e.port, NULL, NULL, false,
-                                   sock_recv_buffer_size_in, sock_send_buffer_size_in, sock_option_flag_in);
+        else {
+	  opt.port = e.port;
+	  opt.f_outbound_transparent = e.f_outbound_transparent;
+          netProcessor.main_accept(NEW(new HttpAccept(e.type)),
+				   fd, NULL, NULL, false, opt
+				   );
+	}
       }
     }
   } else {
     for (int i = 0; http_port_attr_array[i].fd != NO_FD; i++) {
       HttpPortEntry & e = http_port_attr_array[i];
       if (!e.fd) {
-        netProcessor.main_accept(NEW(new HttpAccept(attr)), fd, port, NULL, NULL, false,
-                                 sock_recv_buffer_size_in, sock_send_buffer_size_in, sock_option_flag_in);
+        netProcessor.main_accept(NEW(new HttpAccept(type)),
+				 fd, NULL, NULL, false, opt
+				 );
       }
     }
   }
 #ifdef HAVE_LIBSSL
   SslConfigParams *sslParam = sslTerminationConfig.acquire();
 
-  if (sslParam->getTerminationMode() & sslParam->SSL_TERM_MODE_CLIENT)
-    sslNetProcessor.main_accept(NEW(new HttpAccept(SERVER_PORT_SSL)), ssl_fd, sslParam->getAcceptPort());
+  if (sslParam->getTerminationMode() & sslParam->SSL_TERM_MODE_CLIENT) {
+    opt.reset();
+    opt.port = sslParam->getAcceptPort();
+    sslNetProcessor.main_accept(NEW(new HttpAccept(SERVER_PORT_SSL)), ssl_fd, 
+				0, 0, false, opt);
+  }
 
   sslTerminationConfig.release(sslParam);
 #endif
@@ -329,5 +385,8 @@ start_HttpProxyServer(int fd, int port, 
 void
 start_HttpProxyServerBackDoor(int port)
 {
-  netProcessor.main_accept(NEW(new HttpAccept(SERVER_PORT_DEFAULT, true)), NO_FD, port);
+  NetProcessor::AcceptOptions opt;
+  opt.port = port;
+  netProcessor.main_accept(NEW(new HttpAccept(SERVER_PORT_DEFAULT, true)),
+			   NO_FD, 0, 0, false, opt);
 }

Modified: trafficserver/traffic/trunk/proxy/http2/HttpSM.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http2/HttpSM.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http2/HttpSM.cc (original)
+++ trafficserver/traffic/trunk/proxy/http2/HttpSM.cc Fri Sep  3 02:54:34 2010
@@ -638,12 +638,14 @@ HttpSM::attach_client_session(HttpClient
   ua_entry->vc = client_vc;
   ua_entry->vc_type = HTTP_UA_VC;
 
-  t_state.client_info.ip = client_vc->get_netvc()->get_remote_ip();
-  t_state.client_info.port = client_vc->get_netvc()->get_local_port();
-  t_state.backdoor_request = client_vc->backdoor_connect;
+  NetVConnection* netvc = client_vc->get_netvc();
 
+  t_state.client_info.ip = netvc->get_remote_ip();
+  t_state.client_info.port = netvc->get_local_port();
+  t_state.client_info.is_transparent = netvc->get_is_transparent();
+  t_state.backdoor_request = client_vc->backdoor_connect;
 
-  t_state.client_info.port_attribute = (HttpPortTypes) client_vc->get_netvc()->attributes;
+  t_state.client_info.port_attribute = (HttpPortTypes) netvc->attributes;
 
   HTTP_INCREMENT_DYN_STAT(http_current_client_transactions_stat);
   client_vc->client_trans_stat++;
@@ -653,8 +655,8 @@ HttpSM::attach_client_session(HttpClient
 
 #ifdef USE_NCA
   if (t_state.client_info.port_attribute == SERVER_PORT_NCA) {
-    bool data_found = client_vc->get_netvc()->get_data(NCA_DATA_CACHE_UPCALL,
-                                                       &t_state.nca_info.request_info);
+    bool data_found = netvc->get_data(NCA_DATA_CACHE_UPCALL,
+				      &t_state.nca_info.request_info);
     ink_assert(data_found);
   } else {
 #else
@@ -4067,7 +4069,6 @@ HttpSM::do_cache_lookup_and_read()
 
   HTTP_INCREMENT_TRANS_STAT(http_cache_lookups_stat);
 
-  Debug("http_seq", "[HttpSM::do_cache_lookup_and_read] Issuing cache lookup");
   milestones.cache_open_read_begin = ink_get_hrtime();
   t_state.cache_lookup_result = HttpTransact::CACHE_LOOKUP_NONE;
   t_state.cache_info.lookup_count++;
@@ -4080,6 +4081,7 @@ HttpSM::do_cache_lookup_and_read()
   else
     c_url = t_state.cache_info.lookup_url;
 
+  Debug("http_seq", "[HttpSM::do_cache_lookup_and_read] [%lld] Issuing cache lookup for URL %s",  sm_id, c_url->string_get(&t_state.arena));
   Action *cache_action_handle = cache_sm.open_read(c_url,
                                                    &t_state.hdr_info.client_request,
                                                    &(t_state.cache_info.config),
@@ -4258,7 +4260,8 @@ HttpSM::do_http_server_open(bool raw)
   // to be based on ua_session != NULL instead of req_flavor value.
   ink_assert(ua_entry != NULL ||
              t_state.req_flavor == HttpTransact::REQ_FLAVOR_SCHEDULED_UPDATE ||
-             t_state.req_flavor == HttpTransact::REQ_FLAVOR_REVPROXY);
+             t_state.req_flavor == HttpTransact::REQ_FLAVOR_REVPROXY
+	     );
 
   ink_assert(pending_action == NULL);
   ink_assert(t_state.current.server->port > 0);
@@ -4268,13 +4271,15 @@ HttpSM::do_http_server_open(bool raw)
   opt.set_sock_param(t_state.http_config_param->sock_recv_buffer_size_out,
                      t_state.http_config_param->sock_send_buffer_size_out,
                      t_state.http_config_param->sock_option_flag_out);
-  // TBD: Check for transparency here and set opt accordingly.
+
   if (t_state.http_config_param->outgoing_ip_to_bind_saddr) {
     opt.addr_binding = NetVCOptions::INTF_ADDR;
     opt.local_addr = t_state.http_config_param->outgoing_ip_to_bind_saddr;
+  } else if (t_state.server_info.is_transparent) {
+    opt.addr_binding = NetVCOptions::FOREIGN_ADDR;
+    opt.local_addr = t_state.client_info.ip;
   }
 
-
   Debug("http", "[%lld] open connection to %s: %u.%u.%u.%u",
         sm_id, t_state.current.server->name, PRINT_IP(t_state.current.server->ip));
 

Modified: trafficserver/traffic/trunk/proxy/http2/HttpTransact.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http2/HttpTransact.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http2/HttpTransact.cc (original)
+++ trafficserver/traffic/trunk/proxy/http2/HttpTransact.cc Fri Sep  3 02:54:34 2010
@@ -292,7 +292,7 @@ find_server_and_update_current_info(Http
   URL *url = s->hdr_info.client_request.url_get();
 
   int host_len;
-  const char *host = url->host_get(&host_len);
+  const char *host = s->hdr_info.client_request.host_get(&host_len);
 
   if (ptr_len_cmp(host, host_len, local_host_ip_str, sizeof(local_host_ip_str) - 1) == 0) {
     // Do not forward requests to local_host onto a parent.
@@ -660,31 +660,15 @@ HttpTransact::HandleBlindTunnel(State * 
   HTTPVersion ver(0, 9);
   s->hdr_info.client_request.version_set(ver);
 
-  // Now we need to figure where the request is destined for
-  //   Two options.  First, we got the request for packets
-  //   sent through the arm layer.  If pick the address out that
-  //   way.  Otherwise, the client connected directly which means
-  //   we use our address and a remap rule is reuquired to send
-  //   request to it's proper destination
-  bool dest_found = false;
-  // ua_session is NULL for scheduled updates.
-  // Don't use req_flavor to do the test because if updated
-  // urls are remapped, the req_flavor is changed to REV_PROXY.
-  if (s->http_config_param->transparency_enabled && s->state_machine->ua_session != NULL) {
-    dest_found = setup_transparency(s);
-  }
-
-  if (dest_found == false) {
+  struct in_addr dest_addr;
+  dest_addr.s_addr = s->state_machine->ua_session->get_netvc()->get_local_ip();
 
-    struct in_addr dest_addr;
-    dest_addr.s_addr = s->state_machine->ua_session->get_netvc()->get_local_ip();
+  char *new_host = inet_ntoa(dest_addr);
+  s->hdr_info.client_request.url_get()->host_set(new_host, strlen(new_host));
+  // get_local_port() returns a port number in network order
+  // so it needs to be converted to host order (eg, in i386 machine)
+  s->hdr_info.client_request.url_get()->port_set(ntohs(s->state_machine->ua_session->get_netvc()->get_local_port()));
 
-    char *new_host = inet_ntoa(dest_addr);
-    s->hdr_info.client_request.url_get()->host_set(new_host, strlen(new_host));
-    // get_local_port() returns a port number in network order
-    // so it needs to be converted to host order (eg, in i386 machine)
-    s->hdr_info.client_request.url_get()->port_set(ntohs(s->state_machine->ua_session->get_netvc()->get_local_port()));
-  }
   // Intialize the state vars necessary to sending error responses
   bootstrap_state_variables_from_request(s, &s->hdr_info.client_request);
 
@@ -896,11 +880,10 @@ HttpTransact::EndRemapRequest(State * s)
   Debug("http_trans", "START HttpTransact::EndRemapRequest");
 
   HTTPHdr *incoming_request = &(s->hdr_info.client_request);
-  URL *url = incoming_request->url_get();
-  int host_len, method;
-  const char *host = url->host_get(&host_len);
-
-  method = incoming_request->method_get_wksidx();
+  //URL *url = incoming_request->url_get();
+  int method = incoming_request->method_get_wksidx();
+  int host_len;
+  const char *host = incoming_request->host_get(&host_len);
 
   ////////////////////////////////////////////////////////////////
   // if we got back a URL to redirect to, vector the user there //
@@ -954,45 +937,41 @@ HttpTransact::EndRemapRequest(State * s)
     /////////////////////////////////////////////////////////
     // check for: (1) reverse proxy is on, and no URL host //
     /////////////////////////////////////////////////////////
-    if (s->http_config_param->reverse_proxy_enabled && host == NULL) {
+    if (s->http_config_param->reverse_proxy_enabled
+	&& !s->client_info.is_transparent
+	&& !incoming_request->is_target_in_url()) {
       /////////////////////////////////////////////////////////
-      // the url mapping failed, reverse proxy was enabled,  //
-      // and the url contains no host:                       //
-      //                                                     //
-      // * if there is an explanatory redirect, send there   //
-      // * if there was no host header, send "no host" error //
-      // * if there was a host, say "not found"
+      // the url mapping failed, reverse proxy was enabled,
+      // and the request contains no host:
+      //
+      // * if there is an explanatory redirect, send there.
+      // * if there was no host, send "no host" error.
+      // * if there was a host, say "not found".
       /////////////////////////////////////////////////////////
 
       char *redirect_url = s->http_config_param->reverse_proxy_no_host_redirect;
       int redirect_url_len = s->http_config_param->reverse_proxy_no_host_redirect_len;
-
-      const char *host_hdr = incoming_request->value_get(MIME_FIELD_HOST, MIME_LEN_HOST,
-                                                         &host_len);
       SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
       if (redirect_url) {       /* there is a redirect url */
         build_error_response(s, HTTP_STATUS_MOVED_TEMPORARILY,
                              "Redirect For Explanation", "request#no_host", "\"<em>%s</em>\".<p>", redirect_url);
         s->hdr_info.client_response.value_set(MIME_FIELD_LOCATION, MIME_LEN_LOCATION, redirect_url, redirect_url_len);
-      } else if (host_hdr == NULL) {    /* no host header */
+      // Pavlov - here is where to handle getting the origin server address
+      // socket when there is no host. Need to handle DNS failure elsewhere.
+      } else if (host == NULL) {    /* no host */
         build_error_response(s, HTTP_STATUS_BAD_REQUEST,
                              "Host Header Required", "request#no_host",
                              ("Your browser did not send a \"Host:\" HTTP header, "
                               "so the virtual host being requested could not be "
                               "determined.  To access this site you will need "
                               "to upgrade to a modern browser that supports the HTTP " "\"Host:\" header field."));
-      } else {                  /* there was a host header */
-
+      } else {
         build_error_response(s, HTTP_STATUS_NOT_FOUND,
                              "Not Found on Accelerator", "urlrouting#no_mapping", "Your requested URL was not found.");
       }
       s->reverse_proxy = false;
       goto done;
-    }
-    ///////////////////////////////////////////////////////
-    // check for: (2) no mappings, but mappings required //
-    ///////////////////////////////////////////////////////
-    if (s->http_config_param->url_remap_required && !s->cop_test_page && !s->traffic_net_req) {
+    } else if (s->http_config_param->url_remap_required && !s->cop_test_page && !s->traffic_net_req) {
       ///////////////////////////////////////////////////////
       // the url mapping failed, but mappings are strictly //
       // required (except for synthetic cop accesses), so  //
@@ -1012,12 +991,15 @@ HttpTransact::EndRemapRequest(State * s)
     }
   }
   s->reverse_proxy = true;
+  s->server_info.is_transparent =
+    s->state_machine->ua_session->get_netvc()->get_is_other_side_transparent();
 
 done:
-        /**
-   * Since we don't want to return 404 Not Found error if there's redirect rule,
-   * the function to do redirect is moved before sending the 404 error.
-  **/
+  /**
+    * Since we don't want to return 404 Not Found error if there's
+    * redirect rule, the function to do redirect is moved before
+    * sending the 404 error.
+   **/
   if (handleIfRedirect(s)) {
     Debug("http_trans", "END HttpTransact::RemapRequest");
     TRANSACT_RETURN(PROXY_INTERNAL_CACHE_NOOP, NULL);
@@ -1054,18 +1036,20 @@ HttpTransact::ModifyRequest(State * s)
   const char *hostname;
   MIMEField *max_forwards_f;
   int max_forwards = -1;
+  HTTPHdr* request = &(s->hdr_info.client_request);
 
   Debug("http_trans", "START HttpTransact::ModifyRequest");
 
   // Intialize the state vars necessary to sending error responses
-  bootstrap_state_variables_from_request(s, &s->hdr_info.client_request);
+  bootstrap_state_variables_from_request(s, request);
 
   ////////////////////////////////////////////////
   // If there is no scheme default to http      //
   ////////////////////////////////////////////////
-  URL *url = s->hdr_info.client_request.url_get();
+  URL *url = request->url_get();
 
-  if ((hostname = url->host_get(&hostname_len)) == NULL)
+  hostname = request->host_get(&hostname_len);
+  if (!request->is_target_in_url())
     s->hdr_info.client_req_is_server_style = true;
 
   s->orig_scheme = (scheme = url->scheme_get_wksidx());
@@ -1080,7 +1064,8 @@ HttpTransact::ModifyRequest(State * s)
       s->orig_scheme = URL_WKSIDX_HTTP;
     }
   }
-  if (s->method == HTTP_WKSIDX_CONNECT && url->port_get() == 0)
+
+  if (s->method == HTTP_WKSIDX_CONNECT && !request->is_port_in_header())
     url->port_set(80);
 
   // If the incoming request is proxy-style AND contains a Host header,
@@ -1124,6 +1109,8 @@ HttpTransact::ModifyRequest(State * s)
 
     if (buf)
       xfree(buf);
+
+    request->mark_target_dirty();
   }
 
   if (s->http_config_param->normalize_ae_gzip) {
@@ -1141,16 +1128,6 @@ HttpTransact::ModifyRequest(State * s)
     }
   }
 
-  ////////////////////////////////////////////////////////
-  // First check for the presence of a host header or   //
-  // the availability of the host name through the url. //
-  ////////////////////////////////////////////////////////
-  // ua_session is NULL for scheduled updates.
-  // Don't use req_flavor to do the test because if updated
-  // urls are remapped, the req_flavor is changed to REV_PROXY.
-  if (s->http_config_param->transparency_enabled && s->state_machine->ua_session != NULL) {
-    setup_transparency(s);
-  }
   /////////////////////////////////////////////////////////
   // Modify Accept-Encoding for several specific User-Agent
   /////////////////////////////////////////////////////////
@@ -1574,7 +1551,7 @@ HttpTransact::ReDNSRoundRobin(State * s)
                           "Click the <B>Tools</b> menu, and then click <b>Internet Options</b>.  On the Advanced tab, "
                           "scroll to the Security section and check settings for SSL 2.0, SSL 3.0, TLS 1.0, PCT 1.0.</li>"
                           "<li id=\"list3\">Click the Back button to try another link.</li></ul><p><br></p><h2 id=\"PEText\""
-                          " style=\"font:8pt/11pt verdana; color:black\">502 - Cannot find server or DNS Error</h2></font>"
+                          " style=\"font:8pt/11pt verdana; color:black\">502 - Cannot find server or DNS Error [reDNS]</h2></font>"
                           "</td></tr> </table></body></html>"), s->server_info.name);
     s->cache_info.action = CACHE_DO_NO_ACTION;
     s->next_action = PROXY_SEND_ERROR_CACHE_NOOP;
@@ -1694,8 +1671,8 @@ HttpTransact::OSDNSLookup(State * s)
                             "Click the <B>Tools</b> menu, and then click <b>Internet Options</b>.  On the Advanced tab, "
                             "scroll to the Security section and check settings for SSL 2.0, SSL 3.0, TLS 1.0, PCT 1.0.</li>"
                             "<li id=\"list3\">Click the Back button to try another link.</li></ul><p><br></p><h2 id=\"PEText\""
-                            " style=\"font:8pt/11pt verdana; color:black\">502 - Cannot find server or DNS Error</h2></font>"
-                            "</td></tr> </table></body></html>"), s->server_info.name);
+                            " style=\"font:8pt/11pt verdana; color:black\">502 - Cannot find server or DNS Error [%s:%d]</h2></font>"
+                            "</td></tr> </table></body></html>"), s->server_info.name, host_name_expansion);
       // s->cache_info.action = CACHE_DO_NO_ACTION;
       TRANSACT_RETURN(PROXY_SEND_ERROR_CACHE_NOOP, NULL);
       break;
@@ -1717,10 +1694,7 @@ HttpTransact::OSDNSLookup(State * s)
   get_ka_info_from_host_db(s, &s->server_info, &s->client_info, &s->host_db_info, s->http_config_param);
   s->server_info.dns_round_robin = s->dns_info.round_robin;
   Debug("http_trans", "[OSDNSLookup] DNS lookup for O.S. successful "
-        "IP: %u.%u.%u.%u",
-        ((unsigned char *) &s->server_info.ip)[0],
-        ((unsigned char *) &s->server_info.ip)[1],
-        ((unsigned char *) &s->server_info.ip)[2], ((unsigned char *) &s->server_info.ip)[3]);
+        "IP: %u.%u.%u.%u", PRINT_IP(s->server_info.ip));
 
 
   //Added By YTS Team, yamsat
@@ -1946,13 +1920,19 @@ HttpTransact::DecideCacheLookup(State * 
     HTTP_DEBUG_ASSERT(s->current.mode != TUNNELLING_PROXY);
 
     if (s->cache_info.lookup_url == NULL) {
+      HTTPHdr* incoming_request = &(s->hdr_info.client_request);
 
       if (s->pristine_host_hdr > 0 || s->http_config_param->maintain_pristine_host_hdr) {
         s->cache_info.lookup_url_storage.create(NULL);
-        s->cache_info.lookup_url_storage.copy(s->hdr_info.client_request.url_get());
+        s->cache_info.lookup_url_storage.copy(incoming_request->url_get());
         s->cache_info.lookup_url = &(s->cache_info.lookup_url_storage);
+	// if the target isn't in the URL, put it in the copy for
+	// cache lookup.
+	incoming_request->set_url_target_from_host_field(s->cache_info.lookup_url);
       } else {
-        s->cache_info.lookup_url = s->hdr_info.client_request.url_get();
+	// make sure the target is in the URL.
+	incoming_request->set_url_target_from_host_field();
+        s->cache_info.lookup_url = incoming_request->url_get();
       }
 
       // *somebody* wants us to not hack the host header in a reverse proxy setup.
@@ -1964,7 +1944,7 @@ HttpTransact::DecideCacheLookup(State * 
 
         // So, the host header will have the original host header.
         int host_len;
-        const char *host_hdr = s->hdr_info.client_request.value_get(MIME_FIELD_HOST,
+        const char *host_hdr = incoming_request->value_get(MIME_FIELD_HOST,
                                                                     MIME_LEN_HOST, &host_len);
         if (host_hdr) {
           char *tmp;
@@ -4003,10 +3983,7 @@ HttpTransact::retry_server_connection_no
   char *url_string = url->valid()? url->string_get(&s->arena) : NULL;
 
   Debug("http_trans", "[%d] failed to connect [%d] to %u.%u.%u.%u",
-        s->current.attempts, conn_state,
-        ((unsigned char *) &s->current.server->ip)[0],
-        ((unsigned char *) &s->current.server->ip)[1],
-        ((unsigned char *) &s->current.server->ip)[2], ((unsigned char *) &s->current.server->ip)[3]);
+        s->current.attempts, conn_state, PRINT_IP(s->current.server->ip));
 
   //////////////////////////////////////////
   // on the first connect attempt failure //
@@ -4015,11 +3992,7 @@ HttpTransact::retry_server_connection_no
 
   if (!s->traffic_net_req) {
     Log::error("CONNECT:[%d] could not connect [%s] to %u.%u.%u.%u "
-               "for '%s'", s->current.attempts, HttpDebugNames::get_server_state_name(conn_state),
-               ((unsigned char *) &s->current.server->ip)[0],
-               ((unsigned char *) &s->current.server->ip)[1],
-               ((unsigned char *) &s->current.server->ip)[2],
-               ((unsigned char *) &s->current.server->ip)[3], url_string ? url_string : "<none>");
+               "for '%s'", s->current.attempts, HttpDebugNames::get_server_state_name(conn_state), PRINT_IP(s->current.server->ip), url_string ? url_string : "<none>");
   }
 
   if (url_string) {
@@ -5613,13 +5586,13 @@ HttpTransact::RequestError_t HttpTransac
     return FAILED_PROXY_AUTHORIZATION;
   }
 
+  URL *
+    incoming_url = incoming_hdr->url_get();
   int
     hostname_len;
-  URL *
-    incoming_url;
-  incoming_url = incoming_hdr->url_get();
   const char *
-    hostname = incoming_url->host_get(&hostname_len);
+    hostname = incoming_hdr->host_get(&hostname_len);
+
   if (hostname == NULL) {
     return MISSING_HOST_FIELD;
   }
@@ -5937,9 +5910,9 @@ HttpTransact::initialize_state_variables
   }
 
   int host_len;
-  const char *host = incoming_request->url_get()->host_get(&host_len);
+  const char *host = incoming_request->host_get(&host_len);
   s->server_info.name = s->arena.str_store(host, host_len);
-  s->server_info.port = incoming_request->url_get()->port_get();
+  s->server_info.port = incoming_request->port_get();
 
   if (second_time) {
     s->dns_info.attempts = 0;
@@ -5955,8 +5928,16 @@ HttpTransact::bootstrap_state_variables_
 }
 
 void
-HttpTransact::initialize_state_variables_from_request(State * s, HTTPHdr * incoming_request)
+HttpTransact::initialize_state_variables_from_request(State * s, HTTPHdr * obsolete_incoming_request)
 {
+  HTTPHdr* incoming_request = &(s->hdr_info.client_request);
+
+  // Temporary, until we're confident that the second argument is redundant.
+  ink_assert(incoming_request == obsolete_incoming_request);
+
+  int host_len;
+  const char *host_name = incoming_request->host_get(&host_len);
+
   // check if the request is conditional (IMS or INM)
   if (incoming_request->presence(MIME_PRESENCE_IF_MODIFIED_SINCE | MIME_PRESENCE_IF_NONE_MATCH)) {
     SET_VIA_STRING(VIA_CLIENT_REQUEST, VIA_CLIENT_IMS);
@@ -6018,10 +5999,8 @@ HttpTransact::initialize_state_variables
   }
 
   if (!s->server_info.name || s->redirect_info.redirect_in_process) {
-    int host_len;
-    const char *host = incoming_request->url_get()->host_get(&host_len);
-    s->server_info.name = s->arena.str_store(host, host_len);
-    s->server_info.port = incoming_request->url_get()->port_get();
+    s->server_info.name = s->arena.str_store(host_name, host_len);
+    s->server_info.port = incoming_request->port_get();
   } else {
     HTTP_DEBUG_ASSERT(s->server_info.port != 0);
   }
@@ -6087,10 +6066,8 @@ HttpTransact::initialize_state_variables
       enc_value = enc_val_iter.get_next(&enc_val_len);
     }
   }
-  int host_len;
-  const char *hostname = s->hdr_info.client_request.url_get()->host_get(&host_len);
   s->request_data.hdr = &s->hdr_info.client_request;
-  s->request_data.hostname_str = s->arena.str_store(hostname, host_len);
+  s->request_data.hostname_str = s->arena.str_store(host_name, host_len);
   s->request_data.src_ip = s->client_info.ip;
   s->request_data.dest_ip = 0;
   if (s->state_machine->ua_session) {
@@ -6985,17 +6962,6 @@ HttpTransact::service_transaction_in_pro
   return false;
 }
 
-bool
-HttpTransact::setup_transparency(State * s)
-{
-  NOWARN_UNUSED(s);
-  bool set = false;
-  /*
-   * NOTE: removed ARM code from here
-   */
-  return set;
-}
-
 void
 HttpTransact::process_quick_http_filter(State * s, int method)
 {

Modified: trafficserver/traffic/trunk/proxy/http2/HttpTransact.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http2/HttpTransact.h?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http2/HttpTransact.h (original)
+++ trafficserver/traffic/trunk/proxy/http2/HttpTransact.h Fri Sep  3 02:54:34 2010
@@ -805,7 +805,10 @@ public:
     AbortState_t abort;
     HttpPortTypes port_attribute;
 
-      _ConnectionAttributes():http_version(),
+    /// @c true if the connection is transparent.
+    bool is_transparent;
+
+  _ConnectionAttributes():http_version(),
       keep_alive(HTTP_KEEPALIVE_UNDEFINED),
       receive_chunked_response(false),
       pipeline_possible(false),
@@ -814,7 +817,11 @@ public:
       dns_round_robin(false),
       connect_failure(false),
       transfer_encoding(NO_TRANSFER_ENCODING),
-      ip(0), port(0), state(STATE_UNDEFINED), abort(ABORT_UNDEFINED), port_attribute(SERVER_PORT_DEFAULT)
+      ip(0), port(0),
+      state(STATE_UNDEFINED),
+      abort(ABORT_UNDEFINED),
+      port_attribute(SERVER_PORT_DEFAULT),
+      is_transparent(false)
     {
     };
   }
@@ -1202,7 +1209,7 @@ public:
   static bool handle_trace_and_options_requests(State * s, HTTPHdr * incoming_hdr);
   static void bootstrap_state_variables_from_request(State * s, HTTPHdr * incoming_request);
   static void initialize_state_variables_for_origin_server(State * s, HTTPHdr * incoming_request, bool second_time);
-  static void initialize_state_variables_from_request(State * s, HTTPHdr * incoming_request);
+  static void initialize_state_variables_from_request(State * s, HTTPHdr * obsolete_incoming_request);
   static void initialize_state_variables_from_response(State * s, HTTPHdr * incoming_response);
   static bool is_server_negative_cached(State * s);
   static bool is_cache_response_returnable(State * s);
@@ -1218,7 +1225,6 @@ public:
 //    static bool setup_reverse_proxy(State *s,HTTPHdr *incoming_request);
   static void process_quick_http_filter(State * s, int method);
 
-  static bool setup_transparency(State * s);
   static bool perform_accept_encoding_filtering(State * s);
 
   static HostNameExpansionError_t try_to_expand_host_name(State * s);

Modified: trafficserver/traffic/trunk/proxy/http2/remap/RemapProcessor.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http2/remap/RemapProcessor.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http2/remap/RemapProcessor.cc (original)
+++ trafficserver/traffic/trunk/proxy/http2/remap/RemapProcessor.cc Fri Sep  3 02:54:34 2010
@@ -50,8 +50,9 @@ RemapProcessor::setup_for_remap(HttpTran
   char **redirect_url = &s->remap_redirect;
   char **orig_url = &s->unmapped_request_url;
   char *tag = NULL;
-  const char *request_url_host;
-  int request_url_host_len;
+  const char *request_host;
+  int request_host_len;
+  int request_port;
   bool proxy_request = false;
 
   s->reverse_proxy = rewrite_table->reverse_proxy;
@@ -72,79 +73,44 @@ RemapProcessor::setup_for_remap(HttpTran
     return false;
   }
 
-  request_url_host = request_url->host_get(&request_url_host_len);
-  if (request_url_host_len > 0 || s->reverse_proxy == false) {
-    Debug("url_rewrite", "[lookup] attempting proxy lookup");
-    // Proxy request.  Use the information from the URL on the
-    //  request line.  (Note: we prefer the information in
-    //  the request URL since some user-agents send broken
-    //  host headers.)
-    proxy_request = true;
-    mapping_found =
-      rewrite_table->forwardMappingLookup(request_url, request_url->port_get(), request_url_host,
-                                          request_url_host_len, s->url_map, tag);
-  } else {
-    // Server request.  Use the host header to figure out where
-    // it goes
-    int host_len, host_hdr_len;
-    const char *host_hdr = request_header->value_get(MIME_FIELD_HOST, MIME_LEN_HOST, &host_hdr_len);
-    if (!host_hdr) {
-      host_hdr = "";
-      host_hdr_len = 0;
-    }
-    char *tmp = (char *) memchr(host_hdr, ':', host_hdr_len);
-    int request_port;
+  request_host = request_header->host_get(&request_host_len);
+  request_port = request_header->port_get();
+  proxy_request = request_header->is_target_in_url() || ! s->reverse_proxy;
+
+  // Default to empty host.
+  if (!request_host) {
+    request_host = "";
+    request_host_len = 0;
+  }
 
-    if (tmp == NULL) {
-      host_len = host_hdr_len;
-      // Get the default port from URL structure
-      request_port = request_url->port_get();
-    } else {
-      host_len = tmp - host_hdr;
-      request_port = ink_atoi(tmp + 1, host_hdr_len - host_len);
+  Debug("url_rewrite", "[lookup] attempting %s lookup", proxy_request ? "proxy" : "normal");
 
-      // If atoi fails, try the default for the
-      //   protocol
-      if (request_port == 0) {
-        request_port = request_url->port_get();
-      }
-    }
+  mapping_found = rewrite_table->forwardMappingLookup(request_url, request_port, request_host, request_host_len, s->url_map, tag);
 
-    Debug("url_rewrite", "[lookup] attempting normal lookup");
-    mapping_found = rewrite_table->forwardMappingLookup(request_url, request_port, host_hdr, host_len,
-                                                        s->url_map, tag);
+  if (!proxy_request) { // do extra checks on a server request
 
     // Save this information for later
-    s->hh_info.host_len = host_len;
-    s->hh_info.request_host = host_hdr;
+    // @amc: why is this done only for requests without a host in the URL?
+    s->hh_info.host_len = request_host_len;
+    s->hh_info.request_host = request_host;
     s->hh_info.request_port = request_port;
 
-    // If no rules match, check empty host rules since
-    //   they function as default rules for server requests
-    if (!mapping_found && rewrite_table->nohost_rules && *host_hdr != '\0') {
+    // If no rules match and we have a host, check empty host rules since
+    // they function as default rules for server requests.
+    // If there's no host, we've already done this.
+    if (!mapping_found && rewrite_table->nohost_rules && request_host_len) {
       Debug("url_rewrite", "[lookup] nothing matched");
       mapping_found = rewrite_table->forwardMappingLookup(request_url, 0, "", 0, s->url_map, tag);
     }
 
     if (mapping_found && orig_url) {
-      // We need to insert the host so that we have an accurate URL
-      if (proxy_request == false) {
-        request_url->host_set(s->hh_info.request_host, s->hh_info.host_len);
-        // Only set the port if we need to so default ports
-        //  do show up in URLs
-        if (request_url->port_get() != s->hh_info.request_port) {
-          request_url->port_set(s->hh_info.request_port);
-        }
-      }
+      // Downstream mapping logic (e.g., self::finish_remap())
+      // apparently assumes the presence of the target in the URL, so
+      // we need to copy it. Perhaps it's because it's simpler to just
+      // do the remap on the URL and then fix the field at the end.
+      request_header->set_url_target_from_host_field();
       *orig_url = request_url->string_get_ref(NULL);
     }
-    // if (!map) {
-    //   char * u = request_url->string_get( NULL );
-    //   Debug("url_rewrite","RemapProcessor::setup_for_remap had map as NULL ==> ru:%s rp:%d h:%.*s t:%s", u , request_port, host_len,
-    //        host_hdr, tag);
-    //      if (u)
-    //     xfree(u);
-    // }
   }
 
   if (!mapping_found) {

Modified: trafficserver/traffic/trunk/proxy/mgmt2/LocalManager.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/mgmt2/LocalManager.cc?rev=992187&r1=992186&r2=992187&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/mgmt2/LocalManager.cc (original)
+++ trafficserver/traffic/trunk/proxy/mgmt2/LocalManager.cc Fri Sep  3 02:54:34 2010
@@ -44,7 +44,7 @@
 #include <sys/capability.h>
 #endif
 
-int bindProxyPort(int, in_addr_t, int);
+int bindProxyPort(int, in_addr_t, bool, int);
 
 bool
 LocalManager::SetForDup(void *hIOCPort, long lTProcId, void *hTh)
@@ -1272,13 +1272,19 @@ LocalManager::listenForProxy()
     if (proxy_server_port[i] != -1) {
 
       if (proxy_server_fd[i] < 0) {
+	bool transparent = false;
+
         switch (*proxy_server_port_attributes[i]) {
         case 'D':
           // D is for DNS proxy, udp only
-          proxy_server_fd[i] = bindProxyPort(proxy_server_port[i], proxy_server_incoming_ip_to_bind, SOCK_DGRAM);
+          proxy_server_fd[i] = bindProxyPort(proxy_server_port[i], proxy_server_incoming_ip_to_bind, transparent, SOCK_DGRAM);
           break;
+	case '>': // in-bound (client side) transparent
+	case '=': // fully transparent
+	  transparent = true;
+	  // *FALLTHROUGH*
         default:
-          proxy_server_fd[i] = bindProxyPort(proxy_server_port[i], proxy_server_incoming_ip_to_bind, SOCK_STREAM);
+          proxy_server_fd[i] = bindProxyPort(proxy_server_port[i], proxy_server_incoming_ip_to_bind, transparent, SOCK_STREAM);
         }
       }
 
@@ -1368,7 +1374,7 @@ restoreRootPriv(uid_t *old_euid)
  *  Also, type specifies udp or tcp
  */
 int
-bindProxyPort(int proxy_port, in_addr_t incoming_ip_to_bind, int type)
+bindProxyPort(int proxy_port, in_addr_t incoming_ip_to_bind, bool transparent,  int type)
 {
   int one = 1;
   struct sockaddr_in proxy_addr;
@@ -1400,6 +1406,15 @@ bindProxyPort(int proxy_port, in_addr_t 
     _exit(1);
   }
 
+  if (transparent) {
+    int transparent_value = 1;
+    Debug("http_tproxy", "Listen port %d inbound transparency enabled.\n", proxy_port);
+    if (setsockopt(proxy_port_fd, SOL_IP, ATS_IP_TRANSPARENT, &transparent_value, sizeof(transparent_value)) == -1) {
+      mgmt_elog(stderr, "[bindProxyPort] Unable to set transparent socket option [%d] %s\n", errno, strerror(errno));
+      _exit(1);
+    }
+  }
+
   memset(&proxy_addr, 0, sizeof(proxy_addr));
   proxy_addr.sin_family = AF_INET;
   proxy_addr.sin_addr.s_addr = incoming_ip_to_bind;