You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by to...@apache.org on 2017/03/27 18:17:55 UTC

[1/2] kudu git commit: Update rpc.md with authentication protocol details

Repository: kudu
Updated Branches:
  refs/heads/master 86da259a6 -> 0254216c1


Update rpc.md with authentication protocol details

Change-Id: Iae4c296a53ee31a7a1012acaa954ec72db5ad33f
Reviewed-on: http://gerrit.cloudera.org:8080/6475
Reviewed-by: Todd Lipcon <to...@apache.org>
Tested-by: Kudu Jenkins


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

Branch: refs/heads/master
Commit: 0e188a309533028f2814cee47a3cfb66aefbd46f
Parents: 86da259
Author: Dan Burkert <da...@apache.org>
Authored: Fri Mar 24 15:28:59 2017 -0700
Committer: Todd Lipcon <to...@apache.org>
Committed: Mon Mar 27 17:08:46 2017 +0000

----------------------------------------------------------------------
 docs/design-docs/rpc.md | 142 ++++++++++++++++++++++++++++++-------------
 1 file changed, 99 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/0e188a30/docs/design-docs/rpc.md
----------------------------------------------------------------------
diff --git a/docs/design-docs/rpc.md b/docs/design-docs/rpc.md
index d3b2fba..af03164 100644
--- a/docs/design-docs/rpc.md
+++ b/docs/design-docs/rpc.md
@@ -129,8 +129,10 @@ one except that they are type-safe and do not require the method name to be pass
 The generated ServiceIf class contains pure virtual methods for each of the RPCs
 in the service. Each method to be implemented has an API like:
 
+```
   void MethodName(const RequestPB *req,
      ResponsePB *resp, ::kudu::rpc::RpcContext *context);
+```
 
 The request PB is the user-provided request, and the response PB is a cleared
 protobuf ready to store the RPC response. Once the RPC response has been filled in,
@@ -163,6 +165,7 @@ Exactly once semantics can be enabled for RPCs that require them by using
 the 'track_rpc_result' option when declaring a service interface method.
 
 Example:
+
 ```
 service CalculatorService {
   rpc AddExactlyOnce(ExactlyOnceRequestPB) returns (ExactlyOnceResponsePB) {
@@ -379,13 +382,13 @@ identifies the negotiation protocol step. Each `NegotiatePB` is framed as usual
 using `RequestHeader` or `ResponseHeader` messages with `call_id` -33.
 
 The Kudu negotiation protocol allows the client and server to communicate
-supported RPC feature flags and supported SASL authentication mechanisms,
-initiate an optional TLS handshake, and perform SASL negotiation.
+supported RPC feature flags, initiate an optional TLS handshake, and perform
+authentication.
 
-#### Step 1: Negotiate
+### Step 1: Negotiate
 
-The client and server swap RPC feature flags and supported SASL mechanisms. This
-step always takes exactly one round trip.
+The client and server swap RPC feature flags, supported authentication types,
+and supported SASL mechanisms. This step always takes exactly one round trip.
 
 ```
 Client                                                                    Server
@@ -393,13 +396,15 @@ Client                                                                    Server
    | +----NegotiatePB-----------------------------+                         |
    | | step = NEGOTIATE                           |                         |
    | | supported_features = <client RPC features> | ----------------------> |
-   | | mechanisms = <client SASL mechanisms>      |                         |
+   | | authn_types = <client authn types>         |                         |
+   | | sasl_mechanisms = <client SASL mechanisms> |                         |
    | +--------------------------------------------+                         |
    |                                                                        |
    |                         +----NegotiatePB-----------------------------+ |
    |                         | step = NEGOTIATE                           | |
    | <---------------------- | supported_features = <server RPC features> | |
