You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by so...@apache.org on 2016/11/07 17:39:02 UTC

[trafficserver] branch 6.2.x updated: TS-4697: Free MIOBuffer if the ipallow check fails.

This is an automated email from the ASF dual-hosted git repository.

sorber pushed a commit to branch 6.2.x
in repository https://git-dual.apache.org/repos/asf/trafficserver.git

The following commit(s) were added to refs/heads/6.2.x by this push:
       new  f82a44c   TS-4697: Free MIOBuffer if the ipallow check fails.
f82a44c is described below

commit f82a44c24b0dde47454327d37d52299321776046
Author: Oknet Xu <xu...@skyguard.com.cn>
AuthorDate: Sat Jul 23 20:15:11 2016 +0800

    TS-4697: Free MIOBuffer if the ipallow check fails.
    
    (cherry picked from commit 40b7b484869c1876d7f82953828524c393e650ca)
    
    With minor revision of SpdySessionAccept.
---
 iocore/net/I_SessionAccept.h         | 38 +++++++++++++++++++++++++++++++++++-
 iocore/net/P_SSLNextProtocolAccept.h |  2 +-
 iocore/net/SSLNextProtocolAccept.cc  |  3 ++-
 proxy/ProtocolProbeSessionAccept.cc  | 12 +++++++-----
 proxy/ProtocolProbeSessionAccept.h   |  2 +-
 proxy/http/HttpSessionAccept.cc      | 13 +++++++-----
 proxy/http/HttpSessionAccept.h       |  2 +-
 proxy/http2/Http2SessionAccept.cc    | 13 ++++++++----
 proxy/http2/Http2SessionAccept.h     |  2 +-
 proxy/spdy/SpdySessionAccept.cc      | 11 ++++++-----
 proxy/spdy/SpdySessionAccept.h       |  2 +-
 11 files changed, 74 insertions(+), 26 deletions(-)

diff --git a/iocore/net/I_SessionAccept.h b/iocore/net/I_SessionAccept.h
index 9e36b81..aadf4b2 100644
--- a/iocore/net/I_SessionAccept.h
+++ b/iocore/net/I_SessionAccept.h
@@ -29,12 +29,48 @@
 
 struct AclRecord;
 
+/**
+   The base class SessionAccept can not be used directly. The inherited class of
+   SessionAccept (ex. HttpSessionAccept) is designed to:
+
+     - Check IPAllow policy.
+     - Create ClientSession.
+     - Pass NetVC and MIOBuffer by call ClientSession::new_connection().
+
+   NULL mutex:
+
+     - One specific protocol has ONLY one inherited class of SessionAccept.
+     - The object of this class is shared by all incoming request / NetVC that
+       identified as the protocol by ProtocolSessionProbe.
+     - The inherited class of SessionAccept is non-blocking to allow parallel accepts/
+
+   To implement a inherited class of SessionAccept:
+
+     - No state is recorded by the handler.
+     - Values are required to be set during construction and never changed.
+     - Can not put into EventSystem.
+
+   So a NULL mutex is safe for the continuation.
+*/
+
 class SessionAccept : public Continuation
 {
 public:
   SessionAccept(ProxyMutex *amutex) : Continuation(amutex) { SET_HANDLER(&SessionAccept::mainEvent); }
   ~SessionAccept() {}
-  virtual void accept(NetVConnection *, MIOBuffer *, IOBufferReader *) = 0;
+  /**
+    Accept a new connection on this session.
+
+    If the session accepts the connection by returning true, it
+    takes ownership of all the arguments.
+
+    If the session rejects the connection by returning false, the
+    arguments are unmodified and the caller retains ownership.
+    Typically in this case, the caller would simply destroy all the
+    arguments.
+
+   */
+  virtual bool accept(NetVConnection *, MIOBuffer *, IOBufferReader *) = 0;
 
   /* Returns NULL if the specified client_ip is not allowed by ip_allow
    * Returns a pointer to the relevant IP policy for later processing otherwise */
diff --git a/iocore/net/P_SSLNextProtocolAccept.h b/iocore/net/P_SSLNextProtocolAccept.h
index 51968ce..94b2553 100644
--- a/iocore/net/P_SSLNextProtocolAccept.h
+++ b/iocore/net/P_SSLNextProtocolAccept.h
@@ -37,7 +37,7 @@ public:
   SSLNextProtocolAccept(Continuation *, bool);
   ~SSLNextProtocolAccept();
 
-  void accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
+  bool accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
 
   // Register handler as an endpoint for the specified protocol. Neither
   // handler nor protocol are copied, so the caller must guarantee their
diff --git a/iocore/net/SSLNextProtocolAccept.cc b/iocore/net/SSLNextProtocolAccept.cc
index 1bcec2e..939edc5 100644
--- a/iocore/net/SSLNextProtocolAccept.cc
+++ b/iocore/net/SSLNextProtocolAccept.cc
@@ -148,10 +148,11 @@ SSLNextProtocolAccept::mainEvent(int event, void *edata)
   }
 }
 
