Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

Commit

Permalink
feat(security): start negotiation when a rpc connection is established (
Browse files Browse the repository at this point in the history
  • Loading branch information
levy5307 authored Aug 4, 2020
1 parent 3d0f7c0 commit d8f593b
Show file tree
Hide file tree
Showing 12 changed files with 299 additions and 3 deletions.
15 changes: 15 additions & 0 deletions include/dsn/tool-api/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ class connection_oriented_network : public network
/*!
session managements (both client and server types)
*/

namespace security {
class negotiation;
}

class rpc_client_matcher;
class rpc_session : public ref_counter
{
Expand Down Expand Up @@ -227,6 +232,9 @@ class rpc_session : public ref_counter
bool delay_recv(int delay_ms);
bool on_recv_message(message_ex *msg, int delay_ms);

/// for negotiation
void start_negotiation();

public:
///
/// for subclass to implement receiving message
Expand Down Expand Up @@ -256,6 +264,7 @@ class rpc_session : public ref_counter
enum session_state
{
SS_CONNECTING,
SS_NEGOTIATING,
SS_CONNECTED,
SS_DISCONNECTED
};
Expand Down Expand Up @@ -286,6 +295,7 @@ class rpc_session : public ref_counter
bool set_connecting();
// return true when it is permitted
bool set_disconnected();
void set_negotiation();
void set_connected();

void clear_send_queue(bool resend_msgs);
Expand All @@ -299,11 +309,16 @@ class rpc_session : public ref_counter
message_reader _reader;
message_parser_ptr _parser;

private:
void auth_negotiation();

private:
const bool _is_client;
rpc_client_matcher *_matcher;

std::atomic_int _delay_server_receive_ms;

std::unique_ptr<security::negotiation> _negotiation;
};

// --------- inline implementation --------------
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
add_subdirectory(test)
add_subdirectory(rpc)
add_subdirectory(task)
add_subdirectory(security)

# TODO(zlw) remove perf_counter from dsn_runtime after the refactor by WuTao
add_library(dsn_runtime STATIC
$<TARGET_OBJECTS:dsn.security>
$<TARGET_OBJECTS:dsn.rpc>
$<TARGET_OBJECTS:dsn.task>
$<TARGET_OBJECTS:dsn.perf_counter>
Expand Down
3 changes: 3 additions & 0 deletions src/runtime/rpc/asio_net_provider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ void asio_network_provider::do_accept()
null_parser,
false);

// start negotiation when server accepts the connection
s->start_negotiation();

// when server connection threshold is hit, close the session, otherwise accept it
if (check_if_conn_threshold_exceeded(s->remote_address())) {
dwarn("close rpc connection from %s to %s due to hitting server "
Expand Down
4 changes: 4 additions & 0 deletions src/runtime/rpc/asio_rpc_session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ void asio_rpc_session::connect()
dinfo("client session %s connected", _remote_addr.to_string());

set_options();

// start auth negotiation when client is connecting to server
start_negotiation();

set_connected();
on_send_completed();
start_read_next();
Expand Down
44 changes: 41 additions & 3 deletions src/runtime/rpc/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,23 @@
* THE SOFTWARE.
*/

#include <dsn/tool-api/network.h>
#include <dsn/utility/factory_store.h>
#include "runtime/security/negotiation.h"
#include "message_parser_manager.h"
#include "runtime/rpc/rpc_engine.h"

#include <dsn/tool-api/network.h>
#include <dsn/utility/factory_store.h>

namespace dsn {
/*static*/ join_point<void, rpc_session *>
rpc_session::on_rpc_session_connected("rpc.session.connected");
/*static*/ join_point<void, rpc_session *>
rpc_session::on_rpc_session_disconnected("rpc.session.disconnected");

namespace security {
extern bool FLAGS_enable_auth;
} // namespace security

rpc_session::~rpc_session()
{
clear_send_queue(false);
Expand Down Expand Up @@ -65,7 +71,9 @@ void rpc_session::set_connected()

{
utils::auto_lock<utils::ex_lock_nr> l(_lock);
dassert(_connect_state == SS_CONNECTING, "session must be connecting");
dassert((_connect_state == SS_NEGOTIATING && security::FLAGS_enable_auth) ||
(_connect_state == SS_CONNECTING && !security::FLAGS_enable_auth),
"wrong session state");
_connect_state = SS_CONNECTED;
}

Expand All @@ -75,6 +83,17 @@ void rpc_session::set_connected()
on_rpc_session_connected.execute(this);
}

void rpc_session::set_negotiation()
{
dassert(is_client(), "must be client session");

{
utils::auto_lock<utils::ex_lock_nr> l(_lock);
dassert(_connect_state == SS_CONNECTING, "session must be connecting");
_connect_state = SS_NEGOTIATING;
}
}

bool rpc_session::set_disconnected()
{
{
Expand Down Expand Up @@ -414,6 +433,24 @@ bool rpc_session::on_recv_message(message_ex *msg, int delay_ms)
return true;
}

void rpc_session::start_negotiation()
{
if (security::FLAGS_enable_auth) {
// set the negotiation state if it's a client rpc_session
if (is_client()) {
set_negotiation();
}

auth_negotiation();
}
}

void rpc_session::auth_negotiation()
{
_negotiation = security::create_negotiation(is_client(), this);
_negotiation->start_negotiate();
}

////////////////////////////////////////////////////////////////////////////////////////////////
network::network(rpc_engine *srv, network *inner_provider)
: _engine(srv), _client_hdr_format(NET_HDR_DSN), _unknown_msg_header_format(NET_HDR_INVALID)
Expand Down Expand Up @@ -720,4 +757,5 @@ void connection_oriented_network::on_client_session_disconnected(rpc_session_ptr
scount);
}
}

} // namespace dsn
21 changes: 21 additions & 0 deletions src/runtime/security/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
set(MY_PROJ_NAME dsn.security)

# Source files under CURRENT project directory will be automatically included.
# You can manually set MY_PROJ_SRC to include source files under other directories.
set(MY_PROJ_SRC "")

# Search mode for source files under CURRENT project directory?
# "GLOB_RECURSE" for recursive search
# "GLOB" for non-recursive search
set(MY_SRC_SEARCH_MODE "GLOB")

set(MY_PROJ_INC_PATH "")

set(MY_PROJ_LIBS "")

set(MY_PROJ_LIB_PATH "")

# Extra files that will be installed
set(MY_BINPLACES "")

dsn_add_object()
31 changes: 31 additions & 0 deletions src/runtime/security/client_negotiation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#include "client_negotiation.h"

namespace dsn {
namespace security {

client_negotiation::client_negotiation(rpc_session *session) : negotiation(session) {}

void client_negotiation::start_negotiate()
{
// TBD(zlw)
}

} // namespace security
} // namespace dsn
33 changes: 33 additions & 0 deletions src/runtime/security/client_negotiation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#pragma once

#include "negotiation.h"

namespace dsn {
namespace security {

class client_negotiation : public negotiation
{
public:
client_negotiation(rpc_session *session);
void start_negotiate();
};

} // namespace security
} // namespace dsn
42 changes: 42 additions & 0 deletions src/runtime/security/negotiation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#include "negotiation.h"
#include "client_negotiation.h"
#include "server_negotiation.h"

#include <dsn/utility/flags.h>
#include <dsn/utility/smart_pointers.h>

namespace dsn {
namespace security {

DSN_DEFINE_bool("security", enable_auth, false, "whether open auth or not");

negotiation::~negotiation() {}

std::unique_ptr<negotiation> create_negotiation(bool is_client, rpc_session *session)
{
if (is_client) {
return make_unique<client_negotiation>(session);
} else {
return make_unique<server_negotiation>(session);
}
}

} // namespace security
} // namespace dsn
43 changes: 43 additions & 0 deletions src/runtime/security/negotiation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#pragma once

#include <memory>

namespace dsn {
class rpc_session;

namespace security {

class negotiation
{
public:
negotiation(rpc_session *session) : _session(session) {}
virtual ~negotiation() = 0;

virtual void start_negotiate() = 0;

protected:
// The ownership of the negotiation instance is held by rpc_session.
// So negotiation keeps only a raw pointer.
rpc_session *_session;
};

std::unique_ptr<negotiation> create_negotiation(bool is_client, rpc_session *session);
} // namespace security
} // namespace dsn
31 changes: 31 additions & 0 deletions src/runtime/security/server_negotiation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

#include "server_negotiation.h"

namespace dsn {
namespace security {

server_negotiation::server_negotiation(rpc_session *session) : negotiation(session) {}

void server_negotiation::start_negotiate()
{
// TBD(zlw)
}

} // namespace security
} // namespace dsn
Loading

0 comments on commit d8f593b

Please sign in to comment.