net: Add support for SOCKS5 socket option

The SO_SOCKS5 socket option can be used by the application to
set the SOCKS5 proxy details. These details will be used when
connecting to peer.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
This commit is contained in:
Ravi kumar Veeramally 2019-08-01 16:00:54 +03:00 committed by Jukka Rissanen
commit c8fa169294
4 changed files with 111 additions and 0 deletions

View file

@ -289,6 +289,12 @@ struct net_context {
#endif
#if defined(CONFIG_NET_CONTEXT_TXTIME)
bool txtime;
#endif
#if defined(CONFIG_SOCKS)
struct {
struct sockaddr addr;
socklen_t addrlen;
} proxy;
#endif
} options;
@ -306,6 +312,11 @@ struct net_context {
u8_t ipv6_hop_limit;
u8_t ipv4_ttl;
};
#if defined(CONFIG_SOCKS)
bool proxy_enabled;
#endif
};
static inline bool net_context_is_used(struct net_context *context)
@ -576,6 +587,31 @@ static inline void net_context_set_ipv6_hop_limit(struct net_context *context,
context->ipv6_hop_limit = hop_limit;
}
#if defined(CONFIG_SOCKS)
static inline void net_context_set_proxy_enabled(struct net_context *context,
bool enable)
{
context->proxy_enabled = enable;
}
static inline bool net_context_is_proxy_enabled(struct net_context *context)
{
return context->proxy_enabled;
}
#else
static inline void net_context_set_proxy_enabled(struct net_context *context,
bool enable)
{
ARG_UNUSED(context);
ARG_UNUSED(enable);
}
static inline bool net_context_is_proxy_enabled(struct net_context *context)
{
return false;
}
#endif
/**
* @brief Get network context.
*
@ -951,6 +987,7 @@ enum net_context_option {
NET_OPT_PRIORITY = 1,
NET_OPT_TIMESTAMP = 2,
NET_OPT_TXTIME = 3,
NET_OPT_SOCKS5 = 4,
};
/**

View file

@ -771,6 +771,10 @@ static inline char *inet_ntop(sa_family_t family, const void *src, char *dst,
#define SO_TXTIME 61
#define SCM_TXTIME SO_TXTIME
/* Socket options for SOCKS5 proxy */
/** sockopt: Enable SOCKS5 for Socket */
#define SO_SOCKS5 60
/** @cond INTERNAL_HIDDEN */
/**
* @brief Registration information for a given BSD socket family.

View file

@ -1115,6 +1115,30 @@ static int get_context_timepstamp(struct net_context *context,
#endif
}
static int get_context_proxy(struct net_context *context,
void *value, size_t *len)
{
#if defined(CONFIG_SOCKS)
struct sockaddr *addr = (struct sockaddr *)value;
if (!value || !len) {
return -EINVAL;
}
if (*len < context->options.proxy.addrlen) {
return -EINVAL;
}
*len = MIN(context->options.proxy.addrlen, *len);
memcpy(addr, &context->options.proxy.addr, *len);
return 0;
#else
return -ENOTSUP;
#endif
}
#if defined(CONFIG_NET_CONTEXT_TIMESTAMP)
int net_context_get_timestamp(struct net_context *context,
struct net_pkt *pkt,
@ -1990,6 +2014,29 @@ static int set_context_txtime(struct net_context *context,
#endif
}
static int set_context_proxy(struct net_context *context,
const void *value, size_t len)
{
#if defined(CONFIG_SOCKS)
struct sockaddr *addr = (struct sockaddr *)value;
if (len > NET_SOCKADDR_MAX_SIZE) {
return -EINVAL;
}
if (addr->sa_family != net_context_get_family(context)) {
return -EINVAL;
}
context->options.proxy.addrlen = len;
memcpy(&context->options.proxy.addr, addr, len);
return 0;
#else
return -ENOTSUP;
#endif
}
int net_context_set_option(struct net_context *context,
enum net_context_option option,
const void *value, size_t len)
@ -2014,6 +2061,9 @@ int net_context_set_option(struct net_context *context,
case NET_OPT_TXTIME:
ret = set_context_txtime(context, value, len);
break;
case NET_OPT_SOCKS5:
ret = set_context_proxy(context, value, len);
break;
}
k_mutex_unlock(&context->lock);
@ -2045,6 +2095,9 @@ int net_context_get_option(struct net_context *context,
case NET_OPT_TXTIME:
ret = get_context_txtime(context, value, len);
break;
case NET_OPT_SOCKS5:
ret = get_context_proxy(context, value, len);
break;
}
k_mutex_unlock(&context->lock);

View file

@ -1249,6 +1249,23 @@ int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optname,
return 0;
}
break;
case SO_SOCKS5:
if (IS_ENABLED(CONFIG_SOCKS)) {
ret = net_context_set_option(ctx,
NET_OPT_SOCKS5,
optval, optlen);
if (ret < 0) {
errno = -ret;
return -1;
}
net_context_set_proxy_enabled(ctx, true);
return 0;
}
break;
}