alfred: Use well defined structs to create packets

The current packets sent over the network or over the unix socket were only
defined in the code but not by any struct. This makes it hard to find the right
place in the code to change when working with the struct. It is also makes it
easy to accidently use the wrong position when reading or writing from/to the
buffer.

Structs are introduced to define the fixed entries of a packet. The struct also
defines the position of the dynamic part followed by it using zero-length
arrays.

Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
alfred: Add transaction management block to push_data

The transactions over the network should be secured using transactions based on
the packet count and transaction id. As first step each alfred_push_data packet
has to transport the current identifier of the transaction and the sequence
number of the current packet.

Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
alfred: Add transaction id to request packets

The request sent by a slave has to start a transaction. Otherwise it is not
possible to distinct for him the incoming data without an extra handshaking
protocol. The request packets get an extra field to store the requested
transaction identifier.

Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
alfred: Guarantee monotonic times

The times returned by time(..) and gettimeofday(...) are not monotonic and
therefore the time can jump backwards or forwards. This can happen during after
a settime system call or when the local timezone was changed.

Jumps forward are not problematic and only cause early processing of some
data/more data in the network, but warping back in time can result in hangs and
publishing of outdated data.

Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
alfred: Send a tx end packet after data was pushed

The transaction for a transfer must be checked before the receiver can move the
data to the own data hash. The basic check will use the amount of data
transferred. The sender uses a txend packet including the necessary
information.

Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
alfred: Import the linux kernel list implementation

Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
alfred: Only apply changes after txend status was received

A transaction has to be handled in a atomic way. Either the complete data was
received or it wasn't. The simplest method is to use a buffer to hold all
unconfirmed data instead of using a redo/undo log. All data in this transaction
buffer will be written after the transaction was confirmed or in case of an
failure just dropped.

Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
alfred: Report errors for request data back to client

The client must be able whether there was an error in requesting data or there
is just no data to return. The server will check whether the complete data was
returned and when not it will send an error status packet to the client.

Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
alfred: Only send txend when requested

The synchronization (master <-> master, local -> master) without data doesn't
require a txend because the remote would not have opened a transaction for it.
Therefore, sending a txend would only increase the network requirements.

Signed-off-by: Sven Eckelmann <sven@open-mesh.com>