From df0d7652df60850dc43272e5ef8235dfc966652e Mon Sep 17 00:00:00 2001 From: Tomasz Gorochowik Date: Mon, 4 Feb 2019 16:11:46 +0100 Subject: [PATCH] net: mqtt: Add SOCKS5 proxy support This commits adds a new MQTT transport. The purpose is to be able to connect to a MQTT broker through a SOCKS5 proxy. Signed-off-by: Tomasz Gorochowik --- include/net/mqtt.h | 17 ++++++++ subsys/net/lib/mqtt/CMakeLists.txt | 4 ++ subsys/net/lib/mqtt/Kconfig | 6 +++ subsys/net/lib/mqtt/mqtt_transport.c | 15 ++++++- subsys/net/lib/mqtt/mqtt_transport_socks.c | 47 ++++++++++++++++++++++ 5 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 subsys/net/lib/mqtt/mqtt_transport_socks.c diff --git a/include/net/mqtt.h b/include/net/mqtt.h index 2fd63885372..feae487bcce 100644 --- a/include/net/mqtt.h +++ b/include/net/mqtt.h @@ -348,6 +348,11 @@ enum mqtt_transport_type { MQTT_TRANSPORT_SECURE, #endif /* CONFIG_MQTT_LIB_TLS */ +#if defined(CONFIG_MQTT_LIB_SOCKS) + /** Use SOCKS5 proxy for MQTT connection. */ + MQTT_TRANSPORT_SOCKS, +#endif /* CONFIG_MQTT_LIB_SOCKS */ + /** Shall not be used as a transport type. * Indicator of maximum transport types possible. */ @@ -381,6 +386,18 @@ struct mqtt_transport { struct mqtt_sec_config config; } tls; #endif /* CONFIG_MQTT_LIB_TLS */ + +#if defined(CONFIG_MQTT_LIB_SOCKS) + /* SOCKS5 proxy transport for MQTT */ + struct { + /** Socket descriptor. */ + int sock; + + /** SOCKS5 proxy address. */ + struct sockaddr_storage *proxy; + } socks5; +#endif /* CONFIG_MQTT_LIB_SOCKS */ + }; }; diff --git a/subsys/net/lib/mqtt/CMakeLists.txt b/subsys/net/lib/mqtt/CMakeLists.txt index b6cf9e26842..2055005604e 100644 --- a/subsys/net/lib/mqtt/CMakeLists.txt +++ b/subsys/net/lib/mqtt/CMakeLists.txt @@ -12,3 +12,7 @@ zephyr_library_sources( zephyr_library_sources_ifdef(CONFIG_MQTT_LIB_TLS mqtt_transport_socket_tls.c ) + +zephyr_library_sources_ifdef(CONFIG_MQTT_LIB_SOCKS + mqtt_transport_socks.c + ) diff --git a/subsys/net/lib/mqtt/Kconfig b/subsys/net/lib/mqtt/Kconfig index b53e00dadcc..1c511f27fc3 100644 --- a/subsys/net/lib/mqtt/Kconfig +++ b/subsys/net/lib/mqtt/Kconfig @@ -32,4 +32,10 @@ config MQTT_LIB_TLS help Enable TLS support for socket MQTT Library +config MQTT_LIB_SOCKS + bool "SOCKS proxy support for socket MQTT Library" + select SOCKS + help + Enable SOCKS proxy support for socket MQTT Library + endif # MQTT_LIB diff --git a/subsys/net/lib/mqtt/mqtt_transport.c b/subsys/net/lib/mqtt/mqtt_transport.c index 6d7cc7183c1..ebf33e65ed9 100644 --- a/subsys/net/lib/mqtt/mqtt_transport.c +++ b/subsys/net/lib/mqtt/mqtt_transport.c @@ -29,6 +29,11 @@ extern int mqtt_client_tls_read(struct mqtt_client *client, u8_t *data, extern int mqtt_client_tls_disconnect(struct mqtt_client *client); #endif /* CONFIG_MQTT_LIB_TLS */ +#if defined(CONFIG_MQTT_LIB_SOCKS) +/* Transport handler functions for SOCKS5 proxy socket transport. */ +extern int mqtt_client_socks5_connect(struct mqtt_client *client); +#endif /* CONFIG_MQTT_LIB_SOCKS */ + /**@brief Function pointer array for TCP/TLS transport handlers. */ const struct transport_procedure transport_fn[MQTT_TRANSPORT_NUM] = { { @@ -43,8 +48,16 @@ const struct transport_procedure transport_fn[MQTT_TRANSPORT_NUM] = { mqtt_client_tls_write, mqtt_client_tls_read, mqtt_client_tls_disconnect, - } + }, #endif /* CONFIG_MQTT_LIB_TLS */ +#if defined(CONFIG_MQTT_LIB_SOCKS) + { + mqtt_client_socks5_connect, + mqtt_client_tcp_write, + mqtt_client_tcp_read, + mqtt_client_tcp_disconnect, + }, +#endif /* CONFIG_MQTT_LIB_SOCKS */ }; int mqtt_transport_connect(struct mqtt_client *client) diff --git a/subsys/net/lib/mqtt/mqtt_transport_socks.c b/subsys/net/lib/mqtt/mqtt_transport_socks.c new file mode 100644 index 00000000000..0e44844362b --- /dev/null +++ b/subsys/net/lib/mqtt/mqtt_transport_socks.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 Antmicro Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file mqtt_transport_socks.c + * + * @brief Internal functions to handle transport over SOCKS5 proxy. + */ + +#include +LOG_MODULE_REGISTER(net_mqtt_socks, CONFIG_MQTT_LOG_LEVEL); + +#include +#include +#include +#include + +#include "mqtt_os.h" + +/**@brief Handles connect request for TCP socket transport. + * + * @param[in] client Identifies the client on which the procedure is requested. + * + * @retval 0 or an error code indicating reason for failure. + */ +int mqtt_client_socks5_connect(struct mqtt_client *client) +{ + const struct sockaddr *broker = client->broker; + const struct sockaddr *proxy = + (struct sockaddr *)client->transport.socks5.proxy; + + if (proxy == NULL || broker == NULL) { + return -EINVAL; + } + + client->transport.socks5.sock = + socks5_client_tcp_connect(proxy, broker); + + if (client->transport.socks5.sock < 0) { + return client->transport.socks5.sock; + } + + MQTT_TRC("Connect completed"); + return 0; +}