Ejemplo n.º 1
0
static inline bool get_context(struct net_context **udp_recv6,
			       struct net_context **tcp_recv6,
			       struct net_context **mcast_recv6)
{
	int ret;
	struct sockaddr_in6 mcast_addr6 = { 0 };
	struct sockaddr_in6 my_addr6 = { 0 };

	net_ipaddr_copy(&mcast_addr6.sin6_addr, &in6addr_mcast);
	mcast_addr6.sin6_family = AF_INET6;

	my_addr6.sin6_family = AF_INET6;
	my_addr6.sin6_port = htons(MY_PORT);

	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, udp_recv6);
	if (ret < 0) {
		printk("Cannot get network context for IPv6 UDP (%d)",
			ret);
		return false;
	}

	ret = net_context_bind(*udp_recv6, (struct sockaddr *)&my_addr6,
			       sizeof(struct sockaddr_in6));
	if (ret < 0) {
		printk("Cannot bind IPv6 UDP port %d (%d)",
			ntohs(my_addr6.sin6_port), ret);
		return false;
	}

	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, mcast_recv6);
	if (ret < 0) {
		printk("Cannot get receiving IPv6 mcast "
			"network context (%d)", ret);
		return false;
	}

	ret = net_context_bind(*mcast_recv6, (struct sockaddr *)&mcast_addr6,
			       sizeof(struct sockaddr_in6));
	if (ret < 0) {
		printk("Cannot bind IPv6 mcast (%d)", ret);
		return false;
	}

	ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP, tcp_recv6);
	if (ret < 0) {
		printk("Cannot get network context for IPv6 TCP (%d)", ret);
		return false;
	}

	net_context_setup_pools(*tcp_recv6, tx_tcp_pool, data_tcp_pool);

	ret = net_context_bind(*tcp_recv6, (struct sockaddr *)&my_addr6,
			       sizeof(struct sockaddr_in6));
	if (ret < 0) {
		printk("Cannot bind IPv6 TCP port %d (%d)",
			ntohs(my_addr6.sin6_port), ret);
		return false;
	}

	ret = net_context_listen(*tcp_recv6, 0);
	if (ret < 0) {
		printk("Cannot listen IPv6 TCP (%d)", ret);
		return false;
	}

	return true;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
static inline bool get_context(struct net_context **udp_recv4,
			       struct net_context **udp_recv6,
			       struct net_context **tcp_recv4,
			       struct net_context **tcp_recv6)
{
	int ret;

#if defined(CONFIG_NET_IPV6)
	struct sockaddr_in6 my_addr6 = { 0 };
#endif

#if defined(CONFIG_NET_IPV4)
	struct sockaddr_in my_addr4 = { 0 };
#endif

#if defined(CONFIG_NET_IPV6)
#if !NET_BIND_ANY_ADDR
	net_ipaddr_copy(&my_addr6.sin6_addr, &in6addr_my);
#endif

	my_addr6.sin6_family = AF_INET6;
	my_addr6.sin6_port = htons(MY_PORT);
#endif

#if defined(CONFIG_NET_IPV4)
#if !NET_BIND_ANY_ADDR
	net_ipaddr_copy(&my_addr4.sin_addr, &in4addr_my);
#endif

	my_addr4.sin_family = AF_INET;
	my_addr4.sin_port = htons(MY_PORT);
#endif

#if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_UDP)
	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, udp_recv6);
	if (ret < 0) {
		NET_ERR("Cannot get network context for IPv6 UDP (%d)",
			ret);
		return false;
	}

	net_context_setup_pools(*udp_recv6, tx_udp_slab, data_udp_pool);

	ret = net_context_bind(*udp_recv6, (struct sockaddr *)&my_addr6,
			       sizeof(struct sockaddr_in6));
	if (ret < 0) {
		NET_ERR("Cannot bind IPv6 UDP port %d (%d)",
			ntohs(my_addr6.sin6_port), ret);
		return false;
	}
#endif

#if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_UDP)
	ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, udp_recv4);
	if (ret < 0) {
		NET_ERR("Cannot get network context for IPv4 UDP (%d)",
			ret);
		return false;
	}

	net_context_setup_pools(*udp_recv4, tx_udp_slab, data_udp_pool);

	ret = net_context_bind(*udp_recv4, (struct sockaddr *)&my_addr4,
			       sizeof(struct sockaddr_in));
	if (ret < 0) {
		NET_ERR("Cannot bind IPv4 UDP port %d (%d)",
			ntohs(my_addr4.sin_port), ret);
		return false;
	}
#endif

#if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_TCP)
	if (tcp_recv6) {
		ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP,
				      tcp_recv6);
		if (ret < 0) {
			NET_ERR("Cannot get network context "
				"for IPv6 TCP (%d)", ret);
			return false;
		}

		net_context_setup_pools(*tcp_recv6, tx_tcp_slab, data_tcp_pool);

		ret = net_context_bind(*tcp_recv6,
				       (struct sockaddr *)&my_addr6,
				       sizeof(struct sockaddr_in6));
		if (ret < 0) {
			NET_ERR("Cannot bind IPv6 TCP port %d (%d)",
				ntohs(my_addr6.sin6_port), ret);
			return false;
		}

		ret = net_context_listen(*tcp_recv6, 0);
		if (ret < 0) {
			NET_ERR("Cannot listen IPv6 TCP (%d)", ret);
			return false;
		}
	}
#endif

#if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_TCP)
	if (tcp_recv4) {
		ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP,
				      tcp_recv4);
		if (ret < 0) {
			NET_ERR("Cannot get network context for IPv4 TCP");
			return false;
		}

		net_context_setup_pools(*tcp_recv4, tx_tcp_slab, data_tcp_pool);

		ret = net_context_bind(*tcp_recv4,
				       (struct sockaddr *)&my_addr4,
				       sizeof(struct sockaddr_in));
		if (ret < 0) {
			NET_ERR("Cannot bind IPv4 TCP port %d",
				ntohs(my_addr4.sin_port));
			return false;
		}

		ret = net_context_listen(*tcp_recv4, 0);
		if (ret < 0) {
			NET_ERR("Cannot listen IPv4 TCP");
			return false;
		}
	}
#endif

	return true;
}