Skip to content

Commit

Permalink
In order for proper usage, we needed default constructors for Tls stu… (
Browse files Browse the repository at this point in the history
#20)

* In order for proper usage, we needed default constructors for Tls stuff. Also fixed idiotic mistake on mqtt client not allocating for hostname.

* Metrics tracking, simplify mqtt client setup.

* Reworked header order in main.cpp.

* Added missing header file install.

* Updated comment on lifetimes.

* Zeroing out c++ objects during destruction considered harmful.

* Updated .gitignore.
  • Loading branch information
JonathanHenson authored Apr 13, 2019
1 parent be7daab commit a47d172
Show file tree
Hide file tree
Showing 12 changed files with 503 additions and 81 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.idea
.DS_Store

include/aws/crt/Config.h
16 changes: 16 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ if (NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 11)
endif()

set(AWS_CRT_CPP_VERSION "v0.3.0")
configure_file(include/aws/crt/Config.h.in ${CMAKE_CURRENT_LIST_DIR}/include/aws/crt/Config.h @ONLY)

if (BUILD_DEPS)
set(AWS_DEPS_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps)
if (DEFINED CMAKE_INSTALL_PREFIX)
Expand Down Expand Up @@ -107,6 +110,10 @@ file(GLOB AWS_CRT_IO_HEADERS
"include/aws/crt/io/*.h"
)

file(GLOB AWS_CRT_IOT_HEADERS
"include/aws/iot/*.h"
)

file(GLOB AWS_CRT_MQTT_HEADERS
"include/aws/crt/mqtt/*.h"
)
Expand All @@ -123,6 +130,7 @@ file(GLOB AWS_CRT_CPP_HEADERS
${AWS_CRT_HEADERS}
${AWS_CRT_CRYPTO_HEADERS}
${AWS_CRT_IO_HEADERS}
${AWS_CRT_IOT_HEADERS}
${AWS_CRT_MQTT_HEADERS}
${AWS_CRT_HTTP_HEADERS}
${AWS_CRT_EXTERNAL_HEADERS}
Expand All @@ -140,6 +148,10 @@ file (GLOB AWS_CRT_IO_SRC
"source/io/*.cpp"
)

file (GLOB AWS_CRT_IOT_SRC
"source/iot/*.cpp"
)

file (GLOB AWS_CRT_MQTT_SRC
"source/mqtt/*.cpp"
)
Expand All @@ -156,6 +168,7 @@ file(GLOB AWS_CRT_CPP_SRC
${AWS_CRT_SRC}
${AWS_CRT_CRYPTO_SRC}
${AWS_CRT_IO_SRC}
${AWS_CRT_IOT_SRC}
${AWS_CRT_MQTT_SRC}
${AWS_CRT_HTTP_SRC}
${AWS_CRT_EXTERNAL_CRC}
Expand All @@ -166,13 +179,15 @@ if (WIN32)
source_group("Header Files\\aws\\crt" FILES ${AWS_CRT_HEADERS})
source_group("Header Files\\aws\\crt\\crypto" FILES ${AWS_CRT_CRYPTO_HEADERS})
source_group("Header Files\\aws\\crt\\io" FILES ${AWS_CRT_IO_HEADERS})
source_group("Header Files\\aws\\iot" FILES ${AWS_CRT_IOT_HEADERS})
source_group("Header Files\\aws\\crt\\mqtt" FILES ${AWS_CRT_MQTT_HEADERS})
source_group("Header Files\\aws\\crt\\http" FILES ${AWS_CRT_HTTP_HEADERS})
source_group("Header Files\\aws\\crt\\external" FILES ${AWS_CRT_EXTERNAL_HEADERS})

source_group("Source Files" FILES ${AWS_CRT_SRC})
source_group("Source Files\\crypto" FILES ${AWS_CRT_CRYPTO_SRC})
source_group("Source Files\\io" FILES ${AWS_CRT_IO_SRC})
source_group("Source Files\\iot" FILES ${AWS_CRT_IOT_SRC})
source_group("Source Files\\mqtt" FILES ${AWS_CRT_MQTT_SRC})
source_group("Source Files\\http" FILES ${AWS_CRT_HTTP_SRC})
source_group("Source Files\\external" FILES ${AWS_CRT_EXTERNAL_SRC})
Expand Down Expand Up @@ -214,6 +229,7 @@ target_link_libraries(${CMAKE_PROJECT_NAME} AWS::aws-c-cal AWS::aws-c-http AWS::
install(FILES ${AWS_CRT_HEADERS} DESTINATION "include/aws/crt" COMPONENT Development)
install(FILES ${AWS_CRT_CRYPTO_HEADERS} DESTINATION "include/aws/crt/crypto" COMPONENT Development)
install(FILES ${AWS_CRT_IO_HEADERS} DESTINATION "include/aws/crt/io" COMPONENT Development)
install(FILES ${AWS_CRT_IOT_HEADERS} DESTINATION "include/aws/iot" COMPONENT Development)
install(FILES ${AWS_CRT_MQTT_HEADERS} DESTINATION "include/aws/crt/mqtt" COMPONENT Development)
install(FILES ${AWS_CRT_HTTP_HEADERS} DESTINATION "include/aws/crt/http" COMPONENT Development)
install(FILES ${AWS_CRT_EXTERNAL_HEADERS} DESTINATION "include/aws/crt/external" COMPONENT Development)
Expand Down
1 change: 1 addition & 0 deletions include/aws/crt/Api.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ namespace Aws

AWS_CRT_CPP_API void LoadErrorStrings() noexcept;
AWS_CRT_CPP_API const char *ErrorDebugString(int error) noexcept;
AWS_CRT_CPP_API int LastError() noexcept;
} // namespace Crt
} // namespace Aws
16 changes: 16 additions & 0 deletions include/aws/crt/Config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once
/*
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.
*/
#cmakedefine AWS_CRT_CPP_VERSION "@AWS_CRT_CPP_VERSION@"
26 changes: 20 additions & 6 deletions include/aws/crt/io/TlsOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ namespace Aws
friend class TlsContext;

public:
TlsContextOptions() noexcept;
~TlsContextOptions();
TlsContextOptions(const TlsContextOptions &) noexcept = default;
TlsContextOptions &operator=(const TlsContextOptions &) noexcept = default;
TlsContextOptions(const TlsContextOptions &) noexcept = delete;
TlsContextOptions &operator=(const TlsContextOptions &) noexcept = delete;
TlsContextOptions(TlsContextOptions &&) noexcept;
TlsContextOptions &operator=(TlsContextOptions &&) noexcept;

/**
* Initializes TlsContextOptions with secure by default options, with
Expand All @@ -48,15 +51,24 @@ namespace Aws
static TlsContextOptions InitDefaultClient(Allocator *allocator = DefaultAllocator()) noexcept;
/**
* Initializes TlsContextOptions with secure by default options, with
* client certificate and private key. These are paths to a file on disk. These
* strings must remain in memory for the lifetime of the returned object. These files
* client certificate and private key. These are paths to a file on disk. These files
* must be in the PEM format.
*/
static TlsContextOptions InitClientWithMtls(
const char *cert_path,
const char *pkey_path,
Allocator *allocator = DefaultAllocator()) noexcept;

/**
* Initializes TlsContextOptions with secure by default options, with
* client certificate and private key. These are in memory buffers. These buffers
* must be in the PEM format.
*/
static TlsContextOptions InitClientWithMtls(
const ByteCursor &cert,
const ByteCursor &pkey,
Allocator *allocator = DefaultAllocator()) noexcept;

#ifdef __APPLE__
/**
* Initializes TlsContextOptions with secure by default options, with
Expand Down Expand Up @@ -101,10 +113,11 @@ namespace Aws
*/
void OverrideDefaultTrustStore(const char *caPath, const char *caFile) noexcept;

void OverrideDefaultTrustStore(const ByteCursor &ca) noexcept;

private:
aws_tls_ctx_options m_options;

TlsContextOptions() noexcept;
bool m_isInit;
};

/**
Expand Down Expand Up @@ -156,6 +169,7 @@ namespace Aws
class AWS_CRT_CPP_API TlsContext final
{
public:
TlsContext() noexcept;
TlsContext(
TlsContextOptions &options,
TlsMode mode,
Expand Down
2 changes: 1 addition & 1 deletion include/aws/crt/mqtt/MqttClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ namespace Aws
aws_mqtt_client *m_owningClient;
aws_mqtt_client_connection *m_underlyingConnection;
std::atomic<ConnectionState> m_connectionState;
ByteBuf m_hostNameBuf;
String m_hostName;
uint16_t m_port;
Io::TlsConnectionOptions m_tlsOptions;
Io::SocketOptions m_socketOptions;
Expand Down
159 changes: 159 additions & 0 deletions include/aws/iot/MqttClient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#pragma once
/*
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 <aws/crt/Exports.h>
#include <aws/crt/mqtt/MqttClient.h>

namespace Aws
{
namespace Iot
{
class MqttClient;

/**
* Represents a unique configuration for connecting to a single endpoint. You can use a single instance of this
* class PER endpoint you want to connect to. This object must live through the lifetime of your connection.
*/
class AWS_CRT_CPP_API MqttClientConnectionConfig final
{
public:
MqttClientConnectionConfig() noexcept;
MqttClientConnectionConfig(
const Crt::String &endpoint,
uint16_t port,
const Crt::Io::SocketOptions &socketOptions,
Crt::Io::TlsContext &&tlsContext);

explicit operator bool() const noexcept { return m_context ? true : false; }

private:
Crt::String m_endpoint;
uint16_t m_port;
Crt::Io::TlsContext m_context;
Crt::Io::SocketOptions m_socketOptions;

friend class MqttClient;
};

/**
* Represents configuration parameters for building a MqttClientConnectionConfig object. You can use a single
* instance of this class PER MqttClientConnectionConfig you want to generate. If you want to generate a config
* for a different endpoint or port etc... you need a new instance of this class.
*/
class AWS_CRT_CPP_API MqttClientConnectionConfigBuilder final
{
public:
/**
* Sets the builder up for MTLS using certPath and pkeyPath. These are files on disk and must be in the PEM
* format.
*/
MqttClientConnectionConfigBuilder(
const char *certPath,
const char *pkeyPath,
Crt::Allocator *allocator = Crt::DefaultAllocator()) noexcept;
/**
* Sets the builder up for MTLS using cert and pkey. These are in-memory buffers and must be in the PEM
* format.
*/
MqttClientConnectionConfigBuilder(
const Crt::ByteCursor &cert,
const Crt::ByteCursor &pkey,
Crt::Allocator *allocator = Crt::DefaultAllocator()) noexcept;

/**
* Sets endpoint to connect to.
*/
MqttClientConnectionConfigBuilder &WithEndpoint(const Crt::String &endpoint);

/**
* Sets endpoint to connect to.
*/
MqttClientConnectionConfigBuilder &WithEndpoint(Crt::String &&endpoint);

/**
* Overrides the default port. By default, if ALPN is supported, 443 will be used. Otherwise 8883 will be
* used. If you specify 443 and ALPN is not supported, we will still attempt to connect over 443 without
* ALPN.
*/
MqttClientConnectionConfigBuilder &WithPortOverride(uint16_t port) noexcept;

/**
* Sets the certificate authority for the endpoint you're connecting to. This is a path to a file on disk
* and must be in PEM format.
*/
MqttClientConnectionConfigBuilder &WithCertificateAuthority(const char *caPath) noexcept;

/**
* Sets the certificate authority for the endpoint you're connecting to. This is an in-memory buffer and
* must be in PEM format.
*/
MqttClientConnectionConfigBuilder &WithCertificateAuthority(const Crt::ByteCursor &cert) noexcept;

/** TCP option: Enables TCP keep alive. Defaults to off. */
MqttClientConnectionConfigBuilder &WithTcpKeepAlive() noexcept;

/** TCP option: Sets the connect timeout. Defaults to 3 seconds. */
MqttClientConnectionConfigBuilder &WithTcpConnectTimeout(uint32_t connectTimeoutMs) noexcept;

/** TCP option: Sets time before keep alive probes are sent. Defaults to kernel defaults */
MqttClientConnectionConfigBuilder &WithTcpKeepAliveTimeout(uint16_t keepAliveTimeoutSecs) noexcept;

/**
* TCP option: Sets the frequency of sending keep alive probes in seconds once the keep alive timeout
* expires. Defaults to kernel defaults.
*/
MqttClientConnectionConfigBuilder &WithTcpKeepAliveInterval(uint16_t keepAliveIntervalSecs) noexcept;

/**
* TCP option: Sets the amount of keep alive probes allowed to fail before the connection is terminated.
* Defaults to kernel defaults.
*/
MqttClientConnectionConfigBuilder &WithTcpKeepAliveMaxProbes(uint16_t maxProbes) noexcept;

/**
* Builds a client configuration object from the set options.
*/
MqttClientConnectionConfig Build() noexcept;

private:
Crt::Allocator *m_allocator;
Crt::String m_endpoint;
uint16_t m_portOverride;
Crt::Io::SocketOptions m_socketOptions;
Crt::Io::TlsContextOptions m_contextOptions;
};

/**
* AWS IOT specific Mqtt Client. Sets defaults for using the AWS IOT service. You'll need an instance of
* MqttClientConnectionConfig to use. Once NewConnection returns, you use it's return value identically
* to how you would use Aws::Crt::Mqtt::MqttConnection
*/
class AWS_CRT_CPP_API MqttClient final
{
public:
MqttClient(
Crt::Io::ClientBootstrap &bootstrap,
Crt::Allocator *allocator = Crt::DefaultAllocator()) noexcept;

std::shared_ptr<Crt::Mqtt::MqttConnection> NewConnection(const MqttClientConnectionConfig &config) noexcept;

int LastError() const noexcept { return m_client.LastError(); }
explicit operator bool() const noexcept { return m_client ? true : false; }

private:
Crt::Mqtt::MqttClient m_client;
};
} // namespace Iot
} // namespace Aws
Loading

0 comments on commit a47d172

Please sign in to comment.