netutils/iperf: Split out sockaddr from general logic
We'll add local/rpmsg sockets later, they're mainly different in sockaddr, we can reuse other current logic. Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
e3e3cc28a6
commit
411c98acec
@ -77,6 +77,14 @@ struct iperf_udp_pkt_t
|
|||||||
uint32_t usec;
|
uint32_t usec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef CODE int (*iperf_client_func_t)(FAR struct iperf_ctrl_t *ctrl,
|
||||||
|
FAR struct sockaddr *addr,
|
||||||
|
socklen_t addrlen);
|
||||||
|
typedef CODE int (*iperf_server_func_t)(FAR struct iperf_ctrl_t *ctrl,
|
||||||
|
FAR struct sockaddr *addr,
|
||||||
|
socklen_t addrlen,
|
||||||
|
FAR struct sockaddr *remote_addr);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -196,6 +204,31 @@ static int iperf_show_socket_error_reason(FAR const char *str, int sockfd)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: iperf_print_addr
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Print addr info
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void iperf_print_addr(FAR const char *str, FAR struct sockaddr *addr)
|
||||||
|
{
|
||||||
|
switch (addr->sa_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
FAR struct sockaddr_in *inaddr = (FAR struct sockaddr_in *)addr;
|
||||||
|
printf("%s: %s:%d\n", str,
|
||||||
|
inet_ntoa(inaddr->sin_addr), htons(inaddr->sin_port));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false); /* shouldn't happen */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ts_sec
|
* Name: ts_sec
|
||||||
*
|
*
|
||||||
@ -332,18 +365,59 @@ static int iperf_start_report(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: iperf_run_tcp_server
|
* Name: iperf_run_server
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Start tcp server
|
* Start a server
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int iperf_run_tcp_server(FAR struct iperf_ctrl_t *ctrl)
|
static int iperf_run_server(FAR struct iperf_ctrl_t *ctrl,
|
||||||
|
iperf_server_func_t server_func)
|
||||||
{
|
{
|
||||||
socklen_t addr_len = sizeof(struct sockaddr);
|
|
||||||
struct sockaddr_in remote_addr;
|
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
struct sockaddr_in remote_addr;
|
||||||
|
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(ctrl->cfg.sport);
|
||||||
|
addr.sin_addr.s_addr = ctrl->cfg.sip;
|
||||||
|
|
||||||
|
return server_func(ctrl, (FAR struct sockaddr *)&addr, sizeof(addr),
|
||||||
|
(FAR struct sockaddr *)&remote_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: iperf_run_client
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Start a client
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int iperf_run_client(FAR struct iperf_ctrl_t *ctrl,
|
||||||
|
iperf_client_func_t client_func)
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(ctrl->cfg.dport);
|
||||||
|
addr.sin_addr.s_addr = ctrl->cfg.dip;
|
||||||
|
|
||||||
|
return client_func(ctrl, (FAR struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: iperf_tcp_server
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The main tcp server logic
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int iperf_tcp_server(FAR struct iperf_ctrl_t *ctrl,
|
||||||
|
FAR struct sockaddr *addr, socklen_t addrlen,
|
||||||
|
FAR struct sockaddr *remote_addr)
|
||||||
|
{
|
||||||
int actual_recv = 0;
|
int actual_recv = 0;
|
||||||
int want_recv = 0;
|
int want_recv = 0;
|
||||||
FAR uint8_t *buffer;
|
FAR uint8_t *buffer;
|
||||||
@ -352,7 +426,7 @@ static int iperf_run_tcp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
int sockfd;
|
int sockfd;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
listen_socket = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (listen_socket < 0)
|
if (listen_socket < 0)
|
||||||
{
|
{
|
||||||
iperf_show_socket_error_reason("tcp server create", listen_socket);
|
iperf_show_socket_error_reason("tcp server create", listen_socket);
|
||||||
@ -360,10 +434,7 @@ static int iperf_run_tcp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||||
addr.sin_family = AF_INET;
|
if (bind(listen_socket, addr, addrlen) != 0)
|
||||||
addr.sin_port = htons(ctrl->cfg.sport);
|
|
||||||
addr.sin_addr.s_addr = ctrl->cfg.sip;
|
|
||||||
if (bind(listen_socket, (FAR struct sockaddr *)&addr, sizeof(addr)) != 0)
|
|
||||||
{
|
{
|
||||||
iperf_show_socket_error_reason("tcp server bind", listen_socket);
|
iperf_show_socket_error_reason("tcp server bind", listen_socket);
|
||||||
close(listen_socket);
|
close(listen_socket);
|
||||||
@ -383,8 +454,7 @@ static int iperf_run_tcp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
{
|
{
|
||||||
/* TODO need to change to non-block mode */
|
/* TODO need to change to non-block mode */
|
||||||
|
|
||||||
sockfd = accept(listen_socket, (FAR struct sockaddr *)&remote_addr,
|
sockfd = accept(listen_socket, remote_addr, &addrlen);
|
||||||
&addr_len);
|
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
{
|
{
|
||||||
iperf_show_socket_error_reason("tcp server listen", listen_socket);
|
iperf_show_socket_error_reason("tcp server listen", listen_socket);
|
||||||
@ -393,12 +463,7 @@ static int iperf_run_tcp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char inetaddr[INET_ADDRSTRLEN];
|
iperf_print_addr("accept", remote_addr);
|
||||||
|
|
||||||
printf("accept: %s,%d\n",
|
|
||||||
inet_ntoa_r(remote_addr.sin_addr, inetaddr,
|
|
||||||
sizeof(inetaddr)),
|
|
||||||
htons(remote_addr.sin_port));
|
|
||||||
iperf_start_report(ctrl);
|
iperf_start_report(ctrl);
|
||||||
|
|
||||||
t.tv_sec = IPERF_SOCKET_RX_TIMEOUT;
|
t.tv_sec = IPERF_SOCKET_RX_TIMEOUT;
|
||||||
@ -411,11 +476,7 @@ static int iperf_run_tcp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
actual_recv = recv(sockfd, buffer, want_recv, 0);
|
actual_recv = recv(sockfd, buffer, want_recv, 0);
|
||||||
if (actual_recv == 0)
|
if (actual_recv == 0)
|
||||||
{
|
{
|
||||||
char inetaddr[INET_ADDRSTRLEN];
|
iperf_print_addr("closed by the peer", remote_addr);
|
||||||
printf("closed by the peer: %s,%d\n",
|
|
||||||
inet_ntoa_r(remote_addr.sin_addr, inetaddr,
|
|
||||||
sizeof(inetaddr)),
|
|
||||||
htons(remote_addr.sin_port));
|
|
||||||
|
|
||||||
/* Note: unlike the original iperf, this implementation
|
/* Note: unlike the original iperf, this implementation
|
||||||
* exits after finishing a single connection.
|
* exits after finishing a single connection.
|
||||||
@ -447,17 +508,30 @@ static int iperf_run_tcp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: iperf_run_udp_server
|
* Name: iperf_run_tcp_server
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Start udp server
|
* Start tcp server
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int iperf_run_udp_server(FAR struct iperf_ctrl_t *ctrl)
|
static int iperf_run_tcp_server(FAR struct iperf_ctrl_t *ctrl)
|
||||||
|
{
|
||||||
|
return iperf_run_server(ctrl, iperf_tcp_server);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: iperf_udp_server
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The main udp server logic
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int iperf_udp_server(FAR struct iperf_ctrl_t *ctrl,
|
||||||
|
FAR struct sockaddr *addr, socklen_t addrlen,
|
||||||
|
FAR struct sockaddr *remote_addr)
|
||||||
{
|
{
|
||||||
socklen_t addr_len = sizeof(struct sockaddr_in);
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
int actual_recv = 0;
|
int actual_recv = 0;
|
||||||
struct timeval t;
|
struct timeval t;
|
||||||
int want_recv = 0;
|
int want_recv = 0;
|
||||||
@ -466,7 +540,7 @@ static int iperf_run_udp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
int opt;
|
int opt;
|
||||||
bool udp_recv_start = true;
|
bool udp_recv_start = true;
|
||||||
|
|
||||||
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sockfd = socket(addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
{
|
{
|
||||||
iperf_show_socket_error_reason("udp server create", sockfd);
|
iperf_show_socket_error_reason("udp server create", sockfd);
|
||||||
@ -475,19 +549,12 @@ static int iperf_run_udp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
|
|
||||||
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
if (bind(sockfd, addr, addrlen) != 0)
|
||||||
addr.sin_port = htons(ctrl->cfg.sport);
|
|
||||||
addr.sin_addr.s_addr = ctrl->cfg.sip;
|
|
||||||
if (bind(sockfd, (FAR struct sockaddr *)&addr, sizeof(addr)) != 0)
|
|
||||||
{
|
{
|
||||||
iperf_show_socket_error_reason("udp server bind", sockfd);
|
iperf_show_socket_error_reason("udp server bind", sockfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(ctrl->cfg.sport);
|
|
||||||
addr.sin_addr.s_addr = ctrl->cfg.sip;
|
|
||||||
|
|
||||||
buffer = ctrl->buffer;
|
buffer = ctrl->buffer;
|
||||||
want_recv = ctrl->buffer_len;
|
want_recv = ctrl->buffer_len;
|
||||||
printf("want recv=%d\n", want_recv);
|
printf("want recv=%d\n", want_recv);
|
||||||
@ -499,7 +566,7 @@ static int iperf_run_udp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
while (!ctrl->finish)
|
while (!ctrl->finish)
|
||||||
{
|
{
|
||||||
actual_recv = recvfrom(sockfd, buffer, want_recv, 0,
|
actual_recv = recvfrom(sockfd, buffer, want_recv, 0,
|
||||||
(FAR struct sockaddr *)&addr, &addr_len);
|
remote_addr, &addrlen);
|
||||||
if (actual_recv < 0)
|
if (actual_recv < 0)
|
||||||
{
|
{
|
||||||
iperf_show_socket_error_reason("udp server recv", sockfd);
|
iperf_show_socket_error_reason("udp server recv", sockfd);
|
||||||
@ -508,6 +575,7 @@ static int iperf_run_udp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
{
|
{
|
||||||
if (udp_recv_start == true)
|
if (udp_recv_start == true)
|
||||||
{
|
{
|
||||||
|
iperf_print_addr("accept", remote_addr);
|
||||||
iperf_start_report(ctrl);
|
iperf_start_report(ctrl);
|
||||||
udp_recv_start = false;
|
udp_recv_start = false;
|
||||||
}
|
}
|
||||||
@ -523,17 +591,30 @@ static int iperf_run_udp_server(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: iperf_run_udp_client
|
* Name: iperf_run_udp_server
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Start udp client
|
* Start udp server
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int iperf_run_udp_client(FAR struct iperf_ctrl_t *ctrl)
|
static int iperf_run_udp_server(FAR struct iperf_ctrl_t *ctrl)
|
||||||
|
{
|
||||||
|
return iperf_run_server(ctrl, iperf_udp_server);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: iperf_udp_client
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The main udp client logic
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int iperf_udp_client(FAR struct iperf_ctrl_t *ctrl,
|
||||||
|
FAR struct sockaddr *addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
FAR struct iperf_udp_pkt_t *udp;
|
FAR struct iperf_udp_pkt_t *udp;
|
||||||
struct sockaddr_in addr;
|
|
||||||
int actual_send = 0;
|
int actual_send = 0;
|
||||||
bool retry = false;
|
bool retry = false;
|
||||||
uint32_t delay = 1;
|
uint32_t delay = 1;
|
||||||
@ -544,7 +625,7 @@ static int iperf_run_udp_client(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
int err;
|
int err;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sockfd = socket(addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
{
|
{
|
||||||
iperf_show_socket_error_reason("udp client create", sockfd);
|
iperf_show_socket_error_reason("udp client create", sockfd);
|
||||||
@ -553,10 +634,6 @@ static int iperf_run_udp_client(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
|
|
||||||
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(ctrl->cfg.dport);
|
|
||||||
addr.sin_addr.s_addr = ctrl->cfg.dip;
|
|
||||||
|
|
||||||
iperf_start_report(ctrl);
|
iperf_start_report(ctrl);
|
||||||
buffer = ctrl->buffer;
|
buffer = ctrl->buffer;
|
||||||
udp = (FAR struct iperf_udp_pkt_t *)buffer;
|
udp = (FAR struct iperf_udp_pkt_t *)buffer;
|
||||||
@ -573,8 +650,7 @@ static int iperf_run_udp_client(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
retry = false;
|
retry = false;
|
||||||
actual_send = sendto(sockfd, buffer, want_send, 0,
|
actual_send = sendto(sockfd, buffer, want_send, 0, addr, addrlen);
|
||||||
(FAR struct sockaddr *)&addr, sizeof(addr));
|
|
||||||
|
|
||||||
if (actual_send != want_send)
|
if (actual_send != want_send)
|
||||||
{
|
{
|
||||||
@ -609,34 +685,42 @@ static int iperf_run_udp_client(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: iperf_run_tcp_client
|
* Name: iperf_run_udp_client
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Start tcp client
|
* Start udp client
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int iperf_run_tcp_client(FAR struct iperf_ctrl_t *ctrl)
|
static int iperf_run_udp_client(FAR struct iperf_ctrl_t *ctrl)
|
||||||
|
{
|
||||||
|
return iperf_run_client(ctrl, iperf_udp_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: iperf_tcp_client
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The main tcp client logic
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int iperf_tcp_client(FAR struct iperf_ctrl_t *ctrl,
|
||||||
|
FAR struct sockaddr *addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
struct sockaddr_in remote_addr;
|
|
||||||
FAR uint8_t *buffer;
|
FAR uint8_t *buffer;
|
||||||
int actual_send = 0;
|
int actual_send = 0;
|
||||||
int want_send = 0;
|
int want_send = 0;
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
|
||||||
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
sockfd = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
{
|
{
|
||||||
iperf_show_socket_error_reason("tcp client create", sockfd);
|
iperf_show_socket_error_reason("tcp client create", sockfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&remote_addr, 0, sizeof(remote_addr));
|
if (connect(sockfd, addr, addrlen) < 0)
|
||||||
remote_addr.sin_family = AF_INET;
|
|
||||||
remote_addr.sin_port = htons(ctrl->cfg.dport);
|
|
||||||
remote_addr.sin_addr.s_addr = ctrl->cfg.dip;
|
|
||||||
if (connect(sockfd, (FAR struct sockaddr *)&remote_addr,
|
|
||||||
sizeof(remote_addr)) < 0)
|
|
||||||
{
|
{
|
||||||
iperf_show_socket_error_reason("tcp client connect", sockfd);
|
iperf_show_socket_error_reason("tcp client connect", sockfd);
|
||||||
return -1;
|
return -1;
|
||||||
@ -666,6 +750,19 @@ static int iperf_run_tcp_client(FAR struct iperf_ctrl_t *ctrl)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: iperf_run_tcp_client
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Start tcp client
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int iperf_run_tcp_client(FAR struct iperf_ctrl_t *ctrl)
|
||||||
|
{
|
||||||
|
return iperf_run_client(ctrl, iperf_tcp_client);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: iperf_task_traffic
|
* Name: iperf_task_traffic
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user