TARP is a holistic scheme whose objective is to pass packets over multiple hops in a wireless network. In the literal interpretation of ad hoc and holisticism, the scheme does not belong to any particular layer; it is simply “all there is”. Or, to fit within the terminology of recent decades networking literature, it would be considered an extreme case of a cross-layer protocol.
4.1. The Forwarding Paradigm
The classical formulation of the forwarding problem is this: given a packet received by a node, tell the identity of the node’s neighbor to which the packet should be passed on its way towards the destination. This formulation is natural and works well where the neighborhoods are sharp and stable, as in most wired networks. It naturally lends itself to layering by isolating the problem of hop-to-hop forwarding from end-to-end communication. Solving the end-to-end communication problem amounts then to computing and maintaining routes [
37].
Owing to the multitude of simultaneous and conflicting criteria and constraints (energy [
38], scalability [
39], quality of service [
40], and mobility [
41]), it is impossible to discuss in this paper even the most important representatives of the various techniques proposed in the academic literature (see [
42] for an overview most pertinent to the context of WSNs). The two unifying features of all those schemes are: (1) routes understood as explicit paths in the network, and (2) data-link-layer encapsulation, i.e., a packet sent on every hop is data-link addressed to a specific neighbor of the forwarding node. Even if, in an acknowledgment of the fuzziness of paths in the unkempt environment of WSNs, some routing schemes attempt to provide multiple, alternative routes [
43], the “route” concept (and the consequent data-link encapsulation) is always there.
TARP embodies a departure from the route view and is based on the following assumptions and observations:
Wireless communication, especially in WSNs deployed in the field and/or admitting node mobility or node failures, is inherently flaky. The reliability of a multi-hop transmission over a non-trivial number of links is the product of the reliability of all the individual hops, so it scales poorly [
44].
In the massive collaborative system of a WSN, a node should be able to contribute to the joint effort of the whole network in proportion to its opportunities and abilities. Within the “path-routing” paradigm, a node can either contribute to a path fully or not at all.
The network is low-bandwidth and deals with short data packets. Complicated schemes intended to isolate data-link transfers and prevent collisions among simultaneous transmissions in the neighborhood are not effective in this type of surrounding.
The fact that a packet is “accidentally” overheard by a neighbor of the transmitting node, for which it is not “officially” intended, is not a flaw but a feature that should be embraced by the forwarding scheme.
Redundancy in forwarding a packet, understood as involving more nodes in this task than absolutely necessary, is in fact
absolutely needed to make sense of multi-hop communication in a WSN (see
Section 5.4).
At the level of a single hop, a packet in TARP is always broadcast (re-cast) to all neighbors of the forwarding node. Every node picking up a packet tries to find a reason not to forward the packet. An uninformed node may fail to find one, so it will act overly altruistically, its retransmissions being excessive and unnecessary. This may happen when the node has just joined the network, has moved, or has run out of memory to store the requisite information. Contrast this with the behavior of a similar node operating in the strict fixed-path forwarding regime. Until the problem is detected, diagnosed, and rectified, such a node will be completely useless as a forwarder.
4.3. The Cleaning Rules
Suppose that all we need is a simple mechanism to disseminate information among all nodes in a WSN. We can insert into the chain a single rule that passes every incoming packet to the application and fails. This way, every packet overheard by the node will be received and also forwarded to all nodes in the neighborhood. To prevent infinite flooding, we introduce a field in the packet’s (formal) header, denoted , storing the number of hops experienced by the packet, and impose a limit on that number. is set to 1 on the packet’s originating transmission and incremented by 1 on every retransmission. In contrast to the traditional approach, where such a counter (usually denoted by TTL, for time to live) is decremented on every hop towards zero, we prefer it to reflect the number of hops made so far. The rule may look similar to this:
RuleLHC | (limit hop count): |
| if (packet. MAX_HOPS) { |
| packet. ++; |
| receive (packet); |
| return FAIL; |
| } else { |
| return SUCCEED; |
| } |
Suppose now that we would like to extend the scheme to implement an efficient exchange of packets between identifiable pairs of nodes. As the first step of bringing it closer to a practical solution, we introduce three more fields into the packet header: two node addresses (source and destination, labeled S and D, respectively) and the packet’s sequence number (labeled Q). Consecutive packets sent by the same source have their Q values incremented by 1 modulo the counter’s range. It makes sense to encapsulate packet reception into a separate rule:
RuleRCV | (pass the packet to the application): |
| if (packet.D == my_address packet.D == 0) { |
| receive (packet); |
| } |
| return packet.D == my_address ? SUCCEED: FAIL; |
It accounts for broadcast packets assuming that the special destination address 0 identifies packets that should be received by all nodes. Note that such packets are not removed after the reception: their fate will be decided by the remaining rules in the chain.
The subsequent rules reduce the redundancy of flooding. This one tries to make sure that a given packet is forwarded at most once:
RuleDD | (duplicate discard): |
| signature = concat (packet.S, packet.Q); |
| if (DD_cache.present (signature) { |
| return SUCCEED; |
| } else { |
| DD_cache.add (signature); |
| return FAIL; |
| } |
The rule consults a cache of packet signatures composed by concatenating the packet’s source address S with its serial number Q. If the signature of a received packet is present in the cache, the rule succeeds causing the packet to be ignored. Otherwise, the new signature is added to the cache and the rule fails.
In a rule-based forwarding paradigm, the location of a specific rule in the chain may be flexible or it may be constrained by the locations of other (interdependent) rules. Note that LHC and RCV amount to the minimum sequence of rules in a workable network. Without LHC, the network would just flood indefinitely (chocking itself up), and without RCV, the nodes would not be able to receive. By putting LHC in front of RCV we assume that stray packets are an obvious nuisance and they should be discarded first. By the same token, it makes sense to insert the (more subtle) DD rule after LHC but before RCV to reduce the likelihood of bothering the application with multiple copies of the same packet. Hence, the recommended ordering of the three rules presented so far is: LHC, DD, RCV.
Entries in the DD cache age out after some time to account for the finite range of Q. They will also tend to be pushed out by fresh entries being added to the cache (according to the FIFO policy), because the amount of memory designated for the cache is limited. Note that when the node runs out of cache memory, the scheme will fail gracefully, by letting through some packet duplicates. The node will become more helpful than it should be, but the impact of this degradation on the quality of end-to-end communication need not be detrimental, and it can even be beneficial, if the cache parameters are set right. Note that, owing to the failure-prone nature of DD, the rule does not render LHC irrelevant: needing no local resources, the latter rule is always reliable. The reader should note that until this point, the benefits from TARP come from the comingling, at a local node level, operations that would have been performed at the data link and the network layer in traditional networks. Next, we show how the TARP rules can be used to balance, in a continuously dynamic manner, routing efficiency with reliability.
4.4. The SPD Rule
We now consider the operation of directing a packet towards its destination. The introduced TARP rule is dubbed SPD for Suboptimal Path Discard.
Imagine node
K picking up a packet sent by node
S and addressed to node
D, as illustrated in
Figure 2. According to
Section 4.3, the packet identifies the source
S, the destination
D, and the number of hops
taken by the packet so far.
K sets
and stores the pair <
> in a cache. The node has learned that it can be reached by
S in
hops. Owing to the
DD rule, operating before
SPD,
tends to reflect the smallest number of hops via which
K can be reached from
S at the time. Similarly, when
K sees a packet dispatched by node
D it will store in the
SPD cache the respective pair <
>. Note that only the packet’s source matters for updating the
SPD cache.
One more field in the packet header,
, is set by the packet’s originating node to the backward hop count, i.e., the last seen number of hops from the destination to the source. If the value is unknown (no relevant entry is available in the cache), the source will apply a large setting exceeding any legitimate number of hops, e.g.,
MAX_HOPS used by the
LHC rule (
Section 4.3).
Suppose that
K wants to decide whether it should re-cast (forward) a packet on its way from
S to
D. The node calculates
and compares
with
extracted from the packet’s header. If
is larger than
, the node has grounds to suspect that there is a better route for the packet than a path passing through
K. This is because the estimated number of hops separating
S and
D is
, but when forwarded by
K the packet is expected to make
hops. If the information cached by the nodes were reliable and accurate, the rule might simply decide to succeed (thus dropping the packet) when
and fail otherwise. This way packets would be forwarded along the shortest paths, although in a fuzzy manner, exploring multiple, alternative options. The redundancy of those alternatives can be adjusted with the
slack parameter, denoted by
A, interpreted as the acceptable excess of the path length over the estimated minimum. The rule succeeds if:
and fails otherwise. This admits multiple fuzzy paths up to
A hops longer than the currently estimated minimum.
The rule includes a relaxation mechanism to prevent lockouts caused by stale data. The mechanism is controlled by a parameter, denoted by
C, representing the number of successful applications of any given cache entry (resulting in dropping the packet) after which the rule should be gradually relaxed. To this end, every cache entry includes a counter incremented on every success of the rule triggered by that entry. The value of that counter is divided by
C, and the result is added to the right-hand side of Inequality (
1) together with the slack
A. The effect is to locally bump the slack by 1 every
C successes of the rule. When
, the relaxation mechanism is disabled. The complete rule looks similar to this:
RuleSPD | (suboptimal path discard): |
| SPD_cache.add (packet.S, packet.); |
| ce = SPD_cache.get (packet.D); |
| if (ce != NULL) { |
| R = (C == 0) ? 0: ce.SCount / C; |
| if (packet. packet.) { |
| ce.SCount++; |
| return SUCCEED; |
| } |
| } |
| return FAIL; |
The counter (SCount) is initialized to zero when the cache entry is created or updated.
Note that SPD should follow RCV in the rule chain. This is because before being submitted to SPD the packet has been classified as a bona-fide original packet receivable by the node (based on LHC and DD), and the remaining issue is its retransmission.
The number of entries stored in the
SPD cache will depend on the number of different sources in the packets overheard by the node. While this may be reminiscent of routing tables used by fixed-path forwarding schemes, such as AODV [
46], one should note two contrasting features. First, the cache only stores one simple entry per (overheard) source (the size of this entry is eight bytes in the implementation) and does not have to deal with the node’s neighbors. Second, what is considerably more important, a node that runs out of memory for its
SPD cache is not going to break the connectivity of TARP’s fuzzy paths. Similar to the
DD rule, the node will then err on the side of overzealous forwarding, rather then refusing to forward, what would unavoidably happen in a fixed-path scheme.
Figure 3 illustrates the operation
SPD in collaboration with
DD. If
, then the exchange between
S and
D will be sustained through nodes
and
. Although
is overhearing the packets transmitted by
S and retransmitted by
, it will find that the best path passing through it amounts to four hops, while the current shortest path length indicated in the
field of those packets is three hops. If
A is set to 1, the path leading through
,
, and
will become active. In particular,
D will be receiving packets both from
and
, rejecting those arriving from
as duplicates. If the shorter path fails (a packet that should arrive from
does not materialize at
D), its would-be duplicate reaching
D from
will not be rejected, so the secondary path will take over seamlessly.
Note that addressing only applies at the end-to-end (network) level; in particular, an internal node that never originates or absorbs traffic, needs no address. It can still receive broadcast packets, or overheard ones addressed to other nodes, if they fulfill its reception criteria. This makes the TARP idea somewhat reminiscent of pipelined forwarding schemes [
47,
48], intended for single-sink networks, where the forwarding decisions are based on the node’s
grade related to its hop distance from the destination (sink). Another feature making those schemes similar to TARP is the amalgamation of the MAC layer into forwarding. Two important differences are: (1) the explicit notion of the number of hops separating a node from the destination used for partitioning the set of nodes into disjoint sets (interpreted as a static parameter); (2) the RTS-CTS isolation applied by those schemes at forwarding steps.
4.5. Enhancements
As the nodes overhear packets traveling in the neighborhood, they fill their caches, which helps them avoid unnecessary forwarding. The notable feature of the scheme is that lack of knowledge is not fatal, and the default behavior of an uninformed node is altruistic. One may raise three concerns against this approach:
There is no isolation of the next-hop recipient, and every transmitted packet is essentially broadcast to all neighbors. This precludes collision avoidance schemes based on handshakes and may lead to broadcast storms [
49], especially when the nodes are uninformed.
It is not clear how much the flooding can be contained via heuristic rules that never attempt to construct precise, hop-by-hop routes. Is it possible at all to keep the redundancy at a level comparable to single-path forwarding?
As a consequence of point 1, it seems that the only way to increase the reliability of forwarding is to involve more nodes (and network resources) into the process. With explicit forwarding to a specific next-hop-neighbor, the two nodes can resort to acknowledgments to improve the reliability of communication. This approach seems to be out of reach of the present scheme.
In the following paragraphs, we incrementally address the above concerns. First, to curtail the negative connotations of flooding, let us note that all forwarding protocols, including those that insist on rigid paths, have to deal with the lack of information at the nodes that otherwise might be able to help. Thus, at some stages, they all resort to flooding, if only to discover the neighborhoods and construct the explicit routes [
50]. Put differently, flooding in the context of an uninformed node is no less natural to a scheme based on explicit paths than it is to TARP. In TARP, however, the node’s transition from uninformed to knowledgeable is never sharp and it triggers no fundamental mode change in the node’s behavior.
In answer to concern (1), it has been observed that RTS/CTS handshakes tend to be worthless and harmful when data packets are short [
51,
52,
53]. In a mesh network, the incurred false blocking on exposed terminals is additionally pernicious [
54]. WSNs built around TARP employ simple collision avoidance schemes based on LBT (listen before talk) and randomized backoff which work more than adequately for their niche applications [
55].
With respect to concern (2), formally, the
SPD rule can be tweaked to closely approach shortest-path forwarding. In particular, when
, packets tend to be forwarded in such a way that the number of hops traveled by them is the minimum feasible under the circumstances, where “feasible” means “based on the quickest, demonstrated way to deliver a packet from the opposite end.” Nonetheless, in some configurations of the mesh, this may incur multiple, simultaneous, alternative paths of the same length involving more nodes than (apparently) necessary. For illustration, in the scenario depicted in
Figure 4, the paths
,
,
,
,
and
,
,
,
,
offer the same minimum number of hops between
S and
D, possibly including “cross-hops” such as
and so on. Then, in accordance with the
SPD rule, all the nodes on the two paths will be forwarding packets between
S and
D (because the rule will always fail at each of them). As soon as the paths cross, the duplicates will be eliminated by
DD, but one may object to the replication of labor along
,
,
and
,
,
. While this redundancy lies beyond the scope of
SPD, it can be controlled with a simple mechanism. For that, we add a single-bit flag into the packet header, labeled
O (for optimal path). The flag is set by
SPD whenever the rule fails on Inequality (
1), i.e., based on the information available in the cache,
and when it would also fail if
A were equal zero (note that if
SPD fails for
, then it would also fail for
). In plain words, it means that the rule believes the packet is being forwarded on a path with the minimum feasible number of hops.
Suppose two “parallel” nodes in
Figure 4, say
and
, decide to forward the same packet. This means that the
SPD rule has failed in both cases, the setting of
in both copies of the packet is identical, the
O flag in both copies is set. The copies materialize at the two forwarders practically at the same time, the nodes queue their packets for transmission, and the LBT mechanism kicks in along with the randomized backoff. One of the two nodes, say
wins, the other one,
, waits for the backoff timer with its copy of the packet queued for transmission. When
overhears the copy transmitted by
, it will remove its scheduled copy from the transmit queue. The operation can be implemented as a rule preceding
DD and looking similar to this:
RuleSPP | (suppress parallel paths): |
| if (packet.O) { |
| pkt = find_in_xmit_queue (packet.S, packet.Q); |
| if (pkt != NULL) { |
| discard (pkt); |
| return SUCCEED; |
| } |
| } |
| return FAIL; |
The reason why the rule must precede
DD is that the packet (based on its signature, see
Section 4.3) has been already received by the node, so
DD is likely to succeed on it. The matching modification in the
SPD rule is easy to devise, so we skip it for brevity.
For
SPP to work, the “parallel” nodes must be within mutual range. If they are not, the redundancy will be eliminated on the first pair of nodes where the paths “touch.” It is unlikely that the network spontaneously features two long and never touching paths, both offering the same minimum number of hops between
and
(although situations similar to this may arise during a jamming attack, see
Section 6.2). Then, one should be careful not to overtrim the fuzzy paths, because some degree of redundancy is going to be useful, especially if the network is being designed for reliability and security. Considering that the most likely attack against the networks considered in this paper is DoS, intentional and controllable redundancy in forwarding will be of advantage. Where the demand for bandwidth is moderate, one should be willing to trade it for reliability, not only to combat malicious attacks, but simply to improve the quality of service offered to the application.
The local impact of SPP can be compared to the role of the traditional RTS-CTS handshake in point-to-point forwarding, whose objective is to eliminate damaging contention (collisions) in the neighborhood. While the RTS-CTS handshake is used to reserve the local medium for a single transmission to a specific neighbor, SPP works to eliminate excessive (redundant) retransmissions incurred by forwarding the same packet to multiple nodes in the same neighborhood. The effects of SPP are stronger because they translate into a reduction in the overall network bandwidth needed for successful forwarding.
For one more handy option, the relaxation feature of the
SPD rule can be changed from local to global. As introduced in
Section 4.4, the additional slack
R resulting from the excessive success count of a cache entry augments the standard slack parameter
A. This may force the rule to miss a “success” and retransmit the packet “out of band,” but the next forwarder will likely drop it because (based on
and
) the packet will appear to have deviated from a feasible route. A stronger application of
R is to add it to the packet’s backward hop count
. This has exactly the same effect for the local evaluation of the rule, but it also propagates the extra slack to the packet’s subsequent forwarders. The new variant is listed below:
RuleSPD | (global relaxation option): |
| SPD_cache.add (packet.S, packet.); |
| ce = SPD_cache.get (packet.D); |
| if (ce != NULL) { |
| packet. += (C == 0) ? 0: ce.SCount / C; |
| if (packet. packet.) { |
| ce.SCount++; |
| return SUCCEED; |
| } |
| } |
| return FAIL; |
With respect to concern (3), while strict hop-by-hop acknowledgments (say, of the 4-way handshake variety [
52]) are not possible in TARP, one can think of ways to improve the reliability of a fuzzy hop via multiple retransmissions driven by feedback from the neighborhood. Suppose that all the rules for a packet have failed and the node, call it
K, decides to retransmit the packet. Having performed that,
K will wait until it hears the same packet having been retransmitted by one of its neighbors with a higher value of
, which can be taken as an indication of progress. Until then,
K will be retransmitting the packet at some intervals up to a maximum number of times. This option, dubbed
fuzzy ACKs, has two parameters: the retransmission interval
and the maximum number of (extra) retransmissions
(
means fuzzy ACKs disabled). One little hassle is that final destination of the packet must also retransmit it to notify the last-hop forwarder(s). It is enough to retransmit a dummy version of the packet only consisting of the header. The required information amounts to
S and
Q (the signature) plus
.
The
DD rule can be strengthened (for all or selected packet types) to operate in the so-called shadow mode. With this option, the rule also succeeds when the
Q counter in the processed packet is behind the value in the cache entry, but not further than by the shadow margin
(interpreted modulo the counter’s range). This assumes that a new packet from a given source renders old packets irrelevant, and makes sense for many event/alarm reports. The more aggressive operation of
DD helps resolve packet storms, e.g., resulting from panicky multiple pushes of an alarm button [
5].