From 749eccb999fdf925d522abf5848f7c7fc88fd6ca Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 5 Jul 2018 16:03:54 -0600 Subject: [PATCH] Squashed commit of the following: apps/examples/tcpblaster: Some improvements/fixes in statistics reporting. apps/examples/tcpblaster: Add performance measurement functionality. apps/examples/tcpblaster: Initial commit is just apps/examples/nettest/ with naming changes. --- examples/README.txt | 7 + examples/tcpblaster/.gitignore | 16 + examples/tcpblaster/Kconfig | 574 +++++++++++++++++++++++ examples/tcpblaster/Make.defs | 39 ++ examples/tcpblaster/Makefile | 268 +++++++++++ examples/tcpblaster/tcpblaster.h | 112 +++++ examples/tcpblaster/tcpblaster_client.c | 227 +++++++++ examples/tcpblaster/tcpblaster_cmdline.c | 137 ++++++ examples/tcpblaster/tcpblaster_host.c | 64 +++ examples/tcpblaster/tcpblaster_netinit.c | 191 ++++++++ examples/tcpblaster/tcpblaster_server.c | 242 ++++++++++ examples/tcpblaster/tcpblaster_target1.c | 130 +++++ examples/tcpblaster/tcpblaster_target2.c | 75 +++ 13 files changed, 2082 insertions(+) create mode 100644 examples/tcpblaster/.gitignore create mode 100644 examples/tcpblaster/Kconfig create mode 100644 examples/tcpblaster/Make.defs create mode 100644 examples/tcpblaster/Makefile create mode 100644 examples/tcpblaster/tcpblaster.h create mode 100644 examples/tcpblaster/tcpblaster_client.c create mode 100644 examples/tcpblaster/tcpblaster_cmdline.c create mode 100644 examples/tcpblaster/tcpblaster_host.c create mode 100644 examples/tcpblaster/tcpblaster_netinit.c create mode 100644 examples/tcpblaster/tcpblaster_server.c create mode 100644 examples/tcpblaster/tcpblaster_target1.c create mode 100644 examples/tcpblaster/tcpblaster_target2.c diff --git a/examples/README.txt b/examples/README.txt index 66f221770..32d77fc2c 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -1841,6 +1841,13 @@ examples/system ret = system("ls -Rl /"); +examples/tcpblaster +^^^^^^^^^^^^^^^^^^ + + The tcpblaster example derives from the nettest example and basically duplicatesi + that example when the nettest PERFORMANCE option is selected. tcpblaster has a + little better reporting of performance stats, however. + examples/tcpecho ^^^^^^^^^^^^^^^^ diff --git a/examples/tcpblaster/.gitignore b/examples/tcpblaster/.gitignore new file mode 100644 index 000000000..8598f0ee9 --- /dev/null +++ b/examples/tcpblaster/.gitignore @@ -0,0 +1,16 @@ +/Make.dep +/.depend +/.built +/host +/config.h +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src +/*.hobj +/*.exe +/*.dSYM diff --git a/examples/tcpblaster/Kconfig b/examples/tcpblaster/Kconfig new file mode 100644 index 000000000..8a4f32f75 --- /dev/null +++ b/examples/tcpblaster/Kconfig @@ -0,0 +1,574 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_TCPBLASTER + bool "TCP Performance Test" + default n + depends on NET_TCP + ---help--- + Enable the network test example + +if EXAMPLES_TCPBLASTER + +config EXAMPLES_TCPBLASTER_SENDSIZE + int "Payload size" + default 4096 + ---help--- + This setting determines size of each test packet sent to the server. + +config EXAMPLES_TCPBLASTER_PROGNAME1 + string "Target1 program name" + default "tcpserver" if !EXAMPLES_TCPBLASTER_SERVER1 + default "tcpclient" if EXAMPLES_TCPBLASTER_SERVER1 + depends on BUILD_KERNEL + ---help--- + This is the name of the program that will be use when the TcpBlaster + program is installed for target1. + +config EXAMPLES_TCPBLASTER_STACKSIZE1 + int "Target1 stack size" + default 2048 + +config EXAMPLES_TCPBLASTER_PRIORITY1 + int "Target1 priority" + default 100 + +config EXAMPLES_TCPBLASTER_LOOPBACK + bool "Loopback test" + default n + depends on NET_LOOPBACK || IEEE802154_LOOPBACK || PKTRADIO_LOOPBACK + ---help--- + Perform the test using the local loopback device. In this case, + both the client and the server reside on the target. + +# No server if loopback; No second target if loopback + +if !EXAMPLES_TCPBLASTER_LOOPBACK + +config EXAMPLES_TCPBLASTER_SERVER1 + bool "Target1 is server" + default n + depends on !EXAMPLES_TCPBLASTER_LOOPBACK + ---help--- + Select to use the host as the client side of the test. Default: The + target is the client side of the test + +config EXAMPLES_TCPBLASTER_TARGET2 + bool "Second endpoint is a target" + default n + ---help--- + By default, the host PC is configured as the second endpoint of the + TCPBLASTER. If this option is selected, then the second endpoint + will be built into the FLASH image as well. This means that you + can use two target boards to run the test with no host PC + involvement. + +if EXAMPLES_TCPBLASTER_TARGET2 + +config EXAMPLES_TCPBLASTER_PROGNAME2 + string "Target2 program name" + default "tcpserver" if !EXAMPLES_TCPBLASTER_SERVER2 + default "tcpclient" if EXAMPLES_TCPBLASTER_SERVER2 + depends on BUILD_KERNEL + ---help--- + This is the name of the Target2 program that will be use when the + NSH ELF program is installed. + +config EXAMPLES_TCPBLASTER_PRIORITY2 + int "Target2 task priority" + default 100 + +config EXAMPLES_TCPBLASTER_STACKSIZE2 + int "Target2 stack size" + default 2048 + +endif # EXAMPLES_TCPBLASTER_TARGET2 +endif # !EXAMPLES_TCPBLASTER_LOOPBACK + +if EXAMPLES_TCPBLASTER_LOOPBACK +config EXAMPLES_TCPBLASTER_DAEMON_STACKSIZE + int "Server daemon stack size" + default 2048 + +config EXAMPLES_TCPBLASTER_DAEMON_PRIORITY + int "Server daemon priority" + default 100 +#endif + +endif # EXAMPLES_TCPBLASTER_LOOPBACK + +config EXAMPLES_TCPBLASTER_DEVNAME + string "Network device" + default "eth0" + +choice + prompt "IP Domain" + default EXAMPLES_TCPBLASTER_IPv4 if NET_IPv4 + default EXAMPLES_TCPBLASTER_IPv6 if NET_IPv6 && !NET_IPv4 + +config EXAMPLES_TCPBLASTER_IPv4 + bool "IPv4" + depends on NET_IPv4 + +config EXAMPLES_TCPBLASTER_IPv6 + bool "IPv6" + depends on NET_IPv6 + +endchoice # IP Domain + +# No hardware initialization if loopback + +config EXAMPLES_TCPBLASTER_INIT + bool "Initialize network" + default n if NSH_BUILTIN_APPS + default y if !NSH_BUILTIN_APPS + depends on !BUILD_KERNEL && !EXAMPLES_TCPBLASTER_LOOPBACK + ---help--- + Include logic to initialize the network. This should not be done if + the network is already initialized when tcpblaster runs. This is + usually the case, for example, when tcpblaster is run as an NSH built- + in task. + +config EXAMPLES_TCPBLASTER_NOMAC + bool "Use Canned MAC Address" + default n + depends on EXAMPLES_TCPBLASTER_INIT + +if EXAMPLES_TCPBLASTER_IPv4 + +comment "IPv4 addresses" + +if EXAMPLES_TCPBLASTER_INIT + +config EXAMPLES_TCPBLASTER_IPADDR + hex "Target IP address" + default 0x0a000002 + +config EXAMPLES_TCPBLASTER_DRIPADDR + hex "Default Router IP address (Gateway)" + default 0x0a000001 + +config EXAMPLES_TCPBLASTER_NETMASK + hex "Network Mask" + default 0xffffff00 + +endif # EXAMPLES_TCPBLASTER_INIT + +# No server if loopback + +if !EXAMPLES_TCPBLASTER_LOOPBACK + +config EXAMPLES_TCPBLASTER_SERVERIP + hex "Server IP Address" + default 0x0a000001 if !EXAMPLES_TCPBLASTER_SERVER + default 0x0a000002 if EXAMPLES_TCPBLASTER_SERVER + ---help--- + IP address of the server. If the target is the server, then + EXAMPLES_TCPBLASTER_SERVERIP should be the same as + EXAMPLES_TCPBLASTER_IPADDR (default). If the target is the client, + then the default value of EXAMPLES_TCPBLASTER_SERVERIP is set to the + host PC IP address (possibly the gateway address, + EXAMPLES_TCPBLASTER_DRIPADDR?). + +endif # !EXAMPLES_TCPBLASTER_LOOPBACK +endif # EXAMPLES_TCPBLASTER_IPv4 + +if EXAMPLES_TCPBLASTER_IPv6 +if !NET_ICMPv6_AUTOCONF + +comment "Target IPv6 address" + +if EXAMPLES_TCPBLASTER_INIT + +config EXAMPLES_TCPBLASTER_IPv6ADDR_1 + hex "[0]" + default 0xfc00 + range 0x0 0xffff + ---help--- + Target IPv6 address. This is a 16-bit integer value in host order. + Each of the eight values forming the full IP address must be + specified individually. This is the first of the 8-values. The + default for all eight values is fc00::2. + +config EXAMPLES_TCPBLASTER_IPv6ADDR_2 + hex "[1]" + default 0x0000 + range 0x0 0xffff + ---help--- + Target IPv6 address. This is a 16-bit integer value in host order. + Each of the eight values forming the full IP address must be + specified individually. This is the second of the 8-values. The + default for all eight values is fc00::2. + +config EXAMPLES_TCPBLASTER_IPv6ADDR_3 + hex "[2]" + default 0x0000 + range 0x0 0xffff + ---help--- + Target IPv6 address. This is a 16-bit integer value in host order. + Each of the eight values forming the full IP address must be + specified individually. This is the third of the 8-values. The + default for all eight values is fc00::2. + +config EXAMPLES_TCPBLASTER_IPv6ADDR_4 + hex "[3]" + default 0x0000 + range 0x0 0xffff + ---help--- + Target IPv6 address. This is a 16-bit integer value in host order. + Each of the eight values forming the full IP address must be + specified individually. This is the fourth of the 8-values. The + default for all eight values is fc00::2. + +config EXAMPLES_TCPBLASTER_IPv6ADDR_5 + hex "[4]" + default 0x0000 + range 0x0 0xffff + ---help--- + Target IPv6 address. This is a 16-bit integer value in host order. + Each of the eight values forming the full IP address must be + specified individually. This is the fifth of the 8-values. The + default for all eight values is fc00::2. + +config EXAMPLES_TCPBLASTER_IPv6ADDR_6 + hex "[5]" + default 0x0000 + range 0x0 0xffff + ---help--- + Target IPv6 address. This is a 16-bit integer value in host order. + Each of the eight values forming the full IP address must be + specified individually. This is the sixth of the 8-values. The + default for all eight values is fc00::2. + +config EXAMPLES_TCPBLASTER_IPv6ADDR_7 + hex "[6]" + default 0x0000 + range 0x0 0xffff + ---help--- + Target IPv6 address. This is a 16-bit integer value in host order. + Each of the eight values forming the full IP address must be + specified individually. This is the seventh of the 8-values. The + default for all eight values is fc00::2. + +config EXAMPLES_TCPBLASTER_IPv6ADDR_8 + hex "[7]" + default 0x0002 + range 0x0 0xffff + ---help--- + Target IPv6 address. This is a 16-bit integer value in host order. + Each of the eight values forming the full IP address must be + specified individually. This is the last of the 8-values. The + default for all eight values is fc00::2. + +comment "Router IPv6 address" + +config EXAMPLES_TCPBLASTER_DRIPv6ADDR_1 + hex "[0]" + default 0xfc00 + range 0x0 0xffff + ---help--- + Default router IP address (aka, Gateway). This is a 16-bit integer + value in host order. Each of the eight values forming the full IP + address must be specified individually. This is the first of the + 8-values. The default for all eight values is fc00::1. + +config EXAMPLES_TCPBLASTER_DRIPv6ADDR_2 + hex "[1]" + default 0x0000 + range 0x0 0xffff + ---help--- + Default router IP address (aka, Gateway). This is a 16-bit integer + value in host order. Each of the eight values forming the full IP + address must be specified individually. This is the second of the + 8-values. The default for all eight values is fc00::1. + +config EXAMPLES_TCPBLASTER_DRIPv6ADDR_3 + hex "[2]" + default 0x0000 + range 0x0 0xffff + ---help--- + Default router IP address (aka, Gateway). This is a 16-bit integer + value in host order. Each of the eight values forming the full IP + address must be specified individually. This is the third of the + 8-values. The default for all eight values is fc00::1. + +config EXAMPLES_TCPBLASTER_DRIPv6ADDR_4 + hex "[3]" + default 0x0000 + range 0x0 0xffff + ---help--- + Default router IP address (aka, Gateway). This is a 16-bit integer + value in host order. Each of the eight values forming the full IP + address must be specified individually. This is the fourth of the + 8-values. The default for all eight values is fc00::1. + +config EXAMPLES_TCPBLASTER_DRIPv6ADDR_5 + hex "[4]" + default 0x0000 + range 0x0 0xffff + ---help--- + Default router IP address (aka, Gateway). This is a 16-bit integer + value in host order. Each of the eight values forming the full IP + address must be specified individually. This is the fifth of the + 8-values. The default for all eight values is fc00::1. + +config EXAMPLES_TCPBLASTER_DRIPv6ADDR_6 + hex "[5]" + default 0x0000 + range 0x0 0xffff + ---help--- + Default router IP address (aka, Gateway). This is a 16-bit integer + value in host order. Each of the eight values forming the full IP + address must be specified individually. This is the sixth of the + 8-values. The default for all eight values is fc00::1. + +config EXAMPLES_TCPBLASTER_DRIPv6ADDR_7 + hex "[6]" + default 0x0000 + range 0x0 0xffff + ---help--- + Default router IP address (aka, Gateway). This is a 16-bit integer + value in host order. Each of the eight values forming the full IP + address must be specified individually. This is the seventh of the + 8-values. The default for all eight values is fc00::1. + +config EXAMPLES_TCPBLASTER_DRIPv6ADDR_8 + hex "[7]" + default 0x0001 + range 0x0 0xffff + ---help--- + Default router IP address (aka, Gateway). This is a 16-bit integer + value in host order. Each of the eight values forming the full IP + address must be specified individually. This is the last of the + 8-values. The default for all eight values is fc00::1. + +comment "IPv6 Network mask" + +config EXAMPLES_TCPBLASTER_IPv6NETMASK_1 + hex "[0]" + default 0xffff + range 0x0 0xffff + ---help--- + Network mask. This is a 16-bit integer value in host order. Each + of the eight values forming the full IP address must be specified + individually. This is the first of the 8-values. The default for + all eight values is fe00::0. + +config EXAMPLES_TCPBLASTER_IPv6NETMASK_2 + hex "[1]" + default 0xffff + range 0x0 0xffff + ---help--- + Network mask. This is a 16-bit integer value in host order. Each + of the eight values forming the full IP address must be specified + individually. This is the second of the 8-values. The default for + all eight values is fe00::0. + +config EXAMPLES_TCPBLASTER_IPv6NETMASK_3 + hex "[2]" + default 0xffff + range 0x0 0xffff + ---help--- + Network mask. This is a 16-bit integer value in host order. Each + of the eight values forming the full IP address must be specified + individually. This is the third of the 8-values. The default for + all eight values is fe00::0. + +config EXAMPLES_TCPBLASTER_IPv6NETMASK_4 + hex "[3]" + default 0xffff + range 0x0 0xffff + ---help--- + Network mask. This is a 16-bit integer value in host order. Each + of the eight values forming the full IP address must be specified + individually. This is the fourth of the 8-values. The default for + all eight values is fe00::0. + +config EXAMPLES_TCPBLASTER_IPv6NETMASK_5 + hex "[4]" + default 0xffff + range 0x0 0xffff + ---help--- + Network mask. This is a 16-bit integer value in host order. Each + of the eight values forming the full IP address must be specified + individually. This is the fifth of the 8-values. The default for + all eight values is fe00::0. + +config EXAMPLES_TCPBLASTER_IPv6NETMASK_6 + hex "[5]" + default 0xffff + range 0x0 0xffff + ---help--- + Network mask. This is a 16-bit integer value in host order. Each + of the eight values forming the full IP address must be specified + individually. This is the sixth of the 8-values. The default for + all eight values is fe00::0. + +config EXAMPLES_TCPBLASTER_IPv6NETMASK_7 + hex "[6]" + default 0xffff + range 0x0 0xffff + ---help--- + Network mask. This is a 16-bit integer value in host order. Each + of the eight values forming the full IP address must be specified + individually. This is the seventh of the 8-values. The default for + all eight values is fe00::0. + +config EXAMPLES_TCPBLASTER_IPv6NETMASK_8 + hex "[7]" + default 0xff80 + range 0x0 0xffff + ---help--- + Network mask. This is a 16-bit integer value in host order. Each + of the eight values forming the full IP address must be specified + individually. This is the eighth of the 8-values. The default for + all eight values is fe00::0. + +endif # NET_ICMPv6_AUTOCONF +endif # EXAMPLES_TCPBLASTER_INIT + +# Addresses are well known if loopback is used. + +if !EXAMPLES_TCPBLASTER_LOOPBACK || !NET_LOOPBACK + +comment "Server IPv6 address" + +config EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_1 + hex "[0]" + default 0xfc00 + range 0x0 0xffff + ---help--- + IP address of the server. If the target is the server, then + EXAMPLES_TCPBLASTER_SERVERIP should be the same as + EXAMPLES_TCPBLASTER_IPADDR (default). If the target is the cleint, + then the default value of EXAMPLES_TCPBLASTER_SERVERIP is set to the + host PC IP address (possibly the gateway address, + EXAMPLES_TCPBLASTER_DRIPADDR?). + + This is a 16-bit integer value in host order. Each of the eight + values forming the full IP address must be specified individually. + This is the first of the 8-values. + +config EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_2 + hex "[1]" + default 0x0000 + range 0x0 0xffff + ---help--- + IP address of the server. If the target is the server, then + EXAMPLES_TCPBLASTER_SERVERIP should be the same as + EXAMPLES_TCPBLASTER_IPADDR (default). If the target is the client, + then the default value of EXAMPLES_TCPBLASTER_SERVERIP is set to the + host PC IP address (possibly the gateway address, + EXAMPLES_TCPBLASTER_DRIPADDR?). + + This is a 16-bit integer value in host order. Each of the eight + values forming the full IP address must be specified individually. + This is the second of the 8-values. + +config EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_3 + hex "[2]" + default 0x0000 + range 0x0 0xffff + ---help--- + IP address of the server. If the target is the server, then + EXAMPLES_TCPBLASTER_SERVERIP should be the same as + EXAMPLES_TCPBLASTER_IPADDR (default). If the target is the client, + then the default value of EXAMPLES_TCPBLASTER_SERVERIP is set to the + host PC IP address (possibly the gateway address, + EXAMPLES_TCPBLASTER_DRIPADDR?). + + This is a 16-bit integer value in host order. Each of the eight + values forming the full IP address must be specified individually. + This is the Third of the 8-values. + +config EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_4 + hex "[3]" + default 0x0000 + range 0x0 0xffff + ---help--- + IP address of the server. If the target is the server, then + EXAMPLES_TCPBLASTER_SERVERIP should be the same as + EXAMPLES_TCPBLASTER_IPADDR (default). If the target is the client, + then the default value of EXAMPLES_TCPBLASTER_SERVERIP is set to the + host PC IP address (possibly the gateway address, + EXAMPLES_TCPBLASTER_DRIPADDR?). + + This is a 16-bit integer value in host order. Each of the eight + values forming the full IP address must be specified individually. + This is the fourth of the 8-values. + +config EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_5 + hex "[4]" + default 0x0000 + range 0x0 0xffff + ---help--- + IP address of the server. If the target is the server, then + EXAMPLES_TCPBLASTER_SERVERIP should be the same as + EXAMPLES_TCPBLASTER_IPADDR (default). If the target is the client, + then the default value of EXAMPLES_TCPBLASTER_SERVERIP is set to the + host PC IP address (possibly the gateway address, + EXAMPLES_TCPBLASTER_DRIPADDR?). + + This is a 16-bit integer value in host order. Each of the eight + values forming the full IP address must be specified individually. + This is the fifth of the 8-values. + +config EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_6 + hex "[5]" + default 0x0000 + range 0x0 0xffff + ---help--- + IP address of the server. If the target is the server, then + EXAMPLES_TCPBLASTER_SERVERIP should be the same as + EXAMPLES_TCPBLASTER_IPADDR (default). If the target is the client, + then the default value of EXAMPLES_TCPBLASTER_SERVERIP is set to the + host PC IP address (possibly the gateway address, + EXAMPLES_TCPBLASTER_DRIPADDR?). + + This is a 16-bit integer value in host order. Each of the eight + values forming the full IP address must be specified individually. + This is the sixth of the 8-values. + +config EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_7 + hex "[6]" + default 0x0000 + range 0x0 0xffff + ---help--- + IP address of the server. If the target is the server, then + EXAMPLES_TCPBLASTER_SERVERIP should be the same as + EXAMPLES_TCPBLASTER_IPADDR (default). If the target is the client, + then the default value of EXAMPLES_TCPBLASTER_SERVERIP is set to the + host PC IP address (possibly the gateway address, + EXAMPLES_TCPBLASTER_DRIPADDR?). + + This is a 16-bit integer value in host order. Each of the eight + values forming the full IP address must be specified individually. + This is the seventh of the 8-values. + +config EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_8 + hex "[7]" + default 0x0001 if !EXAMPLES_TCPBLASTER_SERVER + default 0x0002 if EXAMPLES_TCPBLASTER_SERVER + range 0x0 0xffff + ---help--- + IP address of the server. If the target is the server, then + EXAMPLES_TCPBLASTER_SERVERIP should be the same as + EXAMPLES_TCPBLASTER_IPADDR (default). If the target is the client, + then the default value of EXAMPLES_TCPBLASTER_SERVERIP is set to the + host PC IP address (possibly the gateway address, + EXAMPLES_TCPBLASTER_DRIPADDR?). + + This is a 16-bit integer value in host order. Each of the eight + values forming the full IP address must be specified individually. + This is the last of the 8-values. + +endif # !EXAMPLES_TCPBLASTER_LOOPBACK +endif # EXAMPLES_TCPBLASTER_IPv6 + +config EXAMPLES_TCPBLASTER_SERVER_PORTNO + int "Server port number" + default 5471 + +endif # EXAMPLES_TCPBLASTER diff --git a/examples/tcpblaster/Make.defs b/examples/tcpblaster/Make.defs new file mode 100644 index 000000000..f19df0e49 --- /dev/null +++ b/examples/tcpblaster/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/examples/tcpblaster/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2018 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_EXAMPLES_TCPBLASTER),y) +CONFIGURED_APPS += examples/tcpblaster +endif diff --git a/examples/tcpblaster/Makefile b/examples/tcpblaster/Makefile new file mode 100644 index 000000000..feff3866c --- /dev/null +++ b/examples/tcpblaster/Makefile @@ -0,0 +1,268 @@ +############################################################################ +# examples/tcpblaster/Makefile +# +# Copyright (C) 2018 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# Basic TCP networking test + +TARGCMN_CSRCS = tcpblaster_cmdline.c +ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_INIT),y) +TARGCMN_CSRCS += tcpblaster_netinit.c +endif + +TARGCMN_COBJS = $(TARGCMN_CSRCS:.c=$(OBJEXT)) + +# Target 1 Files + +TARG1_CSRCS = +ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK),y) +TARG1_CSRCS += tcpblaster_server.c tcpblaster_client.c +else ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_SERVER),y) +TARG1_CSRCS += tcpblaster_server.c +else +TARG1_CSRCS += tcpblaster_client.c +endif +TARG1_MAINSRC = tcpblaster_target1.c + +TARG1_COBJS = $(TARG1_CSRCS:.c=$(OBJEXT)) +TARG1_MAINOBJ = $(TARG1_MAINSRC:.c=$(OBJEXT)) + +TARG_CSRCS = $(TARG1_CSRCS) $(TARG1_CSRCS) $(TARGCMN_CSRCS) +TARG_OBJS = $(TARG1_COBJS) $(TARGCMN_COBJS) + +# Target 1 Application Info + +ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_SERVER1),y) +CONFIG_EXAMPLES_TCPBLASTER_PROGNAME1 ?= tcpserver +APPNAME1 = tcpserver +else +CONFIG_EXAMPLES_TCPBLASTER_PROGNAME1 ?= tcpclient +APPNAME1 = tcpclient +endif +CONFIG_EXAMPLES_TCPBLASTER_PRIORITY1 ?= 100 +CONFIG_EXAMPLES_TCPBLASTER_STACKSIZE1 ?= 2048 + +PROGNAME1 = $(CONFIG_EXAMPLES_TCPBLASTER_PROGNAME1) +PRIORITY1 = $(CONFIG_EXAMPLES_TCPBLASTER_PRIORITY1) +STACKSIZE1 = $(CONFIG_EXAMPLES_TCPBLASTER_STACKSIZE1) + +# Target 2 + +ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_TARGET2),y) + +TARG2_CSRCS = +ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_SERVER1),y) +TARG2_CSRCS += tcpblaster_client.c +else +TARG2_CSRCS += tcpblaster_server.c +endif +TARG2_MAINSRC = tcpblaster_target2.c + +TARG2_COBJS = $(TARG2_CSRCS:.c=$(OBJEXT)) +TARG2_MAINOBJ = $(TARG2_MAINSRC:.c=$(OBJEXT)) + +# Target 2 Application Info + +ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_SERVER1),y) +CONFIG_EXAMPLES_TCPBLASTER_PROGNAME2 ?= tcpclient +APPNAME2 = tcpclient +else +CONFIG_EXAMPLES_TCPBLASTER_PROGNAME2 ?= tcpserver +APPNAME2 = tcpserver +endif +CONFIG_EXAMPLES_TCPBLASTER_PRIORITY2 ?= 100 +CONFIG_EXAMPLES_TCPBLASTER_STACKSIZE2 ?= 2048 + +PROGNAME2 = $(CONFIG_EXAMPLES_TCPBLASTER_PROGNAME2) +PRIORITY2 = $(CONFIG_EXAMPLES_TCPBLASTER_PRIORITY2) +STACKSIZE2 = $(CONFIG_EXAMPLES_TCPBLASTER_STACKSIZE2) + +endif + +# All targets + +TARG_SRCS = $(TARG1_CRCS) $(TARG1_MAINSRC) $(TARG2_CSRCS) $(TARG2_MAINSRC) $(TARGCMN_CSRCS) +TARG_OBJS = $(TARG1_COBJS) $(TARG2_COBJS) $(TARGCMN_COBJS) + +ifneq ($(CONFIG_BUILD_KERNEL),y) + TARG_OBJS += $(TARG1_MAINOBJ) $(TARG2_MAINOBJ) +endif + +ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_TARGET2),y) +MAINNAME1 = tcpblaster1_main +MAINNAME2 = tcpblaster2_main +else +MAINNAME1 = tcpblaster_main +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + TARG_BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + TARG_BIN = ..\\..\\libapps$(LIBEXT) +else + TARG_BIN = ../../libapps$(LIBEXT) +endif +endif + +# Host + +ifneq ($(CONFIG_EXAMPLES_TCPBLASTER_TARGET2),y) +ifneq ($(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK),y) + + HOSTCFLAGS += -DTCPBLASTER_HOST=1 + ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_SERVER),y) + HOSTCFLAGS += -DCONFIG_EXAMPLES_TCPBLASTER_SERVER=1 -DCONFIG_EXAMPLES_TCPBLASTER_SERVERIP="$(CONFIG_EXAMPLES_TCPBLASTER_SERVERIP)" + endif + + HOST_SRCS = tcpblaster_host.c + ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_SERVER),y) + HOST_SRCS += tcpblaster_client.c + HOST_BIN = tcpclient$(EXEEXT) + else + HOST_SRCS += tcpblaster_server.c + HOST_BIN = tcpserver$(EXEEXT) + endif + + HOSTOBJEXT ?= hobj + HOST_OBJS = $(HOST_SRCS:.c=.$(HOSTOBJEXT)) + +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built $(HOST_BIN) +.PHONY: clean depend distclean preconfig +.PRECIOUS: ../../libapps$(LIBEXT) + +$(TARG1_COBJS) $(TARG1_MAINOBJ) $(TARG2_COBJS) $(TARG2_MAINOBJ) $(TARGCMN_COBJS) : %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +ifneq ($(CONFIG_EXAMPLES_TCPBLASTER_TARGET2),y) +ifneq ($(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK),y) + +$(HOST_OBJS): %.$(HOSTOBJEXT): %.c + @echo "CC: $<" + $(Q) $(HOSTCC) -c $(HOSTCFLAGS) $< -o $@ + +endif +endif + +config.h: $(TOPDIR)/include/nuttx/config.h + @echo "CP: $<" + $(Q) cp $< $@ + +ifneq ($(CONFIG_EXAMPLES_TCPBLASTER_TARGET2),y) +ifneq ($(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK),y) + +$(HOST_BIN): config.h $(HOST_OBJS) + @echo "LD: $@" + $(Q) $(HOSTCC) $(HOSTLDFLAGS) $(HOST_OBJS) -o $@ + +endif +endif + +.built: config.h $(TARG_OBJS) + $(call ARCHIVE, $(TARG_BIN), $(TARG_OBJS)) + $(Q) touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME1): $(OBJS) $(TARG1_MAINOBJ) + @echo "LD: $(PROGNAME1)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME1) $(ARCHCRT0OBJ) $(TARG1_MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME1) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME1) + +else +install: + +endif + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME1),$(PRIORITY1),$(STACKSIZE1),$(MAINNAME1)) + +ifeq ($(CONFIG_EXAMPLES_TCPBLASTER_TARGET2),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME2)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME2),$(PRIORITY2),$(STACKSIZE2),$(MAINNAME2)) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat \ + $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME2)_main.bdat +else +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat +endif +else +context: +endif + +.depend: Makefile config.h $(TARG_CSRCS) + @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(TARG_CSRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: +ifneq ($(CONFIG_EXAMPLES_TCPBLASTER_TARGET2),y) +ifneq ($(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK),y) + $(call DELFILE, *.$(HOSTOBJEXT)) + $(call DELFILE, $(HOST_BIN)) +endif +endif + $(call DELFILE, .built) + $(call DELFILE, *.dSYM) + $(call DELFILE, config.h) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +preconfig: + +-include Make.dep diff --git a/examples/tcpblaster/tcpblaster.h b/examples/tcpblaster/tcpblaster.h new file mode 100644 index 000000000..28abcdc84 --- /dev/null +++ b/examples/tcpblaster/tcpblaster.h @@ -0,0 +1,112 @@ +/**************************************************************************** + * examples/tcpblaster/tcpblaster.h + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __APPS_EXAMPLES_TCPBLASTER_H +#define __APPS_EXAMPLES_TCPBLASTER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef TCPBLASTER_HOST +#else +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef TCPBLASTER_HOST + /* HTONS/L macros are unique to uIP */ + +# define HTONS(a) htons(a) +# define HTONL(a) htonl(a) + + /* Have SO_LINGER */ + +# define TCPBLASTER_HAVE_SOLINGER 1 + +#else +# ifdef CONFIG_NET_SOLINGER +# define TCPBLASTER_HAVE_SOLINGER 1 +# else +# undef TCPBLASTER_HAVE_SOLINGER +# endif +#endif /* TCPBLASTER_HOST */ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_IPv6 +# define AF_INETX AF_INET6 +# define PF_INETX PF_INET6 +#else +# define AF_INETX AF_INET +# define PF_INETX PF_INET +#endif + +#ifndef CONFIG_EXAMPLES_TCPBLASTER_SERVER_PORTNO +# define CONFIG_EXAMPLES_TCPBLASTER_SERVER_PORTNO 5471 +#endif + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_SENDSIZE +# define SENDSIZE CONFIG_EXAMPLES_TCPBLASTER_SENDSIZE +#else +# define SENDSIZE 4096 +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_IPv6 +uint16_t g_tcpblasterserver_ipv6[8]; +#else +uint32_t g_tcpblasterserver_ipv4; +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_INIT +void tcpblaster_initialize(void); +#endif + +void tcpblaster_cmdline(int argc, char **argv); +extern void tcpblaster_client(void); +extern void tcpblaster_server(void); + +#endif /* __APPS_EXAMPLES_TCPBLASTER_H */ diff --git a/examples/tcpblaster/tcpblaster_client.c b/examples/tcpblaster/tcpblaster_client.c new file mode 100644 index 000000000..3ef323a54 --- /dev/null +++ b/examples/tcpblaster/tcpblaster_client.c @@ -0,0 +1,227 @@ +/**************************************************************************** + * examples/tcpblaster/tcpblaster_client.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "tcpblaster.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void tcpblaster_client(void) +{ +#ifdef CONFIG_EXAMPLES_TCPBLASTER_IPv6 + struct sockaddr_in6 server; +#else + struct sockaddr_in server; +#endif + struct timespec start; + socklen_t addrlen; + char *outbuf; + unsigned long sendtotal; + unsigned long totallost; + int sendcount; + int partials; + int sockfd; + int nbytessent; + int ch; + int i; + + /* Allocate buffers */ + + outbuf = (char*)malloc(SENDSIZE); + if (!outbuf) + { + printf("client: failed to allocate buffers\n"); + exit(1); + } + + /* Create a new TCP socket */ + + sockfd = socket(PF_INETX, SOCK_STREAM, 0); + if (sockfd < 0) + { + printf("client socket failure %d\n", errno); + goto errout_with_buffers; + } + + /* Set up the server address */ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_IPv6 + server.sin6_family = AF_INET6; + server.sin6_port = HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVER_PORTNO); + memcpy(server.sin6_addr.s6_addr16, g_tcpblasterserver_ipv6, 8 * sizeof(uint16_t)); + addrlen = sizeof(struct sockaddr_in6); + + printf("Connecting to IPv6 Address: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + g_tcpblasterserver_ipv6[0], g_tcpblasterserver_ipv6[1], g_tcpblasterserver_ipv6[2], g_tcpblasterserver_ipv6[3], + g_tcpblasterserver_ipv6[4], g_tcpblasterserver_ipv6[5], g_tcpblasterserver_ipv6[6], g_tcpblasterserver_ipv6[7]); +#else + server.sin_family = AF_INET; + server.sin_port = HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVER_PORTNO); + server.sin_addr.s_addr = (in_addr_t)g_tcpblasterserver_ipv4; + addrlen = sizeof(struct sockaddr_in); + + printf("Connecting to IPv4 Address: %08lx\n", (unsigned long)g_tcpblasterserver_ipv4); +#endif + + /* Connect the socket to the server */ + + if (connect( sockfd, (struct sockaddr*)&server, addrlen) < 0) + { + printf("client: connect failure: %d\n", errno); + goto errout_with_socket; + } + + printf("client: Connected\n"); + + /* Initialize the buffer */ + + ch = 0x20; + for (i = 0; i < SENDSIZE; i++ ) + { + outbuf[i] = ch; + if (++ch > 0x7e) + { + ch = 0x20; + } + } + + /* Then send messages forever */ + + sendcount = 0; + sendtotal = 0; + partials = 0; + totallost = 0; + + (void)clock_gettime(CLOCK_REALTIME, &start); + + for (; ; ) + { + nbytessent = send(sockfd, outbuf, SENDSIZE, 0); + if (nbytessent < 0) + { + printf("client: send failed: %d\n", errno); + goto errout_with_socket; + } + else if (nbytessent > 0 && nbytessent < SENDSIZE) + { + /* Partial buffers can be sent if there is insufficient buffering + * space to buffer the whole SENDSIZE request. This is not an + * error, but is an interesting thing to keep track of. + */ + + partials++; + totallost += (SENDSIZE - nbytessent); + } + else if (nbytessent != SENDSIZE) + { + printf("client: Bad send length=%d: %d of \n", + nbytessent, SENDSIZE); + goto errout_with_socket; + } + + sendtotal += nbytessent; + + if (++sendcount >= 50) + { + struct timespec elapsed; + struct timespec curr; + float fkbrecvd; + float felapsed; + + (void)clock_gettime(CLOCK_REALTIME, &curr); + + elapsed.tv_sec = curr.tv_sec - start.tv_sec; + if (curr.tv_nsec >= start.tv_nsec) + { + elapsed.tv_nsec = curr.tv_nsec - start.tv_nsec; + } + else + { + unsigned long borrow = 1000000000 - start.tv_nsec; + elapsed.tv_nsec = curr.tv_nsec + borrow; + } + + fkbrecvd = (float)sendtotal / 1024.0; + felapsed = (float)elapsed.tv_sec + (float)elapsed.tv_nsec / 1000000000.0; + printf("Sent %d packets: %7.1f Kb (avg %5.1f Kb) in %6.2f Sec (%7.1f Kbps)\n", + sendcount, fkbrecvd, fkbrecvd/sendcount, felapsed, fkbrecvd/felapsed); + + if (partials > 0) + { + float fkblost; + + fkblost = (float)totallost / 1024.0; + printf("Partial buffers sent: %d Data not sent: %7.1f Kb\n", + partials, fkblost); + } + + sendcount = 0; + sendtotal = 0; + partials = 0; + totallost = 0; + + (void)clock_gettime(CLOCK_REALTIME, &start); + } + } + + free(outbuf); + return; + +errout_with_socket: + close(sockfd); + +errout_with_buffers: + free(outbuf); + exit(1); +} diff --git a/examples/tcpblaster/tcpblaster_cmdline.c b/examples/tcpblaster/tcpblaster_cmdline.c new file mode 100644 index 000000000..04450e196 --- /dev/null +++ b/examples/tcpblaster/tcpblaster_cmdline.c @@ -0,0 +1,137 @@ +/**************************************************************************** + * examples/tcpblaster/tcpblaster_cmdline.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "config.h" + +#include +#include +#include + +#include "tcpblaster.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_IPv6 + +uint16_t g_tcpblasterserver_ipv6[8] = +{ +#if defined(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK) && defined(NET_LOOPBACK) + 0 /* Use the loopback address */ + 0 + 0 + 0 + 0 + 0 + 0 + HTONS(1); +#else + HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_1), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_2), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_3), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_4), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_5), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_6), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_7), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVERIPv6ADDR_8) +#endif +}; + +#else + +#if defined(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK) && defined(NET_LOOPBACK) +uint32_t g_tcpblasterserver_ipv4 = HTONL(0x7f000001); +#else +uint32_t g_tcpblasterserver_ipv4 = HTONL(CONFIG_EXAMPLES_TCPBLASTER_SERVERIP); +#endif + +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * show_usage + ****************************************************************************/ + +static void show_usage(FAR const char *progname) +{ + fprintf(stderr, "USAGE: %s []\n", progname); + exit(1); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * tcpblaster_cmdline + ****************************************************************************/ + +void tcpblaster_cmdline(int argc, char **argv) +{ + /* Currently only a single command line option is supported: The server + * IP address. + */ + + if (argc == 2) + { + int ret; + + /* Convert the argument into a binary address */ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_IPv6 + ret = inet_pton(AF_INET6, argv[1], g_tcpblasterserver_ipv6); +#else + ret = inet_pton(AF_INET, argv[1], &g_tcpblasterserver_ipv4); +#endif + if (ret < 0) + { + fprintf(stderr, "ERROR: is invalid\n"); + show_usage(argv[0]); + } + } + else if (argc != 1) + { + fprintf(stderr, "ERROR: Too many arguments\n"); + show_usage(argv[0]); + } +} diff --git a/examples/tcpblaster/tcpblaster_host.c b/examples/tcpblaster/tcpblaster_host.c new file mode 100644 index 000000000..d1b52549b --- /dev/null +++ b/examples/tcpblaster/tcpblaster_host.c @@ -0,0 +1,64 @@ +/**************************************************************************** + * examples/tcpblaster/tcpblaster_host.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "config.h" +#include "tcpblaster.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * main + ****************************************************************************/ + +int main(int argc, char **argv, char **envp) +{ +#ifdef CONFIG_EXAMPLES_TCPBLASTER_SERVER + tcpblaster_client(); +#else + tcpblaster_server(); +#endif + + return 0; +} diff --git a/examples/tcpblaster/tcpblaster_netinit.c b/examples/tcpblaster/tcpblaster_netinit.c new file mode 100644 index 000000000..19127e5a5 --- /dev/null +++ b/examples/tcpblaster/tcpblaster_netinit.c @@ -0,0 +1,191 @@ +/**************************************************************************** + * examples/tcpblaster/tcpblaster_netinit.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include + +#include "netutils/netlib.h" + +#include "tcpblaster.h" + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_INIT + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_DEVNAME +# define DEVNAME CONFIG_EXAMPLES_TCPBLASTER_DEVNAME +#else +# define DEVNAME "eth0" +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if defined(CONFIG_EXAMPLES_TCPBLASTER_INIT) && \ + defined(CONFIG_EXAMPLES_TCPBLASTER_IPv6) && \ + !defined(CONFIG_NET_ICMPv6_AUTOCONF) +/* Our host IPv6 address */ + +static const uint16_t g_ipv6_hostaddr[8] = +{ + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6ADDR_1), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6ADDR_2), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6ADDR_3), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6ADDR_4), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6ADDR_5), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6ADDR_6), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6ADDR_7), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6ADDR_8), +}; + +/* Default routine IPv6 address */ + +static const uint16_t g_ipv6_draddr[8] = +{ + HTONS(CONFIG_EXAMPLES_TCPBLASTER_DRIPv6ADDR_1), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_DRIPv6ADDR_2), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_DRIPv6ADDR_3), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_DRIPv6ADDR_4), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_DRIPv6ADDR_5), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_DRIPv6ADDR_6), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_DRIPv6ADDR_7), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_DRIPv6ADDR_8), +}; + +/* IPv6 netmask */ + +static const uint16_t g_ipv6_netmask[8] = +{ + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6NETMASK_1), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6NETMASK_2), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6NETMASK_3), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6NETMASK_4), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6NETMASK_5), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6NETMASK_6), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6NETMASK_7), + HTONS(CONFIG_EXAMPLES_TCPBLASTER_IPv6NETMASK_8), +}; +#endif /* CONFIG_EXAMPLES_TCPBLASTER_INIT && CONFIG_EXAMPLES_TCPBLASTER_IPv6 && !CONFIG_NET_ICMPv6_AUTOCONF */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void tcpblaster_initialize(void) +{ +#ifndef CONFIG_EXAMPLES_TCPBLASTER_IPv6 + struct in_addr addr; +#endif +#ifdef CONFIG_EXAMPLES_TCPBLASTER_NOMAC + uint8_t mac[IFHWADDRLEN]; +#endif + +/* Many embedded network interfaces must have a software assigned MAC */ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_NOMAC + mac[0] = 0x00; + mac[1] = 0xe0; + mac[2] = 0xde; + mac[3] = 0xad; + mac[4] = 0xbe; + mac[5] = 0xef; + netlib_setmacaddr(DEVNAME, mac); +#endif + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_IPv6 +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Perform ICMPv6 auto-configuration */ + + netlib_icmpv6_autoconfiguration(DEVNAME); + +#else /* CONFIG_NET_ICMPv6_AUTOCONF */ + + /* Set up our fixed host address */ + + netlib_set_ipv6addr(DEVNAME, + (FAR const struct in6_addr *)g_ipv6_hostaddr); + + /* Set up the default router address */ + + netlib_set_dripv6addr(DEVNAME, + (FAR const struct in6_addr *)g_ipv6_draddr); + + /* Setup the subnet mask */ + + netlib_set_ipv6netmask(DEVNAME, + (FAR const struct in6_addr *)g_ipv6_netmask); + + /* New versions of netlib_set_ipvXaddr will not bring the network up, + * So ensure the network is really up at this point. + */ + + netlib_ifup(DEVNAME); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ +#else /* CONFIG_EXAMPLES_TCPBLASTER_IPv6 */ + + /* Set up our host address */ + + addr.s_addr = HTONL(CONFIG_EXAMPLES_TCPBLASTER_IPADDR); + netlib_set_ipv4addr(DEVNAME, &addr); + + /* Set up the default router address */ + + addr.s_addr = HTONL(CONFIG_EXAMPLES_TCPBLASTER_DRIPADDR); + netlib_set_dripv4addr(DEVNAME, &addr); + + /* Setup the subnet mask */ + + addr.s_addr = HTONL(CONFIG_EXAMPLES_TCPBLASTER_NETMASK); + netlib_set_ipv4netmask(DEVNAME, &addr); + +#endif /* CONFIG_EXAMPLES_TCPBLASTER_IPv6 */ +} + +#endif /* CONFIG_EXAMPLES_TCPBLASTER_INIT */ diff --git a/examples/tcpblaster/tcpblaster_server.c b/examples/tcpblaster/tcpblaster_server.c new file mode 100644 index 000000000..8aee57ec0 --- /dev/null +++ b/examples/tcpblaster/tcpblaster_server.c @@ -0,0 +1,242 @@ +/**************************************************************************** + * examples/tcpblaster/tcpblaster-server.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "tcpblaster.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void tcpblaster_server(void) +{ +#ifdef CONFIG_EXAMPLES_TCPBLASTER_IPv6 + struct sockaddr_in6 myaddr; +#else + struct sockaddr_in myaddr; +#endif +#ifdef TCPBLASTER_HAVE_SOLINGER + struct linger ling; +#endif + struct timespec start; + unsigned long recvtotal; + socklen_t addrlen; + char *buffer; + int recvcount; + int listensd; + int acceptsd; + int nbytesread; + int optval; + + /* Allocate a BIG buffer */ + + buffer = (char*)malloc(SENDSIZE); + if (!buffer) + { + printf("server: failed to allocate buffer\n"); + exit(1); + } + + /* Create a new TCP socket */ + + listensd = socket(PF_INETX, SOCK_STREAM, 0); + if (listensd < 0) + { + printf("server: socket failure: %d\n", errno); + goto errout_with_buffer; + } + + /* Set socket to reuse address */ + + optval = 1; + if (setsockopt(listensd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof(int)) < 0) + { + printf("server: setsockopt SO_REUSEADDR failure: %d\n", errno); + goto errout_with_listensd; + } + + /* Bind the socket to a local address */ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_IPv6 + + myaddr.sin6_family = AF_INET6; + myaddr.sin6_port = HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVER_PORTNO); +#if defined(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK) && !defined(NET_LOOPBACK) + memcpy(myaddr.sin6_addr.s6_addr16, g_tcpblasterserver_ipv6, 8 * sizeof(uint16_t)); +#else + memset(myaddr.sin6_addr.s6_addr16, 0, 8 * sizeof(uint16_t)); +#endif + addrlen = sizeof(struct sockaddr_in6); + + printf("Binding to IPv6 Address: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + myaddr.sin6_addr.s6_addr16[0], myaddr.sin6_addr.s6_addr16[1], + myaddr.sin6_addr.s6_addr16[2], myaddr.sin6_addr.s6_addr16[3], + myaddr.sin6_addr.s6_addr16[4], myaddr.sin6_addr.s6_addr16[5], + myaddr.sin6_addr.s6_addr16[6], myaddr.sin6_addr.s6_addr16[7]); +#else + myaddr.sin_family = AF_INET; + myaddr.sin_port = HTONS(CONFIG_EXAMPLES_TCPBLASTER_SERVER_PORTNO); + +#if defined(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK) && !defined(NET_LOOPBACK) + myaddr.sin_addr.s_addr = (in_addr_t)g_tcpblasterserver_ipv4; +#else + myaddr.sin_addr.s_addr = INADDR_ANY; +#endif + addrlen = sizeof(struct sockaddr_in); + + printf("Binding to IPv4 Address: %08lx\n", + (unsigned long)myaddr.sin_addr.s_addr); +#endif + + if (bind(listensd, (struct sockaddr*)&myaddr, addrlen) < 0) + { + printf("server: bind failure: %d\n", errno); + goto errout_with_listensd; + } + + /* Listen for connections on the bound TCP socket */ + + if (listen(listensd, 5) < 0) + { + printf("server: listen failure %d\n", errno); + goto errout_with_listensd; + } + + /* Accept only one connection */ + + printf("server: Accepting connections on port %d\n", + CONFIG_EXAMPLES_TCPBLASTER_SERVER_PORTNO); + acceptsd = accept(listensd, (struct sockaddr*)&myaddr, &addrlen); + if (acceptsd < 0) + { + printf("server: accept failure: %d\n", errno); + goto errout_with_listensd; + } + + printf("server: Connection accepted -- receiving\n"); + + /* Configure to "linger" until all data is sent when the socket is closed */ + +#ifdef TCPBLASTER_HAVE_SOLINGER + ling.l_onoff = 1; + ling.l_linger = 30; /* timeout is seconds */ + + if (setsockopt(acceptsd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger)) < 0) + { + printf("server: setsockopt SO_LINGER failure: %d\n", errno); + goto errout_with_acceptsd; + } +#endif + + /* Then receive data forever */ + + recvcount = 0; + recvtotal = 0; + + for (; ; ) + { + nbytesread = recv(acceptsd, buffer, SENDSIZE, 0); + if (nbytesread < 0) + { + printf("server: recv failed: %d\n", errno); + goto errout_with_acceptsd; + } + else if (nbytesread == 0) + { + printf("server: The client broke the connection\n"); + goto errout_with_acceptsd; + } + + recvtotal += nbytesread; + + if (++recvcount >= 50) + { + struct timespec elapsed; + struct timespec curr; + float fkbsent; + float felapsed; + + (void)clock_gettime(CLOCK_REALTIME, &curr); + + elapsed.tv_sec = curr.tv_sec - start.tv_sec; + if (curr.tv_nsec >= start.tv_nsec) + { + elapsed.tv_nsec = curr.tv_nsec - start.tv_nsec; + } + else + { + unsigned long borrow = 1000000000 - start.tv_nsec; + elapsed.tv_nsec = curr.tv_nsec + borrow; + } + + fkbsent = (float)recvtotal / 1024.0; + felapsed = (float)elapsed.tv_sec + (float)elapsed.tv_nsec / 1000000000.0; + printf("Received %d packets: %7.1f Kb (avg %5.1f Kb) in %6.2f Sec (%7.1f Kbps)\n", + recvcount, fkbsent, fkbsent/recvcount, felapsed, fkbsent/felapsed); + + recvcount = 0; + recvtotal = 0; + + (void)clock_gettime(CLOCK_REALTIME, &start); + } + } + +errout_with_acceptsd: + close(acceptsd); + +errout_with_listensd: + close(listensd); + +errout_with_buffer: + free(buffer); + exit(1); +} diff --git a/examples/tcpblaster/tcpblaster_target1.c b/examples/tcpblaster/tcpblaster_target1.c new file mode 100644 index 000000000..098c4ecfb --- /dev/null +++ b/examples/tcpblaster/tcpblaster_target1.c @@ -0,0 +1,130 @@ +/**************************************************************************** + * examples/tcpblaster/tcpblaster_target1.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "tcpblaster.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK +static int server_child(int argc, char *argv[]) +{ + tcpblaster_server(); + return EXIT_SUCCESS; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * tcpblaster_main + ****************************************************************************/ + +#if defined(CONFIG_BUILD_KERNEL) +int main(int argc, FAR char *argv[]) +#elif defined(CONFIG_EXAMPLES_TCPBLASTER_TARGET2) +int tcpblaster1_main(int argc, char *argv[]) +#else +int tcpblaster_main(int argc, char *argv[]) +#endif +{ +#ifdef CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK + pid_t child; +#ifdef CONFIG_SCHED_WAITPID + int statloc; +#endif +#endif + + /* Parse any command line options */ + + tcpblaster_cmdline(argc, argv); + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_INIT + /* Initialize the network */ + + tcpblaster_initialize(); +#endif + +#if defined(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK) + /* Then perform the server side of the test on a child task */ + + child = task_create("TcpBlaster Child", CONFIG_EXAMPLES_TCPBLASTER_DAEMON_PRIORITY, + CONFIG_EXAMPLES_TCPBLASTER_DAEMON_STACKSIZE, server_child, + NULL); + if (child < 0) + { + fprintf(stderr, "ERROR: Failed to server daemon\n"); + return EXIT_FAILURE; + } + + usleep(500*1000); + +#elif defined(CONFIG_EXAMPLES_TCPBLASTER_SERVER) + /* Then perform the server side of the test on this thread */ + + tcpblaster_server(); +#endif + +#if !defined(CONFIG_EXAMPLES_TCPBLASTER_SERVER) || \ + defined(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK) + /* Then perform the client side of the test on this thread */ + + tcpblaster_client(); +#endif + +#if defined(CONFIG_EXAMPLES_TCPBLASTER_LOOPBACK) && defined(CONFIG_SCHED_WAITPID) + printf("main: Waiting for the server to exit\n"); + (void)waitpid(child, &statloc, 0); +#endif + + return EXIT_SUCCESS; +} diff --git a/examples/tcpblaster/tcpblaster_target2.c b/examples/tcpblaster/tcpblaster_target2.c new file mode 100644 index 000000000..4db4f66e8 --- /dev/null +++ b/examples/tcpblaster/tcpblaster_target2.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * examples/tcpblaster/tcpblaster_target2.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "config.h" +#include +#include "tcpblaster.h" + +/**************************************************************************** + * tcpblaster_main + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char *argv[]) +#else +int tcpblaster2_main(int argc, char *argv[]) +#endif +{ + /* Parse any command line options */ + + tcpblaster_cmdline(argc, argv); + +#ifdef CONFIG_EXAMPLES_TCPBLASTER_INIT + /* Initialize the network */ + + tcpblaster_initialize(); +#endif + +#if defined(CONFIG_EXAMPLES_TCPBLASTER_SERVER) + /* Then perform the client side of the test on this thread */ + + tcpblaster_client(); +#else + /* Then perform the server side of the test on this thread */ + + tcpblaster_server(); +#endif + + return EXIT_SUCCESS; +}