 NetStrain 3.0
===============

NetStrain is a tool to measure practical data throughput between two
machines over a TCP connection. It can be used for performance
testing, stress/stability testing and to demonstrate various network
effects. It supports both IPv4 and IPv6, provided the underlying
system does.

NetStrain is also intended to demonstrate basic TCP socket programming
and IPv6 support. It includes an getaddrinfo() / getnameinfo()
emulation that can be reused in other programs.

NetStrain is written in C and is designed to compile on any modern
Unix flavour. It requires no special libraries.


 Supported Systems
-------------------

Some strain of Unix with reasonable sockets support is required. So
far, NetStrain has been tested on the following systems:

  Linux 2.2.x + glibc 2.1.x on x86, alpha, powerpc, sparc (Debian 2.2
    "potato")
  Linux 2.4.x + glibc 2.2.x on x86 (Debian 3.0 "woody", RedHat 7.3
    and SuSE 7.2)
  FreeBSD 4.6 on x86
  Darwin 5.x (a.k.a. Mac OS X 10.1.x) on powerpc
  SunOS 5.8 (a.k.a. Solaris 8) on sparc
    (Only worked with gcc and `make LIBS=-lsocket')
  IRIX64 6.5 on mips
  HP-UX 11.00 on hppa2.0

Of these, Linux, FreeBSD and Solaris supported IPv6 during the tests.


 Installation
--------------

Just run make. The net6emuconf shell script will be run to determine
if your system supports the IPv6 interfaces. GNU make is recommended,
but it appears that it's not strictly required. The Makefile and the
shell script both default to `gcc' as the compiler. If you don't have
GCC or want to use your vendor's compiler, set the CC variable
accordingly. You can also set the CPPFLAGS, CFLAGS, LDFLAGS and LIBS
variables if required. It is recommended to do this on the make
command line, like this:

  make CC=cc CFLAGS=-O2 LIBS=-lsocket

Compilation results in two binaries, netstrain and netstraind. Copy
these to a bin directory of your choice, optionally stripping them on
the way. That's all.


 Usage
-------

The system consists of two programs, the client and the server. Data
is sent between the two as fast as possible, either in both directions
simultaneously or in one specific direction. The client displays
running statistics while it runs.

The server must be started first. Its only command line argument is
the port number to listen on. The server starts listening on that
TCP port until it receives a connect. For security and simplicity
reasons, the server only accepts one connect and terminates after the
client disconnects.

The client is started with the host name and port to connect to and a
third parameter giving the direction(s) in which data should be
sent. It then connects to the server using the given data and signals
the direction mode.

Both programs send and receive data until they are interrupted (Ctrl-C
or any other signal) or until the remote side closes the connection.

An example session, first the server:

  pippin:~/coding/netstrain> ./netstraind 7777
  NetStrain 3.0  (c) 2002 Christoph Pfisterer <cp@chrisp.de>
  Listening on :: port 7777 using IPv6...
  netstraind: socket: Address family not supported by protocol
  Listening on 0.0.0.0 port 7777 using IPv4...
  One-shot server waiting for connection
  Incoming connection from 192.168.2.30 port 51871
  Got EOF from socket, shutting down
  pippin:~/coding/netstrain> 

Now, the client side for the same connection:

  frodo:~/coding/netstrain> ./netstrain pippin 7777 send
  NetStrain 3.0  (c) 2002 Christoph Pfisterer <cp@chrisp.de>
  Looking up hostname pippin...
  Connecting to 192.168.2.3 port 7777 using IPv4...
  Connected
  sent:     61586K,    6837.7K/s total,    6853.5K/s current
  recv'd:       0B,         0B/s total,         0B/s current
  ^C
  frodo:~/coding/netstrain> 

Some explanations: pippin is a Linux box, so it has IPv6 interfaces in
the C library, but the running kernel doesn't support IPv6, so the
server falls back to IPv4. frodo runs Mac OS X 10.1, so it only
supports IPv4 (and pippin only has an IPv4 address in DNS). Between
the two is a 100 MBit Ethernet LAN with a non-switched hub (and some
other machines), yielding a typical 6-8 MB/sec figure.


 IPv6 Support
--------------

NetStrain tries to support IPv6 where possible. For this, it requires
the new protocol-agnostic functions getaddrinfo() and getnameinfo() to
do address lookups and conversions. On systems where these are not yet
available, they are emulated using inet_aton(), gethostbyname(),
inet_ntoa() and gethostbyaddr(). The code to do this was adopted from
portable OpenSSH and is factored out into the net6emu* files. Feel
free to reuse it in your own programs.

getaddrinfo() allows the program to specify a protocol to use or to
leave it unspecified. By default, NetStrain leaves the protocol
unspecified, which usually causes IPv6 to be used when it is
available. If desired, the `-4' and `-6' command line options can be
used to force a specific protocol. (They work for both the client and
the server.)

For the curious, here's a transcript from an IPv6-enabled box
accepting an IPv4 connection:

  chrisp@merry:~/netstrain$ ./netstraind 7777
  NetStrain 3.0  (c) 2002 Christoph Pfisterer <cp@chrisp.de>
  Listening on :: port 7777 using IPv6...
  One-shot server waiting for connection
  Incoming connection from ::ffff:192.168.2.30 port 51877
  Got EOF from socket, shutting down

And another one using true IPv6:

  chrisp@merry:~/netstrain$ ./netstraind 7777
  NetStrain 3.0  (c) 2002 Christoph Pfisterer <cp@chrisp.de>
  Listening on :: port 7777 using IPv6...
  One-shot server waiting for connection
  Incoming connection from 3ffe:b80:dfa:1:210:5aff:fe64:79a2 port 1026
  Got EOF from socket, shutting down


 Other Mumblings
-----------------

I'd like to thank:

  The OpenSSH people (http://www.openssh.com), the Curl people
  (http://curl.haxx.se), and many others for making their work
  available as Open Source and thus allowing others to learn from it.

  The Freenet6 people (http://www.freenet6.net) for providing painless
  and free IPv6 connectivity.

  The Department of Computer Science at the Univerity of Stuttgart,
  Germany (http://www.informatik.uni-stuttgart.de) for providing a
  richly flavoured, diverse, heterogeneous Unix population for a quick
  portability test. ;-)

  SourceForge (http://sourceforge.net) for providing not just hosting,
  but also a compile farm with diverse architectures and operating
  systems.


EOF
