SPDX-License-Identifier: GPL-3.0-only
SPDX-FileCopyrightText: Copyright Logan oos Even
SPDX-FileCopyrightText: Copyright Hamish Coleman

# Configuration at Build time

There are a number of configuration options that are made only at build time.

In order to assist with cross compilation, minimising test cases, repeatable
builds and minimising externalities, the build options are generally defaulted
to off.

As part of simplifying cross compilation, the use of auto-detected
configuration settings are being removed.

## Options

After changing any configuration, please do no forget to `make clean` after
the (re-)configuration and before building (again) using `make`.

### `--with-zstd`

ZSTD Compression Support

In addition to the built-in LZO1x for payload compression (using the
`community.compression=lzo` option), n3n optionally supports
[ZSTD](https://github.com/facebook/zstd).  As of 2020, it is considered cutting
edge and [praised](https://en.wikipedia.org/wiki/Zstandard) for reaching the
currently technologically possible Pareto frontier in terms of CPU power versus
compression ratio.

#### Makefile

ZSTD support can be configured using

`./configure --with-zstd`

which then will include ZSTD. It will be available via the
`community.compression=zstd` option on the edges.
Of course, it can be combined with the other optimisation features:

`./configure --with-zstd --with-openssl CFLAGS="-O3 -march=native"`

Again, and this needs to be reiterated sufficiently often, please do no forget to `make clean` after (re-)configuration and before building (again) using `make`.

### `--with-openssl`

Use openssl instead of the built-in AES code

The speed of some ciphers' can take advantage of OpenSSL support This is
disabled by default as the built-in ciphers already prove reasonably fast
in most cases.

When enabled, this will include OpenSSL 1.1. This can also be combined with
the hardware support and compiler optimizations such as.

`./configure --with-openssl CFLAGS="-O3 -march=native"`

To activate, add `--with-openssl` to the `configure` command

Note that compiling with openssl may violate the licensing as the OpenSSL
library contains GPL-incompatible terms and the owners of the copyright of
the parts of this software that would link against openssl have not issued
any exceptions for this use case.  This depends on the exact versions in
use of all the libraries concerned.

### `--enable-pthread`

Enable threading using the pthread library

### `--enable-cap`

Use the libcap to provide reduction of the security privileges needed in the
running daemon

### `--enable-pcap`

If the pcap library is available then the `n3n-decode` tool can be compiled.

### `--enable-natpmp`

One of the two UPnP libraries, this one supports the NATPMP protocol.
See also the next option.

This option depends on the library being installed - on Debian and Ubuntu,
this is `apt-get install libnatpmp-dev`

Note that compiling with this library may add additional requirements to
advertising and packaging in order to meet the licensing specified by it.
You should be sure to read the libraries own license file and take steps
to be in compliance before distributing such a build.

### `--enable-miniupnp`

Enables the other kind of UPnP port mapping protocol.

Turning on either of these two UPnP libraries will enable UPnP support within
the n3n-portfwd tool.

This option depends on the library being installed - on Debian and Ubuntu,
this is `apt-get install libminiupnpc-dev`

Note that compiling with this library may add additional requirements to
advertising and packaging in order to meet the licensing specified by it.
You should be sure to read the libraries own license file and take steps
to be in compliance before distributing such a build.

### Disable Multicast Local Peer Detection

For better local peer detection, the edges try to detect local peers by sending REGISTER
packets to a certain multicast address. Also, edges listen to this address to eventually
fetch such packets.

If these packets disturb network's peace or even get forwarded by (other) edges through the
n3n network, this behavior can be disabled

#### Makefile

Add
`-DSKIP_MULTICAST_PEERS_DISCOVERY`

to your `CFLAGS` when configuring, e.g.

`./configure --with-zstd CFLAGS="-O3 -march=native -DSKIP_MULTICAST_PEERS_DISCOVERY"`

### Deprecation of --with options

Due to historical reasons, the autoconf system does not validate the syntax
of any `--with-X` style options, thus to provide the highest confidence in
the correctness of configuration and compilation, `--enable-X` style options
are preferred.  As part of this, the older `--with-X` options will eventually
be migrated to use `--enable-X`

# Optimisation options

## Compiler Optimizations

The easiest way to boosting speed is by allowing the compiler to apply
optimization to the code. To let the compiler know, the configuration process
can take in the optionally specified compiler flag `-O3`:

`./configure CFLAGS="-O3"`

The `n3n-edge test benchmark` tool can be used before and after to measure the
speed-ups (some code paths will speed up by over 200%!) There is no known risk
in terms of unstable code or so.

## Hardware Features

Some parts of the code significantly benefit from compiler optimizations (`-O3`) and platform features
such as NEON, SSE and AVX. It needs to be decided at compile-time. Hence if compiling for a specific
platform with known features (maybe the local one), it should be specified to the compiler – for
example through the `-march=sandybridge` (you name it) or just `-march=native` for local use.

So far, the following portions of n3n's code benefit from hardware features:

```
AES:               AES-NI
ChaCha20:          SSE2, SSSE3
SPECK:             SSE2, SSSE3, AVX2, AVX512, (NEON)
Random Numbers:    RDSEED, RDRND (not faster but more random seed)
```

The compilations flags could easily be combined:

`./configure CFLAGS="-O3 -march=native"`.

## SPECK – ARM NEON Hardware Acceleration

By default, SPECK does not take advantage of ARM NEON hardware acceleration even if compiled with `-march=native`. The reason is that the NEON implementation proved to be slower than the 64-bit scalar code on Raspberry Pi 3B+, see [here](https://github.com/ntop/n2n/issues/563).

Your specific ARM mileage may vary, so it can be enabled by configuring the definition of the `SPECK_ARM_NEON` macro:

`./configure CFLAGS="-DSPECK_ARM_NEON"`

Just make sure that the correct architecture is set, too. `-march=native` usually works quite well.
