net: app: Fix dual IPv4 and IPv6 support

It was not possible to send IPv4 packets if IPv6 was also
enabled.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2017-07-01 00:39:16 +03:00
commit 7a31d4b8cb
7 changed files with 296 additions and 152 deletions

View file

@ -233,17 +233,30 @@ typedef int (*net_app_entropy_src_cb_t)(void *data, unsigned char *output,
size_t len, size_t *olen);
#endif /* CONFIG_NET_APP_TLS */
/* Information for the context and local/remote addresses used. */
struct net_app_endpoint {
/** Network context. */
struct net_context *ctx;
/** Local address */
struct sockaddr local;
/** Remote address */
struct sockaddr remote;
};
/** Network application context. */
struct net_app_ctx {
#if defined(CONFIG_NET_IPV6)
/** Network IPv6 context. */
struct net_context *ipv6_ctx;
struct net_app_endpoint ipv6;
#endif
#if defined(CONFIG_NET_IPV4)
/** Network IPv4 context. */
struct net_context *ipv4_ctx;
struct net_app_endpoint ipv4;
#endif
/** What is the default endpoint for this context. */
struct net_app_endpoint *default_ctx;
/** Internal function that is called when user data is sent to
* network. By default this is set to net_context_sendto() but
* is overridden for TLS as it requires special handling.
@ -259,12 +272,6 @@ struct net_app_ctx {
*/
net_context_recv_cb_t recv_cb;
/** Local address */
struct sockaddr local;
/** Remote address */
struct sockaddr remote;
#if defined(CONFIG_NET_APP_SERVER)
struct {
#if defined(CONFIG_NET_TCP)
@ -763,11 +770,13 @@ int net_app_send_buf(struct net_app_ctx *ctx,
* @brief Create network packet.
*
* @param ctx Network application context.
* @param family What kind of network packet to get (AF_INET or AF_INET6)
* @param timeout How long to wait the send before giving up.
*
* @return valid net_pkt if ok, NULL if error.
*/
struct net_pkt *net_app_get_net_pkt(struct net_app_ctx *ctx,
sa_family_t family,
s32_t timeout);
/**

View file

@ -133,7 +133,7 @@ struct net_pkt *prepare_send_pkt(struct net_app_ctx *ctx,
struct net_pkt *send_pkt;
bool status;
send_pkt = net_app_get_net_pkt(ctx, K_FOREVER);
send_pkt = net_app_get_net_pkt(ctx, AF_UNSPEC, K_FOREVER);
NET_ASSERT(send_pkt);

View file

@ -72,7 +72,7 @@ struct net_pkt *build_reply_pkt(const char *name,
return NULL;
}
reply_pkt = net_app_get_net_pkt(ctx, K_FOREVER);
reply_pkt = net_app_get_net_pkt(ctx, net_pkt_family(pkt), K_FOREVER);
NET_ASSERT(reply_pkt);

View file

@ -44,15 +44,17 @@ static void dns_cb(enum dns_resolve_status status,
if (info->ai_family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
net_ipaddr_copy(&net_sin(&ctx->remote)->sin_addr,
net_ipaddr_copy(&net_sin(&ctx->ipv4.remote)->sin_addr,
&net_sin(&info->ai_addr)->sin_addr);
ctx->ipv4.remote.family = info->ai_family;
#else
goto out;
#endif
} else if (info->ai_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
net_ipaddr_copy(&net_sin6(&ctx->remote)->sin6_addr,
net_ipaddr_copy(&net_sin6(&ctx->ipv6.remote)->sin6_addr,
&net_sin6(&info->ai_addr)->sin6_addr);
ctx->ipv6.remote.family = info->ai_family;
#else
goto out;
#endif
@ -60,8 +62,6 @@ static void dns_cb(enum dns_resolve_status status,
goto out;
}
ctx->remote.family = info->ai_family;
out:
k_sem_give(&ctx->client.dns_wait);
}
@ -94,7 +94,7 @@ static int resolve_name(struct net_app_ctx *ctx,
ctx->client.dns_id = 0;
if (ctx->remote.family == AF_UNSPEC) {
if (ctx->default_ctx.remote.family == AF_UNSPEC) {
return -EINVAL;
}
@ -188,7 +188,7 @@ static int set_remote_addr(struct net_app_ctx *ctx,
#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4)
ret = net_addr_pton(AF_INET6, addr,
&net_sin6(&ctx->remote)->sin6_addr);
&net_sin6(&ctx->ipv6.remote)->sin6_addr);
if (ret < 0) {
/* Could be hostname, try DNS if configured. */
#if !defined(CONFIG_DNS_RESOLVER)
@ -203,13 +203,15 @@ static int set_remote_addr(struct net_app_ctx *ctx,
#endif
}
net_sin6(&ctx->remote)->sin6_port = htons(peer_port);
net_sin6(&ctx->remote)->sin6_family = AF_INET6;
net_sin6(&ctx->ipv6.remote)->sin6_port = htons(peer_port);
net_sin6(&ctx->ipv6.remote)->sin6_family = AF_INET6;
ctx->ipv6.remote.family = AF_INET6;
ctx->default_ctx = &ctx->ipv6;
#endif /* IPV6 && !IPV4 */
#if defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6)
ret = net_addr_pton(AF_INET, addr,
&net_sin(&ctx->remote)->sin_addr);
&net_sin(&ctx->ipv4.remote)->sin_addr);
if (ret < 0) {
/* Could be hostname, try DNS if configured. */
#if !defined(CONFIG_DNS_RESOLVER)
@ -224,16 +226,18 @@ static int set_remote_addr(struct net_app_ctx *ctx,
#endif
}
net_sin(&ctx->remote)->sin_port = htons(peer_port);
net_sin(&ctx->remote)->sin_family = AF_INET;
net_sin(&ctx->ipv4.remote)->sin_port = htons(peer_port);
net_sin(&ctx->ipv4.remote)->sin_family = AF_INET;
ctx->ipv4.remote.family = AF_INET;
ctx->default_ctx = &ctx->ipv4;
#endif /* IPV6 && !IPV4 */
#if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_IPV6)
ret = net_addr_pton(AF_INET, addr,
&net_sin(&ctx->remote)->sin_addr);
&net_sin(&ctx->ipv4.remote)->sin_addr);
if (ret < 0) {
ret = net_addr_pton(AF_INET6, addr,
&net_sin6(&ctx->remote)->sin6_addr);
&net_sin6(&ctx->ipv6.remote)->sin6_addr);
if (ret < 0) {
/* Could be hostname, try DNS if configured. */
#if !defined(CONFIG_DNS_RESOLVER)
@ -261,23 +265,28 @@ static int set_remote_addr(struct net_app_ctx *ctx,
#if defined(CONFIG_DNS_RESOLVER)
ipv6:
#endif
net_sin6(&ctx->remote)->sin6_port =
net_sin6(&ctx->ipv6.remote)->sin6_port =
htons(peer_port);
net_sin6(&ctx->remote)->sin6_family = AF_INET6;
net_sin6(&ctx->ipv6.remote)->sin6_family = AF_INET6;
ctx->ipv6.remote.family = AF_INET6;
ctx->default_ctx = &ctx->ipv6;
}
} else {
#if defined(CONFIG_DNS_RESOLVER)
ipv4:
#endif
net_sin(&ctx->remote)->sin_port = htons(peer_port);
net_sin(&ctx->remote)->sin_family = AF_INET;
net_sin(&ctx->ipv4.remote)->sin_port = htons(peer_port);
net_sin(&ctx->ipv4.remote)->sin_family = AF_INET;
ctx->ipv4.remote.family = AF_INET;
ctx->default_ctx = &ctx->ipv4;
}
#endif /* IPV4 && IPV6 */
/* If we have not yet figured out what is the protocol family,
* then we cannot continue.
*/
if (ctx->remote.family == AF_UNSPEC) {
if (!ctx->default_ctx ||
ctx->default_ctx->remote.family == AF_UNSPEC) {
NET_ERR("Unknown protocol family.");
return -EPFNOSUPPORT;
}
@ -327,8 +336,24 @@ int net_app_init_client(struct net_app_ctx *ctx,
}
if (peer_addr) {
memcpy(&ctx->remote, peer_addr,
sizeof(ctx->remote));
if (peer_addr->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
memcpy(&ctx->ipv4.remote, peer_addr,
sizeof(ctx->ipv4.remote));
ctx->default_ctx = &ctx->ipv4;
#else
return -EPROTONOSUPPORT;
#endif
} else if (peer_addr->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
memcpy(&ctx->ipv6.remote, peer_addr,
sizeof(ctx->ipv6.remote));
ctx->default_ctx = &ctx->ipv6;
#else
return -EPROTONOSUPPORT;
#endif
}
goto out;
}
@ -344,33 +369,35 @@ int net_app_init_client(struct net_app_ctx *ctx,
}
#if defined(CONFIG_NET_IPV4)
if (ctx->remote.family == AF_INET) {
ctx->local.family = AF_INET;
_net_app_set_local_addr(&ctx->local, NULL,
net_sin(&ctx->local)->sin_port);
if (ctx->ipv4.remote.family == AF_INET) {
ctx->ipv4.local.family = AF_INET;
_net_app_set_local_addr(&ctx->ipv4.local, NULL,
net_sin(&ctx->ipv4.local)->sin_port);
ret = _net_app_set_net_ctx(ctx, ctx->ipv4_ctx, &ctx->local,
ret = _net_app_set_net_ctx(ctx, ctx->ipv4.ctx,
&ctx->ipv4.local,
sizeof(struct sockaddr_in),
ctx->proto);
if (ret < 0) {
net_context_put(ctx->ipv4_ctx);
ctx->ipv4_ctx = NULL;
net_context_put(ctx->ipv4.ctx);
ctx->ipv4.ctx = NULL;
}
}
#endif
#if defined(CONFIG_NET_IPV6)
if (ctx->remote.family == AF_INET6) {
ctx->local.family = AF_INET6;
_net_app_set_local_addr(&ctx->local, NULL,
net_sin6(&ctx->local)->sin6_port);
if (ctx->ipv6.remote.family == AF_INET6) {
ctx->ipv6.local.family = AF_INET6;
_net_app_set_local_addr(&ctx->ipv6.local, NULL,
net_sin6(&ctx->ipv6.local)->sin6_port);
ret = _net_app_set_net_ctx(ctx, ctx->ipv6_ctx, &ctx->local,
ret = _net_app_set_net_ctx(ctx, ctx->ipv6.ctx,
&ctx->ipv6.local,
sizeof(struct sockaddr_in6),
ctx->proto);
if (ret < 0) {
net_context_put(ctx->ipv6_ctx);
ctx->ipv6_ctx = NULL;
net_context_put(ctx->ipv6.ctx);
ctx->ipv6.ctx = NULL;
}
}
#endif
@ -432,7 +459,7 @@ int net_app_connect(struct net_app_ctx *ctx, s32_t timeout)
return -EINVAL;
}
net_ctx = _net_app_select_net_ctx(ctx);
net_ctx = _net_app_select_net_ctx(ctx, NULL);
if (!net_ctx) {
return -EAFNOSUPPORT;
}
@ -456,8 +483,8 @@ int net_app_connect(struct net_app_ctx *ctx, s32_t timeout)
#endif /* CONFIG_NET_APP_TLS */
ret = net_context_connect(net_ctx,
&ctx->remote,
sizeof(ctx->remote),
&ctx->default_ctx->remote,
sizeof(ctx->default_ctx->remote),
_app_connected,
timeout,
ctx);

View file

@ -67,6 +67,22 @@ char *_net_app_sprint_ipaddr(char *buf, int buflen,
return buf;
}
void _net_app_print_info(struct net_app_ctx *ctx)
{
#define PORT_STR_LEN sizeof("[]:xxxxx")
char local[NET_IPV6_ADDR_LEN + PORT_STR_LEN];
char remote[NET_IPV6_ADDR_LEN + PORT_STR_LEN];
_net_app_sprint_ipaddr(local, sizeof(local), &ctx->default_ctx->local);
_net_app_sprint_ipaddr(remote, sizeof(remote),
&ctx->default_ctx->remote);
NET_DBG("net app connect %s %s %s",
local,
ctx->app_type == NET_APP_CLIENT ? "->" : "<-",
remote);
}
#endif /* CONFIG_NET_DEBUG_APP */
#if defined(CONFIG_NET_APP_SERVER) || defined(CONFIG_NET_APP_CLIENT)
@ -228,14 +244,14 @@ static int setup_ipv4_ctx(struct net_app_ctx *ctx,
{
int ret;
ret = net_context_get(AF_INET, sock_type, proto, &ctx->ipv4_ctx);
ret = net_context_get(AF_INET, sock_type, proto, &ctx->ipv4.ctx);
if (ret < 0) {
NET_ERR("Cannot get network context (%d)", ret);
ctx->ipv4_ctx = NULL;
ctx->ipv4.ctx = NULL;
return ret;
}
net_context_setup_pools(ctx->ipv4_ctx, ctx->tx_slab,
net_context_setup_pools(ctx->ipv4.ctx, ctx->tx_slab,
ctx->data_pool);
return ret;
@ -250,14 +266,14 @@ static int setup_ipv6_ctx(struct net_app_ctx *ctx,
{
int ret;
ret = net_context_get(AF_INET6, sock_type, proto, &ctx->ipv6_ctx);
ret = net_context_get(AF_INET6, sock_type, proto, &ctx->ipv6.ctx);
if (ret < 0) {
NET_ERR("Cannot get network context (%d)", ret);
ctx->ipv6_ctx = NULL;
ctx->ipv6.ctx = NULL;
return ret;
}
net_context_setup_pools(ctx->ipv6_ctx, ctx->tx_slab,
net_context_setup_pools(ctx->ipv6.ctx, ctx->tx_slab,
ctx->data_pool);
return ret;
@ -265,6 +281,15 @@ static int setup_ipv6_ctx(struct net_app_ctx *ctx,
#endif /* CONFIG_NET_IPV6 */
#if defined(CONFIG_NET_APP_SERVER) || defined(CONFIG_NET_APP_CLIENT)
static void select_default_ctx(struct net_app_ctx *ctx)
{
#if defined(CONFIG_NET_IPV6)
ctx->default_ctx = &ctx->ipv6;
#elif defined(CONFIG_NET_IPV4)
ctx->default_ctx = &ctx->ipv4;
#endif
}
int _net_app_config_local_ctx(struct net_app_ctx *ctx,
enum net_sock_type sock_type,
enum net_ip_protocol proto,
@ -272,31 +297,59 @@ int _net_app_config_local_ctx(struct net_app_ctx *ctx,
{
int ret;
if (addr->family == AF_INET6) {
if (!addr) {
#if defined(CONFIG_NET_IPV6)
ret = setup_ipv6_ctx(ctx, sock_type, proto);
#else
ret = -EPFNOSUPPORT;
goto fail;
if (ctx->ipv6.local.family == AF_INET6 ||
ctx->ipv6.local.family == AF_UNSPEC) {
ret = setup_ipv6_ctx(ctx, sock_type, proto);
} else {
ret = -EPFNOSUPPORT;
goto fail;
}
#endif
} else if (addr->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
ret = setup_ipv4_ctx(ctx, sock_type, proto);
#else
ret = -EPFNOSUPPORT;
goto fail;
#endif
} else if (addr->family == AF_UNSPEC) {
#if defined(CONFIG_NET_IPV4)
ret = setup_ipv4_ctx(ctx, sock_type, proto);
#endif
/* We ignore the IPv4 error if IPv6 is enabled */
#if defined(CONFIG_NET_IPV6)
ret = setup_ipv6_ctx(ctx, sock_type, proto);
if (ctx->ipv4.local.family == AF_INET ||
ctx->ipv4.local.family == AF_UNSPEC) {
ret = setup_ipv4_ctx(ctx, sock_type, proto);
} else {
ret = -EPFNOSUPPORT;
goto fail;
}
#endif
select_default_ctx(ctx);
} else {
ret = -EINVAL;
goto fail;
if (addr->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
ret = setup_ipv6_ctx(ctx, sock_type, proto);
ctx->default_ctx = &ctx->ipv6;
#else
ret = -EPFNOSUPPORT;
goto fail;
#endif
} else if (addr->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
ret = setup_ipv4_ctx(ctx, sock_type, proto);
ctx->default_ctx = &ctx->ipv4;
#else
ret = -EPFNOSUPPORT;
goto fail;
#endif
} else if (addr->family == AF_UNSPEC) {
#if defined(CONFIG_NET_IPV4)
ret = setup_ipv4_ctx(ctx, sock_type, proto);
ctx->default_ctx = &ctx->ipv4;
#endif
/* We ignore the IPv4 error if IPv6 is enabled */
#if defined(CONFIG_NET_IPV6)
ret = setup_ipv6_ctx(ctx, sock_type, proto);
ctx->default_ctx = &ctx->ipv6;
#endif
} else {
ret = -EINVAL;
goto fail;
}
}
fail:
@ -315,16 +368,16 @@ int net_app_release(struct net_app_ctx *ctx)
}
#if defined(CONFIG_NET_IPV6)
if (ctx->ipv6_ctx) {
net_context_put(ctx->ipv6_ctx);
ctx->ipv6_ctx = NULL;
if (ctx->ipv6.ctx) {
net_context_put(ctx->ipv6.ctx);
ctx->ipv6.ctx = NULL;
}
#endif /* CONFIG_NET_IPV6 */
#if defined(CONFIG_NET_IPV4)
if (ctx->ipv4_ctx) {
net_context_put(ctx->ipv4_ctx);
ctx->ipv4_ctx = NULL;
if (ctx->ipv4.ctx) {
net_context_put(ctx->ipv4.ctx);
ctx->ipv4.ctx = NULL;
}
#endif /* CONFIG_NET_IPV4 */
@ -333,18 +386,33 @@ int net_app_release(struct net_app_ctx *ctx)
return 0;
}
struct net_context *_net_app_select_net_ctx(struct net_app_ctx *ctx)
struct net_context *_net_app_select_net_ctx(struct net_app_ctx *ctx,
const struct sockaddr *dst)
{
#if defined(CONFIG_NET_APP_CLIENT)
if (ctx->app_type == NET_APP_CLIENT) {
if (ctx->remote.family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
return ctx->ipv6_ctx;
#endif
} else if (ctx->remote.family == AF_INET) {
if (!dst) {
return ctx->default_ctx->ctx;
} else {
if (dst->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
return ctx->ipv4_ctx;
return ctx->ipv4.ctx;
#else
return NULL;
#endif
}
if (dst->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
return ctx->ipv6.ctx;
#else
return NULL;
#endif
}
if (dst->family == AF_UNSPEC) {
return ctx->default_ctx->ctx;
}
}
}
#endif /* CONFIG_NET_APP_CLIENT */
@ -354,14 +422,24 @@ struct net_context *_net_app_select_net_ctx(struct net_app_ctx *ctx)
if (ctx->proto == IPPROTO_TCP) {
return ctx->server.net_ctx;
} else if (ctx->proto == IPPROTO_UDP) {
if (ctx->local.family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
return ctx->ipv6_ctx;
#endif
} else if (ctx->local.family == AF_INET) {
if (!dst) {
return ctx->default_ctx->ctx;
} else {
if (dst->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
return ctx->ipv4_ctx;
return ctx->ipv4.ctx;
#else
return NULL;
#endif
}
if (dst->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
return ctx->ipv6.ctx;
#else
return NULL;
#endif
}
}
}
}
@ -434,12 +512,24 @@ int net_app_send_pkt(struct net_app_ctx *ctx,
net_pkt_set_appdatalen(pkt, net_buf_frags_len(pkt->frags));
if (!dst && ctx->proto == IPPROTO_UDP) {
dst = &ctx->remote;
if (ctx->remote.family == AF_INET) {
if (net_pkt_family(pkt) == AF_INET) {
#if defined(CONFIG_NET_IPV4)
dst = &ctx->ipv4.remote;
dst_len = sizeof(struct sockaddr_in);
#else
return -EPFNOSUPPORT;
#endif
} else {
dst_len = sizeof(struct sockaddr_in6);
if (net_pkt_family(pkt) == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
dst = &ctx->ipv6.remote;
dst_len = sizeof(struct sockaddr_in6);
#else
return -EPFNOSUPPORT;
#endif
} else {
return -EPFNOSUPPORT;
}
}
}
@ -478,7 +568,7 @@ int net_app_send_buf(struct net_app_ctx *ctx,
return -EMSGSIZE;
}
net_ctx = _net_app_select_net_ctx(ctx);
net_ctx = _net_app_select_net_ctx(ctx, dst);
if (!net_ctx) {
return -ENOENT;
}
@ -523,9 +613,11 @@ send:
}
struct net_pkt *net_app_get_net_pkt(struct net_app_ctx *ctx,
sa_family_t family,
s32_t timeout)
{
struct net_context *net_ctx;
struct sockaddr dst;
if (!ctx) {
return NULL;
@ -535,7 +627,9 @@ struct net_pkt *net_app_get_net_pkt(struct net_app_ctx *ctx,
return NULL;
}
net_ctx = _net_app_select_net_ctx(ctx);
dst.family = family;
net_ctx = _net_app_select_net_ctx(ctx, &dst);
if (!net_ctx) {
return NULL;
}
@ -570,7 +664,7 @@ int net_app_close(struct net_app_ctx *ctx)
return -ENOENT;
}
net_ctx = _net_app_select_net_ctx(ctx);
net_ctx = _net_app_select_net_ctx(ctx, NULL);
if (!net_ctx) {
return -EAFNOSUPPORT;
}
@ -633,7 +727,7 @@ int _net_app_ssl_tx(void *context, const unsigned char *buf, size_t size)
struct net_pkt *send_buf;
int ret, len;
send_buf = net_app_get_net_pkt(ctx, BUF_ALLOC_TIMEOUT);
send_buf = net_app_get_net_pkt(ctx, AF_UNSPEC, BUF_ALLOC_TIMEOUT);
if (!send_buf) {
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
@ -950,23 +1044,6 @@ int _net_app_entropy_source(void *data, unsigned char *output, size_t len,
return 0;
}
#if defined(CONFIG_NET_DEBUG_APP)
void _net_app_print_info(struct net_app_ctx *ctx)
{
#define PORT_STR_LEN sizeof("[]:xxxxx")
char local[NET_IPV6_ADDR_LEN + PORT_STR_LEN];
char remote[NET_IPV6_ADDR_LEN + PORT_STR_LEN];
_net_app_sprint_ipaddr(local, sizeof(local), &ctx->local);
_net_app_sprint_ipaddr(remote, sizeof(remote), &ctx->remote);
NET_DBG("net app connect %s %s %s",
local,
ctx->app_type == NET_APP_CLIENT ? "->" : "<-",
remote);
}
#endif
int _net_app_ssl_mainloop(struct net_app_ctx *ctx)
{
size_t len;
@ -1043,7 +1120,7 @@ reset:
struct net_pkt *pkt;
int len = ret;
pkt = net_pkt_get_rx(_net_app_select_net_ctx(ctx),
pkt = net_pkt_get_rx(_net_app_select_net_ctx(ctx, NULL),
BUF_ALLOC_TIMEOUT);
if (!pkt) {
ret = -ENOMEM;

View file

@ -77,7 +77,8 @@ int _net_app_config_local_ctx(struct net_app_ctx *ctx,
enum net_sock_type sock_type,
enum net_ip_protocol proto,
struct sockaddr *addr);
struct net_context *_net_app_select_net_ctx(struct net_app_ctx *ctx);
struct net_context *_net_app_select_net_ctx(struct net_app_ctx *ctx,
const struct sockaddr *dst);
int _net_app_ssl_mux(void *context, unsigned char *buf, size_t size);
int _net_app_tls_sendto(struct net_pkt *pkt,
const struct sockaddr *dst_addr,

View file

@ -106,37 +106,37 @@ int net_app_listen(struct net_app_ctx *ctx)
}
#if defined(CONFIG_NET_IPV4)
if (ctx->local.family == AF_UNSPEC) {
ctx->local.family = AF_INET;
if (ctx->ipv4.local.family == AF_UNSPEC) {
ctx->ipv4.local.family = AF_INET;
dual = true;
_net_app_set_local_addr(&ctx->local, NULL,
net_sin(&ctx->local)->sin_port);
_net_app_set_local_addr(&ctx->ipv4.local, NULL,
net_sin(&ctx->ipv4.local)->sin_port);
}
ret = _net_app_set_net_ctx(ctx, ctx->ipv4_ctx, &ctx->local,
ret = _net_app_set_net_ctx(ctx, ctx->ipv4.ctx, &ctx->ipv4.local,
sizeof(struct sockaddr_in), ctx->proto);
if (ret < 0) {
net_context_put(ctx->ipv4_ctx);
ctx->ipv4_ctx = NULL;
net_context_put(ctx->ipv4.ctx);
ctx->ipv4.ctx = NULL;
}
#endif
/* We ignore the IPv4 error if IPv6 is enabled */
#if defined(CONFIG_NET_IPV6)
if (ctx->local.family == AF_UNSPEC || dual) {
ctx->local.family = AF_INET6;
if (ctx->ipv6.local.family == AF_UNSPEC || dual) {
ctx->ipv6.local.family = AF_INET6;
_net_app_set_local_addr(&ctx->local, NULL,
net_sin6(&ctx->local)->sin6_port);
_net_app_set_local_addr(&ctx->ipv6.local, NULL,
net_sin6(&ctx->ipv6.local)->sin6_port);
}
ret = _net_app_set_net_ctx(ctx, ctx->ipv6_ctx, &ctx->local,
ret = _net_app_set_net_ctx(ctx, ctx->ipv6.ctx, &ctx->ipv6.local,
sizeof(struct sockaddr_in6), ctx->proto);
if (ret < 0) {
net_context_put(ctx->ipv6_ctx);
ctx->ipv6_ctx = NULL;
net_context_put(ctx->ipv6.ctx);
ctx->ipv6.ctx = NULL;
}
#endif
@ -160,19 +160,44 @@ int net_app_init_server(struct net_app_ctx *ctx,
return -EALREADY;
}
memset(&ctx->local, 0, sizeof(ctx->local));
#if defined(CONFIG_NET_IPV4)
memset(&ctx->ipv4.local, 0, sizeof(ctx->ipv4.local));
#endif
#if defined(CONFIG_NET_IPV6)
memset(&ctx->ipv6.local, 0, sizeof(ctx->ipv6.local));
#endif
if (server_addr) {
memcpy(&ctx->local, server_addr,
sizeof(ctx->local));
} else {
ctx->local.family = AF_UNSPEC;
if (server_addr->family == AF_INET) {
#if defined(CONFIG_NET_IPV4)
memcpy(&ctx->ipv4.local, server_addr,
sizeof(ctx->ipv4.local));
#else
return -EPROTONOSUPPORT;
#endif
}
if (server_addr->family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
memcpy(&ctx->ipv6.local, server_addr,
sizeof(ctx->ipv6.local));
#else
return -EPROTONOSUPPORT;
#endif
}
} else {
if (port == 0) {
return -EINVAL;
}
net_sin(&ctx->local)->sin_port = htons(port);
#if defined(CONFIG_NET_IPV4)
ctx->ipv4.local.family = AF_INET;
net_sin(&ctx->ipv4.local)->sin_port = htons(port);
#endif
#if defined(CONFIG_NET_IPV6)
ctx->ipv6.local.family = AF_INET6;
net_sin6(&ctx->ipv6.local)->sin6_port = htons(port);
#endif
}
ctx->app_type = NET_APP_SERVER;
@ -182,12 +207,13 @@ int net_app_init_server(struct net_app_ctx *ctx,
ctx->proto = proto;
ctx->sock_type = sock_type;
ret = _net_app_config_local_ctx(ctx, sock_type, proto,
&ctx->local);
ret = _net_app_config_local_ctx(ctx, sock_type, proto, NULL);
if (ret < 0) {
goto fail;
}
NET_ASSERT_INFO(ctx->default_ctx, "Default ctx not selected");
ctx->is_init = true;
fail:
@ -196,8 +222,7 @@ fail:
#if defined(CONFIG_NET_APP_TLS)
static inline void new_server(struct net_app_ctx *ctx,
const char *server_banner,
const struct sockaddr *addr)
const char *server_banner)
{
#if defined(CONFIG_NET_DEBUG_APP) && (CONFIG_SYS_LOG_NET_LEVEL > 2)
#if defined(CONFIG_NET_IPV6)
@ -208,12 +233,17 @@ static inline void new_server(struct net_app_ctx *ctx,
char buf[NET_IPV4_ADDR_LEN + PORT_STR];
#endif
if (addr) {
NET_INFO("%s %s (%p)", server_banner,
_net_app_sprint_ipaddr(buf, sizeof(buf), addr), ctx);
} else {
NET_INFO("%s (%p)", server_banner, ctx);
}
#if defined(CONFIG_NET_IPV6)
NET_INFO("%s %s (%p)", server_banner,
_net_app_sprint_ipaddr(buf, sizeof(buf), &ctx->ipv6.local),
ctx);
#endif
#if defined(CONFIG_NET_IPV4)
NET_INFO("%s %s (%p)", server_banner,
_net_app_sprint_ipaddr(buf, sizeof(buf), &ctx->ipv4.local),
ctx);
#endif
#endif /* CONFIG_NET_DEBUG_APP */
}
@ -335,7 +365,7 @@ int net_app_server_tls(struct net_app_ctx *ctx,
}
if (server_banner) {
new_server(ctx, server_banner, &ctx->local);
new_server(ctx, server_banner);
}
ctx->tls.request_buf = request_buf;