You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2014/07/30 18:38:13 UTC

git commit: TS-2802: add SNI support for origin server connections

Repository: trafficserver
Updated Branches:
  refs/heads/master 63ce14d10 -> c030977ab


TS-2802: add SNI support for origin server connections

Set the SNI name when making SSL origin server connections. Update
IP address literal parsing to accept ptr+len pairs as well as
NUL-terminated strings. This required removing default arguments
in the ConstBuffer constructor, since they cause nasty implicit
conversions.


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

Branch: refs/heads/master
Commit: c030977ab94cc05b48e7a578b9fa1de4949b026d
Parents: 63ce14d
Author: Wei Sun <su...@yahoo-inc.com>
Authored: Wed Jul 30 08:53:12 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Wed Jul 30 09:25:26 2014 -0700

----------------------------------------------------------------------
 CHANGES                           |  3 +++
 iocore/net/I_NetVConnection.h     | 33 ++++++++++++++++++++++++++++++++-
 iocore/net/P_UnixNetVConnection.h |  3 +++
 iocore/net/SSLNetVConnection.cc   | 10 ++++++++++
 lib/ts/TsBuffer.h                 | 14 ++++++--------
 lib/ts/ink_inet.cc                |  4 ++--
 lib/ts/ink_inet.h                 | 20 +++++++++++++++++---
 proxy/ControlBase.cc              |  4 ++--
 proxy/hdrs/MIME.cc                |  2 +-
 proxy/hdrs/URL.cc                 |  2 +-
 proxy/http/HttpSM.cc              |  3 +++
 11 files changed, 80 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index a5c7dbd..d21fc8a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 5.1.0
 