-void
+bool
 SSLNextProtocolAccept::accept(NetVConnection *, MIOBuffer *, IOBufferReader *)
 {
   ink_release_assert(0);
+  return false;
 }
 
 bool
diff --git a/proxy/ProtocolProbeSessionAccept.cc b/proxy/ProtocolProbeSessionAccept.cc
index c6a35f5..9931887 100644
--- a/proxy/ProtocolProbeSessionAccept.cc
+++ b/proxy/ProtocolProbeSessionAccept.cc
@@ -84,7 +84,6 @@ struct ProtocolProbeTrampoline : public Continuation, public ProtocolProbeSessio
     case VC_EVENT_ACTIVE_TIMEOUT:
     case VC_EVENT_INACTIVITY_TIMEOUT:
       // Error ....
-      netvc->do_io_close();
       goto done;
     case VC_EVENT_READ_READY:
     case VC_EVENT_READ_COMPLETE:
@@ -97,7 +96,6 @@ struct ProtocolProbeTrampoline : public Continuation, public ProtocolProbeSessio
 
     if (!reader->is_read_avail_more_than(minimum_read_size - 1)) {
       // Not enough data read. Well, that sucks.
-      netvc->do_io_close();
       goto done;
     }
 
@@ -115,16 +113,19 @@ struct ProtocolProbeTrampoline : public Continuation, public ProtocolProbeSessio
 
     if (probeParent->endpoint[key] == NULL) {
       Warning("Unregistered protocol type %d", key);
-      netvc->do_io_close();
       goto done;
     }
 
     // Directly invoke the session acceptor, letting it take ownership of the input buffer.
-    probeParent->endpoint[key]->accept(netvc, this->iobuf, reader);
+    if (!probeParent->endpoint[key]->accept(netvc, this->iobuf, reader)) {
+      // IPAllow check fails in XxxSessionAccept::accept() if false returned.
+      goto done;
+    }
     delete this;
     return EVENT_CONT;
 
   done:
+    netvc->do_io_close();
     free_MIOBuffer(this->iobuf);
     this->iobuf = NULL;
     delete this;
@@ -163,10 +164,11 @@ ProtocolProbeSessionAccept::mainEvent(int event, void *data)
   return EVENT_CONT;
 }
 
-void
+bool
 ProtocolProbeSessionAccept::accept(NetVConnection *, MIOBuffer *, IOBufferReader *)
 {
   ink_release_assert(0);
+  return false;
 }
 
 void
diff --git a/proxy/ProtocolProbeSessionAccept.h b/proxy/ProtocolProbeSessionAccept.h
index d40404a..d1ae635 100644
--- a/proxy/ProtocolProbeSessionAccept.h
+++ b/proxy/ProtocolProbeSessionAccept.h
@@ -49,7 +49,7 @@ public:
   ~ProtocolProbeSessionAccept() {}
   void registerEndpoint(ProtoGroupKey key, SessionAccept *ap);
 
-  void accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
+  bool accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
 
 private:
   int mainEvent(int event, void *netvc);
diff --git a/proxy/http/HttpSessionAccept.cc b/proxy/http/HttpSessionAccept.cc
index 2030b52..2ec794a 100644
--- a/proxy/http/HttpSessionAccept.cc
+++ b/proxy/http/HttpSessionAccept.cc
@@ -27,7 +27,7 @@
 #include "I_Machine.h"
 #include "Error.h"
 
-void
+bool
 HttpSessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferReader *reader)
 {
   sockaddr const *client_ip   = netvc->get_remote_addr();
@@ -45,8 +45,7 @@ HttpSessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferReade
       // if client address forbidden, close immediately //
       ////////////////////////////////////////////////////
       Warning("client '%s' prohibited by ip-allow policy", ats_ip_ntop(client_ip, ipb, sizeof(ipb)));
-      netvc->do_io_close();
-      return;
+      return false;
     }
   }
 
@@ -73,17 +72,21 @@ HttpSessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferReade
 
   new_session->new_connection(netvc, iobuf, reader, backdoor);
 
-  return;
+  return true;
 }
 
 int
 HttpSessionAccept::mainEvent(int event, void *data)
 {
+  NetVConnection *netvc;
   ink_release_assert(event == NET_EVENT_ACCEPT || event == EVENT_ERROR);
   ink_release_assert((event == NET_EVENT_ACCEPT) ? (data != 0) : (1));
 
   if (event == NET_EVENT_ACCEPT) {
-    this->accept(static_cast<NetVConnection *>(data), NULL, NULL);
+    netvc = static_cast<NetVConnection *>(data);
+    if (!this->accept(netvc, NULL, NULL)) {
+      netvc->do_io_close();
+    }
     return EVENT_CONT;
   }
 
diff --git a/proxy/http/HttpSessionAccept.h b/proxy/http/HttpSessionAccept.h
index 8823630..1cbfbb9 100644
--- a/proxy/http/HttpSessionAccept.h
+++ b/proxy/http/HttpSessionAccept.h
@@ -205,7 +205,7 @@ public:
   }
 
   ~HttpSessionAccept() { return; }
