Compare commits

...

5 Commits

Author SHA1 Message Date
Tristan B. Velloza Kildaire 508226d9f9 Docs
- Updated section for routeing
2024-01-28 16:06:26 +02:00
Tristan B. Velloza Kildaire b07fec978f Router
- Fixed `routeSweep()` to not expire self-routes
2024-01-28 16:03:23 +02:00
Tristan B. Velloza Kildaire e55468712c Message
- Documented two fields
- Documented `encode(Message mIn)` and `encode()`
- Fixed `decode(byte[] dataIn, ref Message decoded)` such that it won't crash on bad decode
2024-01-28 15:52:17 +02:00
Tristan B. Velloza Kildaire b10c938482 Docs
- Moved
- Updated PDF
2024-01-28 14:34:43 +02:00
Tristan B. Velloza Kildaire 30b4b65a18 MType
- Documented enum
2024-01-28 14:33:52 +02:00
7 changed files with 151 additions and 7 deletions

60
doc/00-encoding.md Normal file
View File

@ -0,0 +1,60 @@
Encoding
========
The encoding and decoding for the twine protocol messages is accomplished via the **MessagePack**
format. This is a format of which allows one to encode data structures into a byte stream and
send them over the wire. It is a _format_ because it is standardized - meaning all languages
which have a message pack library can decode twine messages if they re-implement the simple
routines for the various messages - _all the hard work is accomplished by the underlying message pack
library used_.
## The `Message` type
TODO: Add this
### Message types
The type of a message is the first field which one will consider.
We store this as an enum value called `MType`, it is defined below:
```{.numberLines .d}
/**
* Message type
*/
public enum MType
{
/**
* An unknown type
*
* Used for developer
* safety as this would
* be the value for
* `MType.init` and hence
* implies you haven't
* set the `Message`'s
* type field
*/
UNKNOWN,
/**
* A route advertisement
* message
*/
ADV,
/**
* Unicast data
* packet
*/
DATA,
/**
* An ARP request
* or reply
*/
ARP
}
```
It is this type which will aid us in decoding the `byte[] payload`
field with the intended interpretation.

View File

@ -271,9 +271,43 @@ Link[] selected = getLinkMan().getLinks();
logger.info("Advertising to ", selected.length, " many links");
```
As we can see above we sweep the routing table firstly by a call to `routeSweep()`.
---
We also see how we are eneumerating all `Link`(s) which are attached to the router
As we can see above we sweep the routing table firstly by a call to `routeSweep()`,
this is implemented as follows:
```{.numberLines .d}
this.routesLock.lock();
scope(exit)
{
this.routesLock.unlock();
}
foreach(string destination; this.routes.keys())
{
Route cro = this.routes[destination];
// if it has expired and is not a self-route (never expire it)
if(cro.hasExpired() && !cro.isSelfRoute())
{
this.routes.remove(destination);
logger.warn("Expired route '", cro, "'");
}
}
```
It is relatively simple, lock the table check all which have expired, and
if they have then remove them from the table. Finalizing by unlocking the
table's lock.
**Note**: We check `!cro.isSelfRoute()` because we don't want to expire our
self-route, else if we do it we will cease to advertise our prescenece
to neighboring routers after the initial sweep after starting the router.
---
We also see how we are enumerating all `Link`(s) which are attached to the router
(via its `LinkManager` (returned by `getLinkMan()`)). We would like to advertise all
the routes in our table over all of these links.
@ -307,7 +341,7 @@ foreach(Route route; getRoutes())
The advertising of routes works as follows. Given a route $r_i$ in our routing table,
we construct a new route, $r_i_{out}$ of which has all the attributes of the current
route's ($r_i$'s) attributes **however** we update the `via` (or _gateway_) of $r_i_{out}$
to be that of our public key. Only _then_ do we send out the advertisment over the `Link`
to be that of our public key. Only _then_ do we send out the advertisement over the `Link`
in the form of a broadcast.
### Handling of ingress traffic

Binary file not shown.

View File

@ -706,7 +706,8 @@ public class Router : Receiver
{
Route cro = this.routes[destination];
if(cro.hasExpired())
// if it has expired and is not a self-route (never expire it)
if(cro.hasExpired() && !cro.isSelfRoute())
{
this.routes.remove(destination);
logger.warn("Expired route '", cro, "'");

View File

@ -7,39 +7,88 @@ module twine.core.wire;
import msgpack;
/**
* Message type
*/
public enum MType
{
/**
* An unknown type
*
* Used for developer
* safety as this would
* be the value for
* `MType.init` and hence
* implies you haven't
* set the `Message`'s
* type field
*/
UNKNOWN,
/**
* A route advertisement
* message
*/
ADV,
/**
* Unicast data
* packet
*/
DATA,
/**
* An ARP request
* or reply
*/
ARP
}
public struct Message
{
/**
* The type of message (how to
* interpret the payload)
*/
private MType mType;
/**
* The payload itself
*/
private byte[] payload;
/**
* Encodes the given `Message`
* into a byte stream
*
* Params:
* mIn = the message to
* encode
* Returns: encoded bytes
*/
public static byte[] encode(Message mIn)
{
return cast(byte[])pack(mIn);
}
/**
* Encodes this `Message`
*
* Returns: encoded bytes
*/
public byte[] encode()
{
return encode(this);
}
// fixme, if the dataIn is not even in msgpack form it fails WITHOUT exception (dangerous, submit to github as an issue)
public static bool decode(byte[] dataIn, ref Message decoded)
{
// todo, decode properly
try
{
decoded = unpack!(Message)(cast(ubyte[])dataIn);
return true;
}
catch(UnpackException u)
catch(MessagePackException u)
{
return false;
}