-   |                         | mechanisms = <server SASL mechanisms>      | |
+   |                         | authn_types = <preferred authn type>       | |
+   |                         | sasl_mechanisms = <server SASL mechanisms> | |
    |                         +--------------------------------------------+ |
 ```
 
@@ -418,7 +423,7 @@ of using feature flags over version numbers for this purpose:
 * the set of supported features can be determined by code-level support as well
   as conditionally based on configuration or machine capability.
 
-#### Step 2: TLS Handshake
+### Step 2: TLS Handshake
 
 If both the server and client support the `TLS` RPC feature flag, the client
 initiates a TLS handshake, after which both sides wrap the socket in the TLS
@@ -442,12 +447,11 @@ Client                                                                    Server
    |            <...repeat until TLS handshake is complete...>              |
 ```
 
-The client and server repeat `TLS_HANDSHAKE` round-trips until the TLS handshake
-is complete. After the handshake is complete, in the absence of the
-`TLS_AUTHENTICATION_ONLY` feature described belowq, the client and server
-wrap the socket connection such that all further traffic is encrypted via TLS.
+After the handshake is complete, in the absence of the `TLS_AUTHENTICATION_ONLY`
+feature described below, the client and server wrap the socket connection such
+that all further traffic is encrypted via TLS.
 
-##### `TLS_AUTHENTICATION_ONLY`
+#### `TLS_AUTHENTICATION_ONLY`
 
 In many cases, RPC connections are made between a client and server running
 on the same machine. For example, the schedulers in Spark, MapReduce,
@@ -465,16 +469,72 @@ client and server advertise the flag, then after completing the TLS handshake,
 the peers will _not_ wrap the socket with TLS. All other behavior remains
 the same, including channel binding as described below.
 
+### Step 3: Authentication
 
-#### Step 3: SASL Negotiation
+The client and server now authenticate to each other. There are three
+authentication types (SASL, token, and TLS/PKI certificate), and the SASL
+authentication type has two possible mechanisms (GSSAPI and PLAIN). Of these,
+all are considered strong or secure authentication types with the exception of
+SASL PLAIN. The client sends the server its supported authentication types and
+sasl mechanisms in the negotiate step above. The server responds in the
+negotiate step with its preferred authentication type and supported mechanisms.
+The server is thus responsible for choosing the authentication type if there
+are multiple to choose from. Which type is chosen for a particular connection by
+the server depends on configuration and the available credentials:
+
+```
++----------------------+       +----------------------+
+|                      |       |                      |       +----------------------+
+| Does the server have |  yes  | Does the client have |  yes  |                      |
+| a CA-signed TLS      +-------> a CA-signed TLS      +-------> Authenticate via TLS |
+| certificate?         |       | certificate?         |       |                      |
+|                      |       |                      |       +----------------------+
++------+---------------+       +---------+------------+
+       |                                 |
+       |                                 |no
+       |                                 |
+       |                       +---------v------------+       +----------------------+
+       |                       |                      |       |                      |
+       |no                no   | Does the client have |  yes  | Authenticate via     |
+       |      +----------------+ an authentication    +-------> authentication token |
+       |      |                | token?               |       |                      |
+       |      |                |                      |       +----------------------+
+       |      |                +----------------------+
+       |      |
++------v------v--------+       +-----------------------+       +------------------+
+|                      |       |                       |       |                  |
+| Does the server have |  yes  | Does the client have  |  yes  | Authenticate via |
+| a Kerberos keytab?   +-------> Kerberos credentials? +-------> SASL GSSAPI      |
+|                      |       |                       |       |                  |
++------+---------------+       +----------+------------+       +------------------+
+       |                  no              |
+       |no    +---------------------------+                   +------------------+
+       |      |                                               |                  |
+       |      |                                               | Authenticate via |
++------v------v------+                   no                   | SASL PLAIN       |
+|                    +---------------------------------------->                  |
+| Is authentication  |                                        +------------------+
+| required?          |                   yes
+|                    |------------------------------+         +---------------------+
++--------------------+                              |         |                     |
+                                                    +---------> Fail authentication |
+                                                              |                     |
+                                                              +---------------------+
+```
 
