Skip to content

Commit

Permalink
Merge pull request #34 from MiaoZhangAWS/master
Browse files Browse the repository at this point in the history
Add support for tunnel multi-port feature
  • Loading branch information
MiaoZhangAWS authored Nov 16, 2020
2 parents 6d1377a + 5d2be62 commit 8980ea8
Show file tree
Hide file tree
Showing 17 changed files with 2,183 additions and 455 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
run: |
mkdir build
cd build
cmake .. -DOPENSSL_ROOT_DIR=/usr/local/Cellar/[email protected]/1.1.1g/ -DOPENSSL_LIBRARIES=/usr/local/Cellar/[email protected]/1.1.1g/lib/
cmake .. -DOPENSSL_ROOT_DIR=/usr/local/Cellar/[email protected]/1.1.1h/ -DOPENSSL_LIBRARIES=/usr/local/Cellar/[email protected]/1.1.1h/lib/
make
ubuntu:
runs-on: ubuntu-latest
Expand Down
9 changes: 5 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ find_package(Catch2 REQUIRED)
#########################################
# Boost dependencies #
#########################################
set_property(GLOBAL PROPERTY Boost_USE_STATIC_LIBS ON)
set_property(GLOBAL PROPERTY Boost_USE_STATIC_LIBS ON)
set_property(GLOBAL PROPERTY Boost_USE_DEBUG_RUNTIME OFF)
#set_property(GLOBAL PROPERTY Boost_USE_MULTITHREADED ON)
find_package(Boost 1.68.0 REQUIRED COMPONENTS system log log_setup thread program_options date_time)
find_package(Boost 1.68.0 REQUIRED COMPONENTS system log log_setup thread program_options date_time filesystem)
include_directories(${Boost_INCLUDE_DIRS})
foreach(BOOST_LIB ${Boost_LIBRARIES})
string(REPLACE ${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_STATIC_LIBRARY_SUFFIX} BOOST_STATIC_LIB ${BOOST_LIB})
Expand All @@ -81,9 +81,10 @@ endforeach()
#########################################
file(GLOB ALL_SOURCES ${PROJECT_SOURCE_DIR}/src/*.cpp)

set(UTIL_SOURCE ${PROJECT_SOURCE_DIR}/src/config/ConfigFile.cpp)
set(CORE_SOURCES ${PROJECT_SOURCE_DIR}/src/TcpAdapterProxy.cpp ${PROJECT_SOURCE_DIR}/src/ProxySettings.cpp ${PROTO_HDRS} ${PROTO_SRCS})
set(MAIN_SOURCES ${PROJECT_SOURCE_DIR}/src/main.cpp ${CORE_SOURCES})
set(TEST_SOURCES ${PROJECT_SOURCE_DIR}/test/AdapterTests.cpp ${CORE_SOURCES} ${PROJECT_SOURCE_DIR}/test/TestWebsocketServer.cpp)
set(MAIN_SOURCES ${PROJECT_SOURCE_DIR}/src/main.cpp ${CORE_SOURCES} ${UTIL_SOURCE})
set(TEST_SOURCES ${PROJECT_SOURCE_DIR}/test/AdapterTests.cpp ${CORE_SOURCES} ${UTIL_SOURCE} ${PROJECT_SOURCE_DIR}/test/TestWebsocketServer.cpp)

add_executable(${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} ${MAIN_SOURCES})
add_executable(${AWS_TUNNEL_LOCAL_PROXY_TEST_NAME} ${TEST_SOURCES})
Expand Down
162 changes: 153 additions & 9 deletions README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions WebsocketProtocolGuide.md → V1WebSocketProtocolGuide.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
The reference implementation of the local proxy provides features that may require OS facilities not available on all device runtime environments in the industry. This guide provides details about the communication that occurs between the service and client to enable integration without or beyond the local proxy reference implementation choices.
The reference implementation of the local proxy provides features that may require OS facilities not available on all device runtime environments in the industry. This guide provides details about the communication that occurs between the service and client to enable integration without or beyond the local proxy reference implementation choices. This protocol guide is only applicable for v1 local proxy.

## Core implementation requirements

In order to properly connect with and interpret messages from the AWS IoT Secure Tunneling service, the bare minimum is required:
In order to properly connect with and interpret messages from the AWS IoT Secure Tunneling service, the following is required:

**Communications Protocols:**
* Websocket protocol ([RFC6455](https://tools.ietf.org/html/rfc6455)) over TCP/IP
Expand Down
287 changes: 287 additions & 0 deletions V2WebSocketProtocolGuide.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions resources/Message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ message Message {
int32 streamId = 2;
bool ignorable = 3;
bytes payload = 4;
string serviceId = 5;
repeated string availableServiceIds = 6;

enum Type {
UNKNOWN = 0;
DATA = 1;
STREAM_START = 2;
STREAM_RESET = 3;
SESSION_RESET = 4;
SERVICE_IDS = 5;
}
}
2 changes: 1 addition & 1 deletion src/ProxySettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace aws { namespace iot { namespace securedtunneling { namespace settings
bool const DEFAULT_WEB_SOCKET_DATA_ERROR_RETRY = true;

char const * const KEY_WEB_SOCKET_SUBPROTOCOL = "tunneling.proxy.websocket.subprotocol";
std::string const DEFAULT_WEB_SOCKET_SUBPROTOCOL = "aws.iot.securetunneling-1.0";
std::string const DEFAULT_WEB_SOCKET_SUBPROTOCOL = "aws.iot.securetunneling-2.0";

char const * const KEY_WEB_SOCKET_MAX_FRAME_SIZE = "tunneling.proxy.websocket.max_frame_size";
std::size_t const DEFAULT_WEB_SOCKET_MAX_FRAME_SIZE = DEFAULT_MAX_DATA_FRAME_SIZE * 2;
Expand Down
1,166 changes: 903 additions & 263 deletions src/TcpAdapterProxy.cpp

Large diffs are not rendered by default.

182 changes: 98 additions & 84 deletions src/TcpAdapterProxy.h

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions src/TcpClient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <boost/beast/core/flat_buffer.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ip/tcp.hpp>
#include "Message.pb.h"

namespace aws { namespace iot { namespace securedtunneling { namespace connection {
class tcp_client
{
public:
typedef boost::shared_ptr<tcp_client> pointer;
tcp_client(boost::asio::io_context & io_context, std::size_t write_buf_size, std::size_t read_buf_size, std::size_t ws_write_buf_size)
: resolver_(io_context)
{
connection_ =
tcp_connection::create(io_context, write_buf_size, read_buf_size, ws_write_buf_size);
}
static pointer create(boost::asio::io_context& io_context, std::size_t const & write_buf_size, std::size_t const & read_buf_size, std::size_t const & ws_write_buf_size)
{
return pointer(new tcp_client(io_context, write_buf_size, read_buf_size, ws_write_buf_size));
}

tcp_connection::pointer connection_;
tcp::resolver resolver_;
// function object defines what to do after set up a tcp socket
std::function<void()> after_setup_tcp_socket = nullptr;
// function object defines what to do receiving control message: stream start
std::function<void()> on_receive_stream_start = nullptr;
};
}}}}
70 changes: 70 additions & 0 deletions src/TcpConnection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <boost/beast/core/flat_buffer.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "Message.pb.h"

namespace aws { namespace iot { namespace securedtunneling { namespace connection {
using message = com::amazonaws::iot::securedtunneling::Message;
using boost::asio::ip::tcp;
class tcp_connection
: public boost::enable_shared_from_this<tcp_connection>
{
public:
typedef boost::shared_ptr<tcp_connection> pointer;

static pointer create(boost::asio::io_context& io_context, std::size_t const & write_buf_size, std::size_t const & read_buf_size, std::size_t ws_write_buf_size)
{
return pointer(new tcp_connection(io_context, write_buf_size, read_buf_size, ws_write_buf_size));
}

tcp::socket& socket()
{
return socket_;
}

tcp_connection(boost::asio::io_context & io_context, std::size_t write_buf_size, std::size_t read_buf_size, std::size_t ws_write_buf_size)
: socket_(io_context)
, tcp_write_buffer_(write_buf_size)
, tcp_read_buffer_(read_buf_size)
, web_socket_data_write_buffer_(ws_write_buf_size)
{
}

tcp::socket socket_;
// A buffer holding data writes to customer's application
boost::beast::multi_buffer tcp_write_buffer_;
// A buffer holding data reads from customer's application
boost::beast::flat_buffer tcp_read_buffer_;
/**
* A buffer holding data that will be sent to secure tunneling server through web socket connection.
* This buffer will only hold data belongs to its own stream in a multiplexed tunnel.
*/
boost::beast::flat_buffer outgoing_message_buffer_;
//Buffer sequence storing the raw bytes read from the tcp socket reads
//to send over web socket. The bytes in this buffer represent the raw application
//data not already packaged in protobuf messages. This allows us to
//condense smaller TCP read chunks to bigger web socket writes. It also makes
//it impossible to "inject" a non-data message in data sequence order
boost::beast::multi_buffer web_socket_data_write_buffer_;
// Is this tcp socket currently writing
bool is_tcp_socket_writing_{ false };
// Is this tcp socket currently reading
bool is_tcp_socket_reading_{ false };
// function object defines what to do after send a message
std::function<void()> after_send_message;
// function object defines what to do upon receiving control message
std::function<bool(message const &)> on_control_message = nullptr;
// function object defines what to do upon receiving data message
std::function<bool(message const &)> on_data_message = nullptr;
// function object defines what to do if there is a tcp error occurred
std::function<void(boost::system::error_code const&)> on_tcp_error = nullptr;
// function object defines what to do when tcp_write_buffer_ drain has completed
std::function<void()> on_tcp_write_buffer_drain_complete = nullptr;
// function object defines what to do when web_socket_data_write_buffer_ drain has completed
std::function<void()> on_web_socket_write_buffer_drain_complete = nullptr;
};
}}}}
39 changes: 39 additions & 0 deletions src/TcpServer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <boost/beast/core/flat_buffer.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ip/tcp.hpp>
#include "TcpConnection.h"

namespace aws { namespace iot { namespace securedtunneling { namespace connection {
using boost::asio::ip::tcp;
class tcp_server
{
public:
typedef boost::shared_ptr<tcp_server> pointer;
tcp_server(boost::asio::io_context & io_context, std::size_t write_buf_size, std::size_t read_buf_size, std::size_t ws_write_buf_size)
: acceptor_(io_context)
, resolver_(io_context)
{
connection_ =
tcp_connection::create(io_context, write_buf_size, read_buf_size, ws_write_buf_size);
}

static pointer create(boost::asio::io_context& io_context, std::size_t const & write_buf_size, std::size_t const & read_buf_size, std::size_t const & ws_write_buf_size)
{
return pointer(new tcp_server(io_context, write_buf_size, read_buf_size, ws_write_buf_size));
}

tcp::acceptor & acceptor()
{
return acceptor_;
}

tcp::acceptor acceptor_;
tcp::resolver resolver_;
tcp_connection::pointer connection_;
// function object defines what to do after set up a tcp socket
std::function<void()> after_setup_tcp_socket = nullptr;
};
}}}}
Loading

0 comments on commit 8980ea8

Please sign in to comment.