-  void accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
+  bool accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
   int mainEvent(int event, void *netvc);
 
 private:
diff --git a/proxy/http2/Http2SessionAccept.cc b/proxy/http2/Http2SessionAccept.cc
index b2594de..d3603f1 100644
--- a/proxy/http2/Http2SessionAccept.cc
+++ b/proxy/http2/Http2SessionAccept.cc
@@ -36,7 +36,7 @@ Http2SessionAccept::~Http2SessionAccept()
 {
 }
 
-void
+bool
 Http2SessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferReader *reader)
 {
   sockaddr const *client_ip           = netvc->get_remote_addr();
@@ -44,8 +44,7 @@ Http2SessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferRead
   if (!session_acl_record) {
     ip_port_text_buffer ipb;
     Warning("HTTP/2 client '%s' prohibited by ip-allow policy", ats_ip_ntop(client_ip, ipb, sizeof(ipb)));
-    netvc->do_io_close();
-    return;
+    return false;
   }
   netvc->attributes = this->options.transport_type;
 
@@ -59,16 +58,22 @@ Http2SessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferRead
   Http2ClientSession *new_session = THREAD_ALLOC_INIT(http2ClientSessionAllocator, this_ethread());
   new_session->acl_record         = session_acl_record;
   new_session->new_connection(netvc, iobuf, reader, false /* backdoor */);
+
+  return true;
 }
 
 int
 Http2SessionAccept::mainEvent(int event, void *data)
 {
+  NetVConnection *netvc;
   ink_release_assert(event == NET_EVENT_ACCEPT || event == EVENT_ERROR);
   ink_release_assert((event == NET_EVENT_ACCEPT) ? (data != 0) : (1));
 
   if (event == NET_EVENT_ACCEPT) {
-    this->accept(static_cast<NetVConnection *>(data), NULL, NULL);
+    netvc = static_cast<NetVConnection *>(data);
+    if (!this->accept(netvc, NULL, NULL)) {
+      netvc->do_io_close();
+    }
     return EVENT_CONT;
   }
 
diff --git a/proxy/http2/Http2SessionAccept.h b/proxy/http2/Http2SessionAccept.h
index 8df082d..06a721d 100644
--- a/proxy/http2/Http2SessionAccept.h
+++ b/proxy/http2/Http2SessionAccept.h
@@ -43,7 +43,7 @@ struct Http2SessionAccept : public SessionAccept {
   explicit Http2SessionAccept(const HttpSessionAccept::Options &);
   ~Http2SessionAccept();
 
-  void accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
+  bool accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
   int mainEvent(int event, void *netvc);
 
 private:
diff --git a/proxy/spdy/SpdySessionAccept.cc b/proxy/spdy/SpdySessionAccept.cc
index d8c1a60..2fdde64 100644
--- a/proxy/spdy/SpdySessionAccept.cc
+++ b/proxy/spdy/SpdySessionAccept.cc
@@ -43,10 +43,9 @@ SpdySessionAccept::mainEvent(int event, void *edata)
     NetVConnection *netvc = static_cast<NetVConnection *>(edata);
 
 #if TS_HAS_SPDY
-    SpdyClientSession *sm = SpdyClientSession::alloc();
-    sm->version           = this->version;
-
-    sm->new_connection(netvc, NULL, NULL, false);
+    if (!this->accept(netvc, NULL, NULL)) {
+      netvc->do_io_close();
+    }
 #else
     Error("accepted a SPDY session, but SPDY support is not available");
     netvc->do_io_close();
@@ -59,17 +58,19 @@ SpdySessionAccept::mainEvent(int event, void *edata)
   return EVENT_CONT;
 }
 
-void
+bool
 SpdySessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferReader *reader)
 {
 #if TS_HAS_SPDY
   SpdyClientSession *sm = SpdyClientSession::alloc();
   sm->version           = this->version;
   sm->new_connection(netvc, iobuf, reader, false);
+  return true;
 #else
   (void)netvc;
   (void)iobuf;
   (void)reader;
   ink_release_assert(0);
+  return false;
 #endif
 }
diff --git a/proxy/spdy/SpdySessionAccept.h b/proxy/spdy/SpdySessionAccept.h
index 2de56b1..6a2fab2 100644
--- a/proxy/spdy/SpdySessionAccept.h
+++ b/proxy/spdy/SpdySessionAccept.h
@@ -35,7 +35,7 @@ class SpdySessionAccept : public SessionAccept
 public:
   explicit SpdySessionAccept(spdy::SessionVersion vers);
   ~SpdySessionAccept() {}
-  void accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
+  bool accept(NetVConnection *, MIOBuffer *, IOBufferReader *);
 
 private:
   int mainEvent(int event, void *netvc);

-- 
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].