-The client and server now initiate a SASL handshake. The client is responsible
+The client will initiate the type-specific authentiation handshake.
+
+#### SASL Handshake
+
+When the server includes the SASL authentication type in the `NEGOTIATE` step
+response, the client will initiate a SASL handshake. The client is responsible
 for choosing which SASL mechanism is used, with the restriction that it must be
 in the set of mutually supported SASL mechanisms exchanged in the `NEGOTIATE`
-step. Depending on the mechanism, SASL negotiation may serve to authenticate the
-client to the server, and vice versa.
+step. The `GSSAPI` (Kerberos) mechanism allows the client and server to
+mutually authenticate. The `PLAIN` mechanism is used when connecting without
+secure authentication.
 
-SASL negotiation may take one or more round trips. The first and last messages
+The SASL handshake may take one or more round trips. The first and last messages
 are always a `SASL_INITIATE` from the client and a `SASL_SUCCESS` from the
 server, respectively. In between `SASL_INITIATE` and `SASL_SUCCESS`, zero or
 more pairs of `SASL_CHALLENGE` and `SASL_RESPONSE` messages from server and
@@ -507,22 +567,7 @@ Client                                                                    Server
    |                                                +---------------------+ |
 ```
 
-### Authentication
-
-When security is enabled, the negotiation process is responsible for mutually
-authenticating the client and server to each other. There are three distinct
-methods of mutual authentication, one of which will be chosen during
-negotiation. Which method is chosen for a particular connection depends on the
-configuration of the client and server. All authentication methods require the
-connection to be protected with TLS encryption.
-
-| server authentication of client | client authentication of server | notes |
-|---|---|---|
-| Kerberos | Kerberos | Kerberos provides strong mutual authentication, channel binding ties the Kerberos authentication to the TLS channel |
-| Certificate | Certificate | client and server authenticate via certs signed by mutually trusted CA |
-| Token | Certificate | client authenticates by passing a token signed by a key which is trusted by the server |
-
-#### Kerberos Authentication
+##### Kerberos
 
 Kerberos authentication requires the client and server to be configured with
 Kerberos principal credentials. Typically the client must have an active TGT
@@ -547,12 +592,10 @@ negotiation.
 #### Certificate Authentication
 
 When the client and server are configured with certificates signed by a mutually
-trusted certificate authority (CA), certificate authentication can be used
-to authenticate the client and server.
-
-TODO(dan): explain how the two sides decide on certificate authentication.
-           Probably via a special SASL mechanism (`KUDU_CERTIFICATE`) which
-           short-circuits any actual SASL messages.
+trusted certificate authority (CA), certificate authentication can be used to
+authenticate the client and server. Certificate authentication is nothing more
+than a mutually-verified TLS handshake, so no additional message need to be
+exchanged.
 
 #### Token Authentication
 
@@ -561,9 +604,22 @@ and the client to be configured with a token. The server's certificate must be
 signed by a CA trusted by the client, and the client's token must be signed by a
 token-signing-key which is trusted by the server.
 
-TODO(dan): explain how the two sides decide on token authentication.
-           Probably via a special SASL mechanism (`KUDU_TOKEN`) which sends a
-           single round of SASL messages containing the token and a reply ack.
+The client sends its authentication token to the server in a `TOKEN_EXCHANGE`
+response step negotiation message, and the server responds with an empty
+`TOKEN_EXCHANGE` message on success.
+
+```
+Client                                                                    Server
+   |                                                                        |
+   | +----NegotiatePB---------------------+                                 |
+   | | step = TOKEN_EXCHANGE              |                                 |
+   | | authn_token = <client token>       | ------------------------------> |
+   | +------------------------------------+                                 |
+   |                                                                        |
+   |                                              +----NegotiatePB--------+ |
+   | <------------------------------------------- | step = TOKEN_EXCHANGE | |
+   |                                              +-----------------------+ |
+```
 
 ## Connection Context
 


[2/2] kudu git commit: log_block_manager: use sparse_hash_map for block map

Posted by to...@apache.org.
log_block_manager: use sparse_hash_map for block map

Based on my testing, this reduces the memory usage of 1M blocks from
~24M to ~9MB. Lookup performance should be similar. Write performance
may be slightly slower but this is relatively infrequent and not on a
hot path.

I also did an allocation trace of a simple program putting 1M <int,int>
pairs into both types of maps. With unordered_map, this resulted in 1M
16-byte allocations and several larger allocations as the hashtable
bucket array grew (largest being 8MB). With the sparse_hash_map, the
allocation sizes were evenly distributed with ~55K allocations at a
bunch of sizes between 16 and 384 bytes, with no large allocations. This
should be more efficient in terms of avoiding memory fragmentation or
longer resizing pauses as blocks are added.

In order for this patch to work on gcc 4.9, I had to patch sparsehash.
gcc 4 doesn't support std::is_trivially_copy_constructible. This adds a
workaround to the sparsehash source to use boost's implementation of the
same.

Change-Id: I2e75deba7f7fb8d4f800695f195304df603e4ce9
Reviewed-on: http://gerrit.cloudera.org:8080/6471
Reviewed-by: Adar Dembo <ad...@cloudera.com>
Tested-by: Todd Lipcon <to...@apache.org>


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

Branch: refs/heads/master
Commit: 0254216c18af036a62a11fcfae8a77b781d74aa2
Parents: 0e188a3
Author: Todd Lipcon <to...@apache.org>
Authored: Fri Mar 24 16:09:55 2017 -0700
Committer: Todd Lipcon <to...@apache.org>
Committed: Mon Mar 27 18:07:11 2017 +0000

----------------------------------------------------------------------
 src/kudu/fs/log_block_manager.cc                |  1 +
 src/kudu/fs/log_block_manager.h                 |  7 ++-
 thirdparty/download-thirdparty.sh               |  6 +++
 ...-Add-compatibily-for-gcc-4.x-in-traits.patch | 53 ++++++++++++++++++++
 4 files changed, 65 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/0254216c/src/kudu/fs/log_block_manager.cc
----------------------------------------------------------------------
diff --git a/src/kudu/fs/log_block_manager.cc b/src/kudu/fs/log_block_manager.cc
index 6792226..503273f 100644
--- a/src/kudu/fs/log_block_manager.cc
+++ b/src/kudu/fs/log_block_manager.cc
@@ -1248,6 +1248,7 @@ LogBlockManager::LogBlockManager(Env* env, const BlockManagerOptions& opts)
     read_only_(opts.read_only),
     buggy_el6_kernel_(IsBuggyEl6Kernel(env->GetKernelRelease())),
     next_block_id_(1) {
+  blocks_by_block_id_.set_deleted_key(BlockId());
 
   int64_t file_cache_capacity = GetFileCacheCapacityForBlockManager(env_);
   if (file_cache_capacity != kint64max) {

http://git-wip-us.apache.org/repos/asf/kudu/blob/0254216c/src/kudu/fs/log_block_manager.h
----------------------------------------------------------------------
diff --git a/src/kudu/fs/log_block_manager.h b/src/kudu/fs/log_block_manager.h
index 32249af..0d99d72 100644
--- a/src/kudu/fs/log_block_manager.h
+++ b/src/kudu/fs/log_block_manager.h
@@ -29,6 +29,7 @@
 
 #include <boost/optional/optional.hpp>
 #include <gtest/gtest_prod.h>
+#include <sparsehash/sparse_hash_map>
 
 #include "kudu/fs/block_id.h"
 #include "kudu/fs/block_manager.h"
@@ -197,10 +198,12 @@ class LogBlockManager : public BlockManager {
       BlockIdHash,
       BlockIdEqual> UntrackedBlockMap;
 
+  // Type for the actual block map used to store all live blocks.
+  // We use sparse_hash_map<> here to reduce memory overhead.
   typedef MemTrackerAllocator<
       std::pair<const BlockId, scoped_refptr<internal::LogBlock> > > BlockAllocator;
-  typedef std::unordered_map<
-      const BlockId,
+  typedef google::sparse_hash_map<
+      BlockId,
       scoped_refptr<internal::LogBlock>,
       BlockIdHash,
       BlockIdEqual,

http://git-wip-us.apache.org/repos/asf/kudu/blob/0254216c/thirdparty/download-thirdparty.sh
----------------------------------------------------------------------
diff --git a/thirdparty/download-thirdparty.sh b/thirdparty/download-thirdparty.sh
index 708ac52..aa53960 100755
--- a/thirdparty/download-thirdparty.sh
+++ b/thirdparty/download-thirdparty.sh
@@ -305,8 +305,14 @@ if [ ! -d "$BREAKPAD_SOURCE" ]; then
   fetch_and_expand breakpad-${BREAKPAD_VERSION}.tar.gz
 fi
 
+SPARSEHASH_PATCHLAVEL=2
+delete_if_wrong_patchlevel $SPARSEHASH_SOURCE $SPARSEHASH_PATCHLEVEL
 if [ ! -d "$SPARSEHASH_SOURCE" ]; then
   fetch_and_expand sparsehash-c11-${SPARSEHASH_VERSION}.tar.gz
+  pushd $SPARSEHASH_SOURCE
+  patch -p1 < $TP_DIR/patches/sparsehash-0001-Add-compatibily-for-gcc-4.x-in-traits.patch
+  touch patchlevel-$SPARSEHASH_PATCHLAVEL
+  popd
 fi
 
 echo "---------------"

http://git-wip-us.apache.org/repos/asf/kudu/blob/0254216c/thirdparty/patches/sparsehash-0001-Add-compatibily-for-gcc-4.x-in-traits.patch
----------------------------------------------------------------------
diff --git a/thirdparty/patches/sparsehash-0001-Add-compatibily-for-gcc-4.x-in-traits.patch b/thirdparty/patches/sparsehash-0001-Add-compatibily-for-gcc-4.x-in-traits.patch
new file mode 100644
index 0000000..43215c1
--- /dev/null
+++ b/thirdparty/patches/sparsehash-0001-Add-compatibily-for-gcc-4.x-in-traits.patch
@@ -0,0 +1,53 @@
+From 6c2e37ffdd85823549634ab53931bc412b297bde Mon Sep 17 00:00:00 2001
+From: Todd Lipcon <to...@cloudera.com>
+Date: Fri, 24 Mar 2017 15:14:31 -0700
+Subject: [PATCH] Add compatibily for gcc 4.x in traits
+
+gcc 4.x doesn't implement std::is_trivially_copy_constructible<>. In
+order to maintain compatibility with those versions, we switch to using
+the equivalent trait in boost.
+
+Tested by building a small test using gcc 4.8, gcc 5.4, and clang 3.9.
+
+This was discussed upstream at https://github.com/sparsehash/sparsehash-c11/pull/19
+but determined that it wasn't a good idea for the upstream project.
+---
+ sparsehash/traits | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/sparsehash/traits b/sparsehash/traits
+index 65135a6..e1e5648 100644
+--- a/sparsehash/traits
++++ b/sparsehash/traits
+@@ -30,6 +30,12 @@
+ #pragma once
+ #include <type_traits>
+ #include <utility>  // For pair
++#include <boost/move/detail/type_traits.hpp>
++
++// Work around lack of std::is_trivially_copy_constructible in gcc 4.x by
++// using the boost version.
++#define SPARSEHASH_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
++  ::boost::move_detail::is_trivially_copy_constructible<T>::value
+ 
+ namespace google {
+ 
+@@ -43,7 +49,7 @@ namespace google {
+ template <class T>
+ struct is_relocatable
+     : std::integral_constant<bool,
+-                             (std::is_trivially_copy_constructible<T>::value &&
++                             (SPARSEHASH_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) &&
+                               std::is_trivially_destructible<T>::value)> {};
+ template <class T, class U>
+ struct is_relocatable<std::pair<T, U>>
+@@ -52,4 +58,4 @@ struct is_relocatable<std::pair<T, U>>
+ 
+ template <class T>
+ struct is_relocatable<const T> : is_relocatable<T> {};
+-}
+\ No newline at end of file
++}
+-- 
+2.7.4
+