+  *) [TS-2802] Add SNI support for origin server connections.
+   Author: Wei Sun <su...@yahoo-inc.com>
+
   *) [TS-2958] url_sig: remove printf's and make redirects use appropriate
    status codes.
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/iocore/net/I_NetVConnection.h
----------------------------------------------------------------------
diff --git a/iocore/net/I_NetVConnection.h b/iocore/net/I_NetVConnection.h
index 5223267..dcf86a7 100644
--- a/iocore/net/I_NetVConnection.h
+++ b/iocore/net/I_NetVConnection.h
@@ -159,21 +159,52 @@ struct NetVCOptions {
 
   EventType etype;
 
+  char * sni_servername; // SSL SNI to origin
+
   /// Reset all values to defaults.
   void reset();
 
   void set_sock_param(int _recv_bufsize, int _send_bufsize, unsigned long _opt_flags,
                       unsigned long _packet_mark = 0, unsigned long _packet_tos = 0);
 
-  NetVCOptions() {
+  NetVCOptions() : sni_servername(NULL) {
     reset();
   }
 
+  ~NetVCOptions() {
+    ats_free(sni_servername);
+  }
+
+  void set_sni_servername(const char * name, size_t len) {
+    IpEndpoint ip;
+
+    ats_free(sni_servername);
+    sni_servername = NULL;
+    // Literal IPv4 and IPv6 addresses are not permitted in "HostName".(rfc6066#section-3)
+    if (ats_ip_pton(ts::ConstBuffer(name, len), &ip) != 0) {
+      sni_servername = ats_strndup(name, len);
+    }
+  }
+
+  NetVCOptions & operator=(const NetVCOptions & opt) {
+    if (&opt != this) {
+      ats_free(this->sni_servername);
+      memcpy(this, &opt, sizeof(opt));
+      if (opt.sni_servername) {
+        this->sni_servername = ats_strdup(opt.sni_servername);
+      }
+    }
+    return *this;
+  }
+
   /// @name Debugging
   //@{
   /// Convert @a s to its string equivalent.
   static char const* toString(addr_bind_style s);
   //@}
+
+private:
+  NetVCOptions(const NetVCOptions&);
 };
 
 /**

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/iocore/net/P_UnixNetVConnection.h
----------------------------------------------------------------------
diff --git a/iocore/net/P_UnixNetVConnection.h b/iocore/net/P_UnixNetVConnection.h
index 867b11d..0b7845e 100644
--- a/iocore/net/P_UnixNetVConnection.h
+++ b/iocore/net/P_UnixNetVConnection.h
@@ -65,6 +65,9 @@ NetVCOptions::reset()
   packet_tos = 0;
 
   etype = ET_NET;
+
+  ats_free(sni_servername);
+  sni_servername = NULL;
 }
 
 TS_INLINE void

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/iocore/net/SSLNetVConnection.cc
----------------------------------------------------------------------
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 67aabbc..0f4a6b3 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -648,6 +648,16 @@ SSLNetVConnection::sslClientHandShakeEvent(int &err)
 {
   int ret;
 
+#if TS_USE_TLS_SNI
+  if (options.sni_servername) {
+    if (SSL_set_tlsext_host_name(ssl, options.sni_servername)) {
+      Debug("ssl", "using SNI name '%s' for client handshake", options.sni_servername);
+    } else {
+      SSLError("failed to set SNI name '%s' for client handshake", options.sni_servername);
+    }
+  }
+#endif
+
   ret = SSL_connect(ssl);
   switch (SSL_get_error(ssl, ret)) {
   case SSL_ERROR_NONE:

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/lib/ts/TsBuffer.h
----------------------------------------------------------------------
diff --git a/lib/ts/TsBuffer.h b/lib/ts/TsBuffer.h
index dbcd72e..1abc6fe 100644
--- a/lib/ts/TsBuffer.h
+++ b/lib/ts/TsBuffer.h
@@ -53,7 +53,6 @@ namespace ts {
     size_t _size; ///< Size of memory chunk.
 
     /// Default constructor.
-    /// Elements are in uninitialized state.
     Buffer();
 
     /** Construct from pointer and size.
@@ -62,7 +61,7 @@ namespace ts {
      */
     Buffer(
       char* ptr, ///< Pointer to buffer.
-      size_t n = 0 ///< Size of buffer.
+      size_t n  ///< Size of buffer.
     );
     /** Construct from two pointers.
 	@note This presumes a half open range, (start, end]
@@ -143,7 +142,6 @@ namespace ts {
     size_t _size; ///< Size of memory chunk.
 
     /// Default constructor.
-    /// Elements are in uninitialized state.
     ConstBuffer();
 
     /** Construct from pointer and size.
@@ -152,7 +150,7 @@ namespace ts {
      */
     ConstBuffer(
       char const * ptr, ///< Pointer to buffer.
-      size_t n = 0///< Size of buffer.
+      size_t n ///< Size of buffer.
     );
     /** Construct from two pointers.
 	@note This presumes a half open range (start, end]
@@ -305,7 +303,7 @@ namespace ts {
   // ----------------------------------------------------------
   // Inline implementations.
 
-  inline Buffer::Buffer() { }
+  inline Buffer::Buffer() : _ptr(NULL), _size(0) { }
   inline Buffer::Buffer(char* ptr, size_t n) : _ptr(ptr), _size(n) { }
   inline Buffer& Buffer::set(char* ptr, size_t n) { _ptr = ptr; _size = n; return *this; }
   inline Buffer::Buffer(char* start, char* end) : _ptr(start), _size(end - start) { }
@@ -329,7 +327,7 @@ namespace ts {
   inline char * Buffer::data() const { return _ptr; }
   inline size_t Buffer::size() const { return _size; }
 
-  inline ConstBuffer::ConstBuffer() { }
+  inline ConstBuffer::ConstBuffer() : _ptr(NULL), _size(0) { }
   inline ConstBuffer::ConstBuffer(char const* ptr, size_t n) : _ptr(ptr), _size(n) { }
   inline ConstBuffer::ConstBuffer(char const* start, char const* end) : _ptr(start), _size(end - start) { }
   inline ConstBuffer::ConstBuffer(Buffer const& that) : _ptr(that._ptr), _size(that._size) { }
@@ -372,7 +370,7 @@ namespace ts {
   }
 
   inline ConstBuffer ConstBuffer::splitOn(char const* p) {
-    self zret(0); // default to empty return.
+    self zret; // default to empty return.
     if (this->contains(p)) {
       size_t n = p - _ptr;
       zret.set(_ptr, n);
@@ -391,7 +389,7 @@ namespace ts {
   }
 
   inline ConstBuffer ConstBuffer::after(char const* p) const {
-    return this->contains(p) ? self(p + 1, (_size-(p-_ptr))-1) : self(0);
+    return this->contains(p) ? self(p + 1, (_size-(p-_ptr))-1) : self();
   }
   inline ConstBuffer ConstBuffer::after(char c) const {
     return this->after(this->find(c));

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/lib/ts/ink_inet.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_inet.cc b/lib/ts/ink_inet.cc
index 3221ab2..5cff34f 100644
--- a/lib/ts/ink_inet.cc
+++ b/lib/ts/ink_inet.cc
@@ -246,10 +246,10 @@ ats_ip_parse(ts::ConstBuffer src, ts::ConstBuffer* addr, ts::ConstBuffer* port)
 }
 
 int
-ats_ip_pton(char const* text, sockaddr* ip) {
+ats_ip_pton(const ts::ConstBuffer& src, sockaddr* ip)
+{
   int zret = -1;
   ts::ConstBuffer addr, port;
-  ts::ConstBuffer src(text, strlen(text)+1);
 
   ats_ip_invalidate(ip);
   if (0 == ats_ip_parse(src, &addr, &port)) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/lib/ts/ink_inet.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_inet.h b/lib/ts/ink_inet.h
index fcaca0d..30ebc8f 100644
--- a/lib/ts/ink_inet.h
+++ b/lib/ts/ink_inet.h
@@ -953,7 +953,7 @@ inline char const* ats_ip_nptop(
     @return 0 on success, non-zero on failure.
 */
 int ats_ip_pton(
-  char const* text, ///< [in] text.
+  const ts::ConstBuffer& text, ///< [in] text.
   sockaddr* addr ///< [out] address
 );
 
@@ -972,16 +972,30 @@ inline int ats_ip_pton(
   char const* text, ///< [in] text.
   sockaddr_in6* addr ///< [out] address
 ) {
-  return ats_ip_pton(text, ats_ip_sa_cast(addr));
+  return ats_ip_pton(ts::ConstBuffer(text, strlen(text)), ats_ip_sa_cast(addr));
 }
 
 inline int ats_ip_pton(
-  char const* text, ///< [in] text.
+  const ts::ConstBuffer& text, ///< [in] text.
   IpEndpoint* addr ///< [out] address
 ) {
   return ats_ip_pton(text, &addr->sa);
 }
 
+inline int ats_ip_pton(
+  const char * text, ///< [in] text.
+  IpEndpoint* addr ///< [out] address
+) {
+  return ats_ip_pton(ts::ConstBuffer(text, strlen(text)), &addr->sa);
+}
+
+inline int ats_ip_pton(
+  const char * text, ///< [in] text.
+  sockaddr * addr ///< [out] address
+) {
+  return ats_ip_pton(ts::ConstBuffer(text, strlen(text)), addr);
+}
+
 /** Get the best address info for @a name.
 
     @name is passed to @c getaddrinfo which does a host lookup if @a

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/proxy/ControlBase.cc
----------------------------------------------------------------------
diff --git a/proxy/ControlBase.cc b/proxy/ControlBase.cc
index 710f3be..be24137 100644
--- a/proxy/ControlBase.cc
+++ b/proxy/ControlBase.cc
@@ -350,7 +350,7 @@ struct TextMod : public ControlBase::Modifier {
 
 };
 
-TextMod::TextMod() : text(0) {}
+TextMod::TextMod() : text() {}
 TextMod::~TextMod() {
   free(text.data());
 }
@@ -390,7 +390,7 @@ void MultiTextMod::set(char * value) {
   Tokenizer rangeTok(",");
   int num_tok = rangeTok.Initialize(value, SHARE_TOKS);
   for(int i = 0; i < num_tok; i++){
-    ts::Buffer text(0);
+    ts::Buffer text;
     text.set(ats_strdup(rangeTok[i]), strlen(rangeTok[i]));
     this->text_vec.push_back(text);
   }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/proxy/hdrs/MIME.cc
----------------------------------------------------------------------
diff --git a/proxy/hdrs/MIME.cc b/proxy/hdrs/MIME.cc
index 2cf3e9b..18976a2 100644
--- a/proxy/hdrs/MIME.cc
+++ b/proxy/hdrs/MIME.cc
@@ -2160,7 +2160,7 @@ MIMEField* MIMEHdr::get_host_port_values(
 
   if (field) {
     ts::ConstBuffer b(field->m_ptr_value, field->m_len_value);
-    ts::ConstBuffer host(0), port(0);
+    ts::ConstBuffer host, port;
 
     if (b) {
       char const* x;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/proxy/hdrs/URL.cc
----------------------------------------------------------------------
diff --git a/proxy/hdrs/URL.cc b/proxy/hdrs/URL.cc
index 65930e9..732e018 100644
--- a/proxy/hdrs/URL.cc
+++ b/proxy/hdrs/URL.cc
@@ -1167,7 +1167,7 @@ url_parse_internet(HdrHeap* heap, URLImpl* url,
   char const* cur = *start;
   char const* base; // Base for host/port field.
   char const* bracket = 0; // marker for open bracket, if any.
-  ts::ConstBuffer user(0), passw(0), host(0), port(0);
+  ts::ConstBuffer user, passw, host, port;
   static size_t const MAX_COLON = 8; // max # of valid colons.
   size_t n_colon = 0;
   char const* last_colon = 0; // pointer to last colon seen.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/c030977a/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 5d7239c..e7c6d2f 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -4641,6 +4641,9 @@ HttpSM::do_http_server_open(bool raw)
 
   if (scheme_to_use == URL_WKSIDX_HTTPS) {
     DebugSM("http", "calling sslNetProcessor.connect_re");
+    int len = 0;
+    const char * host = t_state.hdr_info.server_request.host_get(&len);
+    opt.set_sni_servername(host, len);
     connect_action_handle = sslNetProcessor.connect_re(this,    // state machine
                                                        &t_state.current.server->addr.sa,    // addr + port
                                                        &opt);