blob: c0b289dd8f6671cb65a435f2954414547b22dc67 [file] [log] [blame]
/*
* Copyright (c) 2017 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <logging/log.h>
LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
#include <stdio.h>
#include <ztest_assert.h>
#include <net/socket.h>
#include "../../socket_helpers.h"
#define BUF_AND_SIZE(buf) buf, sizeof(buf) - 1
#define STRLEN(buf) (sizeof(buf) - 1)
#define TEST_STR_SMALL "test"
/* More than 256 bytes, to use >1 net_buf. */
#define TEST_STR2 \
"The Zephyr Project, a Linux Foundation hosted Collaboration " \
"Project, is an open source collaborative effort uniting leaders " \
"from across the industry to build a best-in-breed small, scalable, " \
"real-time operating system (RTOS) optimized for resource-" \
"constrained devices, across multiple architectures."
#define ANY_PORT 0
#define SERVER_PORT 4242
#define CLIENT_PORT 9898
/* Common routine to communicate packets over pair of sockets. */
static void comm_sendto_recvfrom(int client_sock,
struct sockaddr *client_addr,
socklen_t client_addrlen,
int server_sock,
struct sockaddr *server_addr,
socklen_t server_addrlen)
{
ssize_t sent = 0;
ssize_t recved = 0;
struct sockaddr addr;
socklen_t addrlen;
struct sockaddr addr2;
socklen_t addrlen2;
static char rx_buf[400] = {0};
zassert_not_null(client_addr, "null client addr");
zassert_not_null(server_addr, "null server addr");
/*
* Test client -> server sending
*/
sent = sendto(client_sock, TEST_STR_SMALL, strlen(TEST_STR_SMALL),
0, server_addr, server_addrlen);
zassert_equal(sent, strlen(TEST_STR_SMALL), "sendto failed");
/* Test recvfrom(MSG_PEEK) */
addrlen = sizeof(addr);
clear_buf(rx_buf);
recved = recvfrom(server_sock, rx_buf, sizeof(rx_buf),
MSG_PEEK, &addr, &addrlen);
zassert_true(recved >= 0, "recvfrom fail");
zassert_equal(recved, strlen(TEST_STR_SMALL),
"unexpected received bytes");
zassert_mem_equal(rx_buf, BUF_AND_SIZE(TEST_STR_SMALL), "wrong data");
zassert_equal(addrlen, client_addrlen, "unexpected addrlen");
/* Test normal recvfrom() */
addrlen = sizeof(addr);
clear_buf(rx_buf);
recved = recvfrom(server_sock, rx_buf, sizeof(rx_buf),
0, &addr, &addrlen);
zassert_true(recved >= 0, "recvfrom fail");
zassert_equal(recved, strlen(TEST_STR_SMALL),
"unexpected received bytes");
zassert_mem_equal(rx_buf, BUF_AND_SIZE(TEST_STR_SMALL), "wrong data");
zassert_equal(addrlen, client_addrlen, "unexpected addrlen");
/* Check the client port */
if (net_sin(client_addr)->sin_port != ANY_PORT) {
zassert_equal(net_sin(client_addr)->sin_port,
net_sin(&addr)->sin_port,
"unexpected client port");
}
/*
* Test server -> client sending
*/
sent = sendto(server_sock, BUF_AND_SIZE(TEST_STR2),
0, &addr, addrlen);
zassert_equal(sent, STRLEN(TEST_STR2), "sendto failed");
/* Test normal recvfrom() */
addrlen2 = sizeof(addr);
clear_buf(rx_buf);
recved = recvfrom(client_sock, rx_buf, sizeof(rx_buf),
0, &addr2, &addrlen2);
zassert_true(recved >= 0, "recvfrom fail");
zassert_equal(recved, STRLEN(TEST_STR2),
"unexpected received bytes");
zassert_mem_equal(rx_buf, BUF_AND_SIZE(TEST_STR2), "wrong data");
zassert_equal(addrlen2, server_addrlen, "unexpected addrlen");
/* Check the server port */
zassert_equal(net_sin(server_addr)->sin_port,
net_sin(&addr2)->sin_port,
"unexpected server port");
/* Test that unleft leftover data from datagram is discarded. */
/* Send 2 datagrams */
sent = sendto(server_sock, BUF_AND_SIZE(TEST_STR2),
0, &addr, addrlen);
zassert_equal(sent, STRLEN(TEST_STR2), "sendto failed");
sent = sendto(server_sock, BUF_AND_SIZE(TEST_STR_SMALL),
0, &addr, addrlen);
zassert_equal(sent, STRLEN(TEST_STR_SMALL), "sendto failed");
/* Receive just beginning of 1st datagram */
addrlen2 = sizeof(addr);
clear_buf(rx_buf);
recved = recvfrom(client_sock, rx_buf, 16, 0, &addr2, &addrlen2);
zassert_true(recved == 16, "recvfrom fail");
zassert_mem_equal(rx_buf, TEST_STR2, 16, "wrong data");
/* Make sure that now we receive 2nd datagram */
addrlen2 = sizeof(addr);
clear_buf(rx_buf);
recved = recvfrom(client_sock, rx_buf, 16, 0, &addr2, &addrlen2);
zassert_true(recved == STRLEN(TEST_STR_SMALL), "recvfrom fail");
zassert_mem_equal(rx_buf, BUF_AND_SIZE(TEST_STR_SMALL), "wrong data");
}
void test_v4_sendto_recvfrom(void)
{
int rv;
int client_sock;
int server_sock;
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
prepare_sock_udp_v4(CONFIG_NET_CONFIG_MY_IPV4_ADDR, ANY_PORT,
&client_sock, &client_addr);
prepare_sock_udp_v4(CONFIG_NET_CONFIG_MY_IPV4_ADDR, SERVER_PORT,
&server_sock, &server_addr);
rv = bind(server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
zassert_equal(rv, 0, "bind failed");
comm_sendto_recvfrom(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr),
server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
rv = close(client_sock);
zassert_equal(rv, 0, "close failed");
rv = close(server_sock);
zassert_equal(rv, 0, "close failed");
}
void test_v6_sendto_recvfrom(void)
{
int rv;
int client_sock;
int server_sock;
struct sockaddr_in6 client_addr;
struct sockaddr_in6 server_addr;
prepare_sock_udp_v6(CONFIG_NET_CONFIG_MY_IPV6_ADDR, ANY_PORT,
&client_sock, &client_addr);
prepare_sock_udp_v6(CONFIG_NET_CONFIG_MY_IPV6_ADDR, SERVER_PORT,
&server_sock, &server_addr);
rv = bind(server_sock,
(struct sockaddr *)&server_addr, sizeof(server_addr));
zassert_equal(rv, 0, "bind failed");
comm_sendto_recvfrom(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr),
server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
rv = close(client_sock);
zassert_equal(rv, 0, "close failed");
rv = close(server_sock);
zassert_equal(rv, 0, "close failed");
}
void test_v4_bind_sendto(void)
{
int rv;
int client_sock;
int server_sock;
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
prepare_sock_udp_v4(CONFIG_NET_CONFIG_MY_IPV4_ADDR, CLIENT_PORT,
&client_sock, &client_addr);
prepare_sock_udp_v4(CONFIG_NET_CONFIG_MY_IPV4_ADDR, SERVER_PORT,
&server_sock, &server_addr);
rv = bind(client_sock,
(struct sockaddr *)&client_addr, sizeof(client_addr));
zassert_equal(rv, 0, "bind failed");
rv = bind(server_sock,
(struct sockaddr *)&server_addr, sizeof(server_addr));
zassert_equal(rv, 0, "bind failed");
comm_sendto_recvfrom(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr),
server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
rv = close(client_sock);
zassert_equal(rv, 0, "close failed");
rv = close(server_sock);
zassert_equal(rv, 0, "close failed");
}
void test_v6_bind_sendto(void)
{
int rv;
int client_sock;
int server_sock;
struct sockaddr_in6 client_addr;
struct sockaddr_in6 server_addr;
prepare_sock_udp_v6(CONFIG_NET_CONFIG_MY_IPV6_ADDR, CLIENT_PORT,
&client_sock, &client_addr);
prepare_sock_udp_v6(CONFIG_NET_CONFIG_MY_IPV6_ADDR, SERVER_PORT,
&server_sock, &server_addr);
rv = bind(client_sock,
(struct sockaddr *)&client_addr, sizeof(client_addr));
zassert_equal(rv, 0, "bind failed");
rv = bind(server_sock,
(struct sockaddr *)&server_addr, sizeof(server_addr));
zassert_equal(rv, 0, "bind failed");
comm_sendto_recvfrom(client_sock,
(struct sockaddr *)&client_addr,
sizeof(client_addr),
server_sock,
(struct sockaddr *)&server_addr,
sizeof(server_addr));
rv = close(client_sock);
zassert_equal(rv, 0, "close failed");
rv = close(server_sock);
zassert_equal(rv, 0, "close failed");
}
void test_send_recv_2_sock(void)
{
int sock1, sock2;
struct sockaddr_in bind_addr, conn_addr;
char buf[10];
int len, rv;
prepare_sock_udp_v4(CONFIG_NET_CONFIG_MY_IPV4_ADDR, 55555,
&sock1, &bind_addr);
prepare_sock_udp_v4(CONFIG_NET_CONFIG_MY_IPV4_ADDR, 55555,
&sock2, &conn_addr);
rv = bind(sock1, (struct sockaddr *)&bind_addr, sizeof(bind_addr));
zassert_equal(rv, 0, "bind failed");
rv = connect(sock2, (struct sockaddr *)&conn_addr, sizeof(conn_addr));
zassert_equal(rv, 0, "connect failed");
len = send(sock2, BUF_AND_SIZE(TEST_STR_SMALL), 0);
zassert_equal(len, STRLEN(TEST_STR_SMALL), "invalid send len");
clear_buf(buf);
len = recv(sock1, buf, sizeof(buf), MSG_PEEK);
zassert_equal(len, STRLEN(TEST_STR_SMALL), "Invalid recv len");
zassert_mem_equal(buf, BUF_AND_SIZE(TEST_STR_SMALL), "Wrong data");
clear_buf(buf);
len = recv(sock1, buf, sizeof(buf), 0);
zassert_equal(len, STRLEN(TEST_STR_SMALL), "Invalid recv len");
zassert_mem_equal(buf, BUF_AND_SIZE(TEST_STR_SMALL), "Wrong data");
rv = close(sock1);
zassert_equal(rv, 0, "close failed");
rv = close(sock2);
zassert_equal(rv, 0, "close failed");
}
void test_main(void)
{
ztest_test_suite(socket_udp,
ztest_unit_test(test_send_recv_2_sock),
ztest_unit_test(test_v4_sendto_recvfrom),
ztest_unit_test(test_v6_sendto_recvfrom),
ztest_unit_test(test_v4_bind_sendto),
ztest_unit_test(test_v6_bind_sendto));
ztest_run_test_suite(socket_udp);
}