From 85ef00deb4a31bdcb654c69b8178d7e462193f70 Mon Sep 17 00:00:00 2001 From: Ravi kumar Veeramally Date: Tue, 13 Aug 2019 11:44:00 +0300 Subject: [PATCH] samples: net: echo_client: Add SOCKS5 support SOCKS5 support added to echo_client. Details are added in README file about how to verify this feature using echo-client with echo-server running on Linux host. Signed-off-by: Ravi kumar Veeramally --- samples/net/sockets/echo_client/README.rst | 38 +++++++++++++++++ .../sockets/echo_client/overlay-socks5.conf | 1 + samples/net/sockets/echo_client/src/tcp.c | 42 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 samples/net/sockets/echo_client/overlay-socks5.conf diff --git a/samples/net/sockets/echo_client/README.rst b/samples/net/sockets/echo_client/README.rst index 794096a7fdb..6cbc0892a4f 100644 --- a/samples/net/sockets/echo_client/README.rst +++ b/samples/net/sockets/echo_client/README.rst @@ -90,6 +90,44 @@ The certificate and private key used by the sample can be found in the sample's :ref:`sockets-echo-server-sample` enable establishing a secure connection between the samples. +SOCKS5 proxy support +==================== + +It is also possible to connect to the echo-server through a SOCKS5 proxy. +To enable it, use ``-DOVERLAY_CONFIG=overlay-socks5.conf`` when running ``west +build`` or ``cmake``. + +By default, to make the testing easier, the proxy is expected to run on the +same host as the echo-server in Linux host. + +To start a proxy server, for example a builtin SOCKS server support in ssh +can be used (-D option). Use the following command to run it on your host +with the default port: + +For IPv4 proxy server: + +.. code-block: console + + $ ssh -N -D 0.0.0.0:1080 localhost + +For IPv6 proxy server: + +.. code-block: console + + $ ssh -N -D [::]:1080 localhost + +Run both commands if you are testing IPv4 and IPv6. + +To connect to a proxy server that is not running under the same IP as the +echo-server or uses a different port number, modify the following values +in echo_client/src/tcp.c. + +.. code-block:: c + + #define SOCKS5_PROXY_V4_ADDR IPV4_ADDR + #define SOCKS5_PROXY_V6_ADDR IPV6_ADDR + #define SOCKS5_PROXY_PORT 1080 + Running echo-server in Linux Host ================================= diff --git a/samples/net/sockets/echo_client/overlay-socks5.conf b/samples/net/sockets/echo_client/overlay-socks5.conf new file mode 100644 index 00000000000..807940e92a7 --- /dev/null +++ b/samples/net/sockets/echo_client/overlay-socks5.conf @@ -0,0 +1 @@ +CONFIG_SOCKS=y diff --git a/samples/net/sockets/echo_client/src/tcp.c b/samples/net/sockets/echo_client/src/tcp.c index e3b4dca61e6..7794b46fc2f 100644 --- a/samples/net/sockets/echo_client/src/tcp.c +++ b/samples/net/sockets/echo_client/src/tcp.c @@ -22,6 +22,15 @@ LOG_MODULE_DECLARE(net_echo_client_sample, LOG_LEVEL_DBG); #define RECV_BUF_SIZE 128 +/* These proxy server addresses are only used when CONFIG_SOCKS + * is enabled. To connect to a proxy server that is not running + * under the same IP as the peer or uses a different port number, + * modify the values. + */ +#define SOCKS5_PROXY_V6_ADDR CONFIG_NET_CONFIG_PEER_IPV6_ADDR +#define SOCKS5_PROXY_V4_ADDR CONFIG_NET_CONFIG_PEER_IPV4_ADDR +#define SOCKS5_PROXY_PORT 1080 + static ssize_t sendall(int sock, const void *buf, size_t len) { while (len) { @@ -91,6 +100,39 @@ static int start_tcp_proto(struct data *data, struct sockaddr *addr, return -errno; } + if (IS_ENABLED(CONFIG_SOCKS)) { + struct sockaddr proxy_addr; + socklen_t proxy_addrlen; + + if (addr->sa_family == AF_INET) { + struct sockaddr_in *proxy4 = + (struct sockaddr_in *)&proxy_addr; + + proxy4->sin_family = AF_INET; + proxy4->sin_port = htons(SOCKS5_PROXY_PORT); + inet_pton(AF_INET, SOCKS5_PROXY_V4_ADDR, + &proxy4->sin_addr); + proxy_addrlen = sizeof(struct sockaddr_in); + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6 *proxy6 = + (struct sockaddr_in6 *)&proxy_addr; + + proxy6->sin6_family = AF_INET6; + proxy6->sin6_port = htons(SOCKS5_PROXY_PORT); + inet_pton(AF_INET6, SOCKS5_PROXY_V6_ADDR, + &proxy6->sin6_addr); + proxy_addrlen = sizeof(struct sockaddr_in6); + } else { + return -EINVAL; + } + + ret = setsockopt(data->tcp.sock, SOL_SOCKET, SO_SOCKS5, + &proxy_addr, proxy_addrlen); + if (ret < 0) { + return ret; + } + } + #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) sec_tag_t sec_tag_list[] = { CA_CERTIFICATE_TAG,