From ec044c706c7a1c324f33be2c42fa9f79a3f2cb91 Mon Sep 17 00:00:00 2001 From: Ravi kumar Veeramally Date: Thu, 8 Feb 2018 14:13:32 +0200 Subject: [PATCH 1/2] net: app: Fix get_server_ctx helper function When net_app_ctx has multiple net_contexts, selecting net_context based on dst address has some glitches. E.g. One net_app_ctx and two net_contexts (net_ctx1, net_ctx2). Both net_contexts are mapped to net_app_ctx. When a caller looking for net_ctx (e.g. net_ctx2) with matching dst address. Loop goes through net_ctx1 and dst doesn't match. But another if condition checks does this net_context mapped to net_app_ctx, yes it matches. So return net_ctx1, which is wrong. So first go through all elements in array of net_contexts for matching dst address, if it fails to find then go for matching net_app_ctx. Signed-off-by: Ravi kumar Veeramally --- subsys/net/lib/app/net_app.c | 60 +++++++++++++++++------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/subsys/net/lib/app/net_app.c b/subsys/net/lib/app/net_app.c index 3fa0327a3ffcd..c5f12c4bb12c4 100644 --- a/subsys/net/lib/app/net_app.c +++ b/subsys/net/lib/app/net_app.c @@ -562,27 +562,45 @@ struct net_context *select_client_ctx(struct net_app_ctx *ctx, #if defined(CONFIG_NET_APP_SERVER) #if defined(CONFIG_NET_TCP) -static struct net_context *get_server_ctx(struct net_app_ctx *ctx, - const struct sockaddr *dst) + +static struct net_context *get_server_ctx_without_dst(struct net_app_ctx *ctx) { int i; for (i = 0; i < CONFIG_NET_APP_SERVER_NUM_CONN; i++) { struct net_context *tmp = ctx->server.net_ctxs[i]; - u16_t port, rport; if (!tmp || !net_context_is_used(tmp)) { continue; } - if (!dst) { - if (tmp->net_app == ctx) { - NET_DBG("Selecting net_ctx %p iface %p for " - "NULL dst", - tmp, net_context_get_iface(tmp)); - return tmp; - } + if (tmp->net_app != ctx) { + continue; + } + NET_DBG("Selecting net_ctx %p iface %p for NULL dst", + tmp, net_context_get_iface(tmp)); + + return tmp; + } + + return NULL; +} + +static struct net_context *get_server_ctx(struct net_app_ctx *ctx, + const struct sockaddr *dst) +{ + int i; + + if (!dst) { + return get_server_ctx_without_dst(ctx); + } + + for (i = 0; i < CONFIG_NET_APP_SERVER_NUM_CONN; i++) { + struct net_context *tmp = ctx->server.net_ctxs[i]; + u16_t port, rport; + + if (!tmp || !net_context_is_used(tmp)) { continue; } @@ -606,16 +624,6 @@ static struct net_context *get_server_ctx(struct net_app_ctx *ctx, ntohs(rport)); return tmp; } - - if (tmp->net_app == ctx) { - NET_DBG("Selecting net_ctx %p iface %p" - " for %s port %d", tmp, - net_context_get_iface(tmp), - dst->sa_family == AF_UNSPEC ? - "AF_UNSPEC" : "AF_INET6", - ntohs(rport)); - return tmp; - } } if (IS_ENABLED(CONFIG_NET_IPV4) && @@ -637,20 +645,10 @@ static struct net_context *get_server_ctx(struct net_app_ctx *ctx, ntohs(port)); return tmp; } - - if (tmp->net_app == ctx) { - NET_DBG("Selecting net_ctx %p iface %p" - " for %s port %d", tmp, - net_context_get_iface(tmp), - dst->sa_family == AF_UNSPEC ? - "AF_UNSPEC" : "AF_INET", - ntohs(port)); - return tmp; - } } } - return NULL; + return get_server_ctx_without_dst(ctx); } #endif /* CONFIG_NET_TCP */ From 04a63ce2f3d35bab323b3d0ac6cf0d745f4fac37 Mon Sep 17 00:00:00 2001 From: Ravi kumar Veeramally Date: Thu, 8 Feb 2018 14:35:23 +0200 Subject: [PATCH 2/2] net: app: Add a new API to get net pkt based on dst Added a new API to get net pkt based on dst address. Destination address will be used to find correct net_context. Signed-off-by: Ravi kumar Veeramally --- include/net/net_app.h | 13 +++++++++++++ subsys/net/lib/app/net_app.c | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/net/net_app.h b/include/net/net_app.h index 1ce62198043a4..2c12d72740760 100644 --- a/include/net/net_app.h +++ b/include/net/net_app.h @@ -855,6 +855,19 @@ struct net_pkt *net_app_get_net_pkt(struct net_app_ctx *ctx, sa_family_t family, s32_t timeout); +/** + * @brief Create network packet based on dst address. + * + * @param ctx Network application context. + * @param dst Destination address to select net_context + * @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_with_dst(struct net_app_ctx *ctx, + const struct sockaddr *dst, + s32_t timeout); + /** * @brief Create network buffer that will hold network data. * diff --git a/subsys/net/lib/app/net_app.c b/subsys/net/lib/app/net_app.c index c5f12c4bb12c4..fdcb5ac228a19 100644 --- a/subsys/net/lib/app/net_app.c +++ b/subsys/net/lib/app/net_app.c @@ -963,6 +963,28 @@ struct net_pkt *net_app_get_net_pkt(struct net_app_ctx *ctx, return net_pkt_get_tx(net_ctx, timeout); } +struct net_pkt *net_app_get_net_pkt_with_dst(struct net_app_ctx *ctx, + const struct sockaddr *dst, + s32_t timeout) +{ + struct net_context *net_ctx; + + if (!ctx || !dst) { + return NULL; + } + + if (!ctx->is_init) { + return NULL; + } + + net_ctx = _net_app_select_net_ctx(ctx, dst); + if (!net_ctx) { + return NULL; + } + + return net_pkt_get_tx(net_ctx, timeout); +} + struct net_buf *net_app_get_net_buf(struct net_app_ctx *ctx, struct net_pkt *pkt, s32_t timeout)