void http_accept_cb(struct net_context *net_ctx, struct sockaddr *addr, socklen_t addr_len, int status, void *data) { struct http_server_ctx *http_ctx = NULL; ARG_UNUSED(addr_len); ARG_UNUSED(data); if (status != 0) { net_context_put(net_ctx); return; } print_client_banner(addr); http_ctx = http_ctx_get(); if (!http_ctx) { net_context_put(net_ctx); return; } http_ctx_set(http_ctx, net_ctx); net_context_recv(net_ctx, http_rx_tx, K_NO_WAIT, http_ctx); }
static void tcp_disconnect(struct http_client_ctx *ctx) { if (ctx->tcp.ctx) { net_context_put(ctx->tcp.ctx); ctx->tcp.ctx = NULL; } }
static void telnet_accept(struct net_context *client, struct sockaddr *addr, socklen_t addrlen, int error, void *user_data) { if (error) { LOG_ERR("Error %d", error); goto error; } if (client_cnx) { LOG_WRN("A telnet client is already in."); goto error; } if (net_context_recv(client, telnet_recv, 0, NULL)) { LOG_ERR("Unable to setup reception (family %u)", net_context_get_family(client)); goto error; } LOG_DBG("Telnet client connected (family AF_INET%s)", net_context_get_family(client) == AF_INET ? "" : "6"); orig_printk_hook = __printk_get_hook(); __printk_hook_install(telnet_console_out); client_cnx = client; k_timer_start(&send_timer, TELNET_TIMEOUT, TELNET_TIMEOUT); return; error: net_context_put(client); }
int udp_init(struct udp_context *ctx) { struct net_context *udp_ctx = { 0 }; struct net_context *mcast_ctx = { 0 }; struct sockaddr_in6 my_addr = { 0 }; struct sockaddr_in6 my_mcast_addr = { 0 }; int rc; k_sem_init(&ctx->rx_sem, 0, UINT_MAX); net_ipaddr_copy(&my_mcast_addr.sin6_addr, &mcast_addr); my_mcast_addr.sin6_family = AF_INET6; net_ipaddr_copy(&my_addr.sin6_addr, &server_addr); my_addr.sin6_family = AF_INET6; my_addr.sin6_port = htons(SERVER_PORT); rc = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &udp_ctx); if (rc < 0) { printk("Cannot get network context for IPv6 UDP (%d)", rc); return -EIO; } rc = net_context_bind(udp_ctx, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in6)); if (rc < 0) { printk("Cannot bind IPv6 UDP port %d (%d)", SERVER_PORT, rc); goto error; } rc = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &mcast_ctx); if (rc < 0) { printk("Cannot get receiving IPv6 mcast (%d)", rc); goto error; } rc = net_context_bind(mcast_ctx, (struct sockaddr *)&my_mcast_addr, sizeof(struct sockaddr_in6)); if (rc < 0) { printk("Cannot get bind IPv6 mcast (%d)", rc); goto error; } ctx->rx_pkt = NULL; ctx->remaining = 0; ctx->net_ctx = udp_ctx; rc = net_context_recv(ctx->net_ctx, udp_received, K_NO_WAIT, ctx); if (rc != 0) { return -EIO; } return 0; error: net_context_put(udp_ctx); return -EINVAL; }
void receive(void) { struct net_context *udp_recv4 = { 0 }; struct net_context *udp_recv6 = { 0 }; struct net_context *tcp_recv4 = { 0 }; struct net_context *tcp_recv6 = { 0 }; if (!get_context(&udp_recv4, &udp_recv6, &tcp_recv4, &tcp_recv6)) { NET_ERR("Cannot get network contexts"); return; } NET_INFO("Starting to wait"); #if defined(CONFIG_NET_TCP) setup_tcp_accept(tcp_recv4, tcp_recv6); #endif #if defined(CONFIG_NET_UDP) setup_udp_recv(udp_recv4, udp_recv6); #endif k_sem_take(&quit_lock, K_FOREVER); NET_INFO("Stopping..."); #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_UDP) net_context_put(udp_recv6); #endif #if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_UDP) net_context_put(udp_recv4); #endif #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_TCP) net_context_put(tcp_recv6); #endif #if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_TCP) net_context_put(tcp_recv4); #endif }
static void telnet_end_client_connection(void) { __printk_hook_install(orig_printk_hook); orig_printk_hook = NULL; k_timer_stop(&send_timer); net_context_put(client_cnx); client_cnx = NULL; telnet_rb_init(); }
static void listen(void) { struct net_context *udp_recv6 = { 0 }; struct net_context *tcp_recv6 = { 0 }; struct net_context *mcast_recv6 = { 0 }; if (!get_context(&udp_recv6, &tcp_recv6, &mcast_recv6)) { printk("Cannot get network contexts"); return; } printk("Starting to wait"); setup_tcp_accept(tcp_recv6); setup_udp_recv(udp_recv6); k_sem_take(&quit_lock, K_FOREVER); printk("Stopping..."); net_context_put(udp_recv6); net_context_put(mcast_recv6); net_context_put(tcp_recv6); }
static bool get_local_address(struct sol_network_link_addr *addr) { struct net_context *empty_ctx; struct net_addr local_addr = { 0 }; empty_ctx = net_context_get(IPPROTO_UDP, NULL, 0, &local_addr, 0); SOL_NULL_CHECK(empty_ctx, false); addr->family = SOL_NETWORK_FAMILY_INET6; addr->port = 0; memcpy(&addr->addr.in6, &local_addr.in6_addr, sizeof(addr->addr.in6)); net_context_put(empty_ctx); return true; }
void http_client_release(struct http_client_ctx *ctx) { if (!ctx) { return; } #if defined(CONFIG_HTTPS) if (ctx->is_https) { https_shutdown(ctx); } #endif /* CONFIG_HTTPS */ /* https_shutdown() might have released the context already */ if (ctx->tcp.ctx) { net_context_put(ctx->tcp.ctx); ctx->tcp.ctx = NULL; } ctx->tcp.receive_cb = NULL; ctx->rsp.cb = NULL; k_sem_give(&ctx->req.wait); #if defined(CONFIG_DNS_RESOLVER) if (ctx->dns_id) { dns_cancel_addr_info(ctx->dns_id); } #endif /* Let all the pending waiters run */ k_yield(); /* Coverity tells in CID 170742 that the next memset() is * is overwriting the ctx struct. This is false positive as * the struct is initialized with proper size. */ memset(ctx, 0, sizeof(*ctx)); }
static void telnet_setup_server(struct net_context **ctx, sa_family_t family, struct sockaddr *addr, socklen_t addrlen) { if (net_context_get(family, SOCK_STREAM, IPPROTO_TCP, ctx)) { SYS_LOG_ERR("No context available"); goto error; } if (net_context_bind(*ctx, addr, addrlen)) { SYS_LOG_ERR("Cannot bind on family AF_INET%s", family == AF_INET ? "" : "6"); goto error; } if (net_context_listen(*ctx, 0)) { SYS_LOG_ERR("Cannot listen on"); goto error; } if (net_context_accept(*ctx, telnet_accept, 0, NULL)) { SYS_LOG_ERR("Cannot accept"); goto error; } SYS_LOG_DBG("Telnet console enabled on AF_INET%s", family == AF_INET ? "" : "6"); return; error: SYS_LOG_ERR("Unable to start telnet on AF_INET%s", family == AF_INET ? "" : "6"); if (*ctx) { net_context_put(*ctx); *ctx = NULL; } }
static int tcp_connect(struct http_client_ctx *ctx) { socklen_t addrlen = sizeof(struct sockaddr_in); int ret; if (ctx->tcp.ctx && net_context_is_used(ctx->tcp.ctx) && net_context_get_state(ctx->tcp.ctx) == NET_CONTEXT_CONNECTED) { /* If we are already connected, then just return */ return -EALREADY; } if (ctx->tcp.remote.family == AF_INET6) { addrlen = sizeof(struct sockaddr_in6); /* If we are reconnecting, then make sure the source port * is re-calculated so that the peer will not get confused * which connection the connection is related to. * This was seen in Linux which dropped packets when the same * source port was for a new connection after the old connection * was terminated. */ net_sin6(&ctx->tcp.local)->sin6_port = 0; } else { net_sin(&ctx->tcp.local)->sin_port = 0; } ret = get_local_addr(ctx); if (ret < 0) { NET_DBG("Cannot get local address (%d)", ret); return ret; } ret = net_context_get(ctx->tcp.remote.family, SOCK_STREAM, IPPROTO_TCP, &ctx->tcp.ctx); if (ret) { NET_DBG("Get context error (%d)", ret); return ret; } net_context_setup_pools(ctx->tcp.ctx, ctx->tx_slab, ctx->data_pool); ret = net_context_bind(ctx->tcp.ctx, &ctx->tcp.local, addrlen); if (ret) { NET_DBG("Bind error (%d)", ret); goto out; } ret = net_context_connect(ctx->tcp.ctx, &ctx->tcp.remote, addrlen, NULL, ctx->tcp.timeout, NULL); if (ret) { NET_DBG("Connect error (%d)", ret); goto out; } return net_context_recv(ctx->tcp.ctx, ctx->tcp.recv_cb, K_NO_WAIT, ctx); out: net_context_put(ctx->tcp.ctx); ctx->tcp.ctx = NULL; return ret; }