mirror of https://github.com/deavmi/twine
Compare commits
3 Commits
a3fc8b4f5e
...
0089ce4b0d
Author | SHA1 | Date |
---|---|---|
Tristan B. Velloza Kildaire | 0089ce4b0d | |
Tristan B. Velloza Kildaire | 9cfebdbefe | |
Tristan B. Velloza Kildaire | 64cb1f7d2d |
106
doc/router.md
106
doc/router.md
|
@ -113,4 +113,108 @@ public struct Route
|
|||
}
|
||||
```
|
||||
|
||||
##
|
||||
## The router
|
||||
|
||||
The `Router` class is the main component of the twine system. Everything such as `Link` objects and so forth make a part of the
|
||||
router's way or working. The router performs several core tasks which include:
|
||||
|
||||
1. Maintaining the routing table
|
||||
* This means we advertise all routes present in the routing table to other routers over the available links
|
||||
* It also means checking the routing table every _now and then_ for routes which ought to be expired
|
||||
* Receiving advertised routes from other nodes and checking if they should be installed into the table
|
||||
2. Traffic management
|
||||
* Support for installing a message handler which will run whenever traffic detained to you arrives
|
||||
* Forwarding traffic on behalf of others; to its final destination
|
||||
* Allowing the sending of traffic to other nodes
|
||||
|
||||
### The routing table
|
||||
|
||||
The routing table is at the heart of handling egress and forward-intended traffic. It relatively simple as well,
|
||||
infact this is the routing table itself:
|
||||
|
||||
```{.d}
|
||||
// routing tables
|
||||
private Route[string] routes;
|
||||
private Mutex routesLock;
|
||||
```
|
||||
|
||||
There are then several methods which manipulate this routing table by locking it, performing some action and then
|
||||
releasing said lock:
|
||||
|
||||
| Method | Description |
|
||||
|-----------------------------------------|------------------------------------------------------------------|
|
||||
| `Optional!(Route) findRoute(string)` | Given the destination network-layer address this returns an `Optional` potentially containing the found `Route` |
|
||||
| `installRoute(Route route)` | Checks if the given route should be installed and, if so, installs it. |
|
||||
| `dumpRoutes()` | This is a debugging method which prints out the routing table in ASCII form |
|
||||
|
||||
#### Installing of routes
|
||||
|
||||
Let's take a closer look at `installRoute(Route route)` because I would like to explain the logic that is used
|
||||
to determine whether or not a given route, received from an advertisement, is installed into the routing table
|
||||
or not.
|
||||
|
||||
```{.numberLines .d}
|
||||
private void installRoute(Route route)
|
||||
{
|
||||
this.routesLock.lock();
|
||||
|
||||
scope(exit)
|
||||
{
|
||||
this.routesLock.unlock();
|
||||
}
|
||||
|
||||
Route* cr = route.destination() in this.routes;
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Firstly as you have seen we lock the routing table mutex to make sure we don't get any inconsistent changes
|
||||
to the routing table during usage (remember that we will be modifying it and others could be doing so as
|
||||
well). We then also set a `scope(exit)` statement which means that upon any exiting of this level of scope
|
||||
we will unlock the mutex. Lastly we then get a pointer to the `Route` in the table at the given key. Remember
|
||||
the routing table was a `Route[string]` which means the `string`, _the key_, is the destination address
|
||||
of the incoming route in this case. The _value_ would be the found `Route*` if any.
|
||||
|
||||
```{.numberLines .d}
|
||||
...
|
||||
|
||||
// if no such route installs, go ahead and install it
|
||||
if(cr is null)
|
||||
{
|
||||
this.routes[route.destination()] = route;
|
||||
}
|
||||
```
|
||||
|
||||
As you can see above we first check if the pointer was `null`, which indicates no route to said destination
|
||||
existed. Therefore we will then install the incoming route at that destination.
|
||||
|
||||
```{.numberLines .d}
|
||||
...
|
||||
|
||||
// if such a route exists, then only install it if it
|
||||
// has a smaller distance than the current route
|
||||
else
|
||||
{
|
||||
if(route.distance() < (*cr).distance())
|
||||
{
|
||||
this.routes[route.destination()] = route;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if matched route is the same as incoming route
|
||||
// then simply refresh the current one
|
||||
if(*cr == route)
|
||||
{
|
||||
cr.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
However, if a route did exist then we need to check some things before we install it. Namely, we only install
|
||||
the route if the predicate of $d(r_{incoming}) < d(r_{current})$ where $d(r_i)$ is the distance metric of a given
|
||||
route $r_i$. If this is _not_ the case then we do not install the route. However, we do do a check to see if
|
||||
the incoming route is identical (must have been the same router advertising a route we received from it earlier)
|
||||
then we simply refresh it (reset its timer) instead of storing it again, if that is not the case we don't change
|
||||
anything.
|
BIN
doc/texput.pdf
BIN
doc/texput.pdf
Binary file not shown.
Loading…
Reference in New Issue