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:
parent
489ea9ba4f
commit
7a31d4b8cb
7 changed files with 296 additions and 152 deletions
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue