Bug 879 - source address selection for AODV using DeferredRouteRequest
source address selection for AODV using DeferredRouteRequest
Status: RESOLVED FIXED
Product: ns-3
Classification: Unclassified
Component: aodv
pre-release
All All
: P2 critical
Assigned To: Elena Buchatskaya
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-04-16 02:28 EDT by Tom Henderson
Modified: 2010-08-10 23:38 EDT (History)
3 users (show)

See Also:


Attachments
test case (6.48 KB, text/x-csrc)
2010-04-20 02:10 EDT, Tom Henderson
Details
test case with NSC-TCP (6.88 KB, text/x-c++src)
2010-07-27 00:25 EDT, Elena Buchatskaya
Details
patch to fix (3.22 KB, patch)
2010-08-07 18:49 EDT, Tom Henderson
Details | Diff
revised test case for ns-3 TCP (7.00 KB, text/x-csrc)
2010-08-07 18:50 EDT, Tom Henderson
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Henderson 2010-04-16 02:28:37 EDT
This problem was reported by Glenn Evans, although the subject line attributed it to OnOffApplication or Pcap changes.  It seems to be really an AODV issue and is related to previously closed bug 772.

The problem is that Tcp::Connect performs source address selection, and presently, the address returned for locally outbound packets is 102.102.102.102 (with destination to loopback interface).  This source address is bound to the endpoint.  This causes a deferred route request from RouteInput (which succeeds) but the source address of the Tcp SYN seems to not be rewritten:

3.001566 ARP, Request who-has 192.168.0.1 (ff:ff:ff:ff:ff:ff) tell 192.168.0.5, length 32
3.001847 ARP, Reply 192.168.0.1 is-at 00:00:00:00:00:01, length 32
3.001939 Acknowledgment RA:00:00:00:00:00:01 
3.002101 IP 102.102.102.102.49153 > 192.168.0.1.5000: Flags [S], seq 0, win 65535, length 0
3.002117 Acknowledgment RA:00:00:00:00:00:05 
3.002276 IP 192.168.0.1.654 > 192.168.0.255.654:  aodv rreq 24  hops 0 id 0x00000001
        dst 102.102.102.102 seq 0 src 192.168.0.1 seq 1

The above causes the destination 192.168.0.1 to initiate a RREQ for 102.102.102.102.  

Fixing this SYN source address in the Aodv deferred route request will not be sufficient, however, because there is no mechanism for AODV to call back up to Tcp and tell it to reset its endpoint source address to the one that is aligned with AODV's RREP.

This may be alleviated by forcing the user originating packets on an AODV router to bind to a specific outbound interface, in which case passing the oif parameter to RouteOutput() could result in a correct source address being returned (even if the packet is still looped to the loopback address to find the right next hop).

If we want to support the more general case where the user does not specify a locally bound interface for outbound packets, then something along the lines of a new flag in the Ipv4Route (m_deferred) could be added; in such a scenario, AODV passes a route back to the TCP but marks it as "deferred".  TCP keeps this state, and when the connection SYN exchange completes, checks this flag and if set, calls into RouteOutput() again to learn the source address that was found by the AODV RREP.
Comment 1 Tom Henderson 2010-04-20 02:10:21 EDT
Created attachment 837 [details]
test case

here is a test case, changing the example in src/routing/aodv.cc to use a TCP application instead of ICMP.  ICMP and UDP do not seem to exhibit problems, but TCP does.  I would be leery of using TCP with AODV until this is fixed.
Comment 2 Tom Henderson 2010-04-20 02:10:49 EDT
raising priority
Comment 3 Elena Buchatskaya 2010-04-20 14:57:25 EDT
(In reply to comment #0)
> This problem was reported by Glenn Evans, although the subject line attributed
> it to OnOffApplication or Pcap changes.  It seems to be really an AODV issue
> and is related to previously closed bug 772.

AODV just takes source address from the header that was passed to RouteOutput() before. So the problem is that Tcp::Connect sets only destination address in this header, not source. Thus source address in this header equals default value from Ipv4Address constructor (102.102.102.102). Also at present time tcp socket passes to RouteOutput() null pointer to NetDevice  and therefore AODV can't set correct source address. If route is not known and oif != 0 in RouteOutput, should AODV use oif to determine source address or simply take it from header?

> Fixing this SYN source address in the Aodv deferred route request will not be
> sufficient, however, because there is no mechanism for AODV to call back up to
> Tcp and tell it to reset its endpoint source address to the one that is aligned
> with AODV's RREP.

AODV is a  routing protocol and so it is responsible only for route discovery.

> This may be alleviated by forcing the user originating packets on an AODV
> router to bind to a specific outbound interface, in which case passing the oif
> parameter to RouteOutput() could result in a correct source address being
> returned (even if the packet is still looped to the loopback address to find
> the right next hop).

This would correctly work in case of one interface per device. I know a user who is interested in AODV simulation with multiple interfaces (http://groups.google.com/group/ns-3-users/browse_thread/thread/f88a6c5e5e41cca6). Generally speaking, TCP socket can't 'know' the interface from which the packet should be sent and AODV can't 'know' this before route discovery either.

> If we want to support the more general case where the user does not specify a
> locally bound interface for outbound packets, then something along the lines of
> a new flag in the Ipv4Route (m_deferred) could be added; in such a scenario,
> AODV passes a route back to the TCP but marks it as "deferred".  TCP keeps this
> state, and when the connection SYN exchange completes, checks this flag and if
> set, calls into RouteOutput() again to learn the source address that was found
> by the AODV RREP.

Well, it looks like smart workaround.
Comment 4 Josh Pelkey 2010-04-30 13:16:04 EDT
changeset 533be42b3c7f
Comment 5 Josh Pelkey 2010-04-30 13:16:32 EDT
whoops, wrong bug.  reopening :)
Comment 6 Elena Buchatskaya 2010-07-27 00:23:48 EDT
I use AODV with NSC-TCP instead of native ns-3 TCP model and everything works fine. NSC-TCP passes fully formed header (with source address) to routing protocol. 

0.1s 0 [node 0] AodvRoutingProtocol:RouteOutput(0x9ef52f8, 10.0.0.3)
0.1s 0 [node 0] AodvRoutingProtocol:LoopbackRoute(0x9ef52f8, tos 0x0 ttl 64 id 1 protocol 6 offset 0 flags [none] length: 60 10.0.0.1 > 10.0.0.3)
0.1s 0 [node 0] AodvRoutingProtocol:RouteInput(0x9ef52f8, 3, 10.0.0.3, 05-06-00:00:00:00:00:00)
0.1s 0 [node 0] AodvRoutingProtocol:DeferredRouteOutput(0x9ef52f8, 0x9f46d48, tos 0x0 ttl 64 id 1 protocol 6 offset 0 flags [none] length: 60 10.0.0.1 > 10.0.0.3)
0.1s 0 [node 0] AodvRoutingProtocol:DeferredRouteOutput(): Add packet 3 to queue. Protocol 6
0.1s 0 [node 0] AodvRoutingProtocol:SendRequest(0x9ef52f8, 10.0.0.3)

Since AODV works with real world TCP/IP network stack, the error should be in the TCP model implementation.
Comment 7 Elena Buchatskaya 2010-07-27 00:25:28 EDT
Created attachment 955 [details]
test case with NSC-TCP
Comment 8 Tom Henderson 2010-07-27 00:26:03 EDT
(In reply to comment #6)
> I use AODV with NSC-TCP instead of native ns-3 TCP model and everything works
> fine. NSC-TCP passes fully formed header (with source address) to routing
> protocol. 
> 
> 0.1s 0 [node 0] AodvRoutingProtocol:RouteOutput(0x9ef52f8, 10.0.0.3)
> 0.1s 0 [node 0] AodvRoutingProtocol:LoopbackRoute(0x9ef52f8, tos 0x0 ttl 64 id
> 1 protocol 6 offset 0 flags [none] length: 60 10.0.0.1 > 10.0.0.3)
> 0.1s 0 [node 0] AodvRoutingProtocol:RouteInput(0x9ef52f8, 3, 10.0.0.3,
> 05-06-00:00:00:00:00:00)
> 0.1s 0 [node 0] AodvRoutingProtocol:DeferredRouteOutput(0x9ef52f8, 0x9f46d48,
> tos 0x0 ttl 64 id 1 protocol 6 offset 0 flags [none] length: 60 10.0.0.1 >
> 10.0.0.3)
> 0.1s 0 [node 0] AodvRoutingProtocol:DeferredRouteOutput(): Add packet 3 to
> queue. Protocol 6
> 0.1s 0 [node 0] AodvRoutingProtocol:SendRequest(0x9ef52f8, 10.0.0.3)
> 
> Since AODV works with real world TCP/IP network stack, the error should be in
> the TCP model implementation.

I think it works with NSC because NSC only supports one interface; multi-interface NSC does not work in ns-3.
Comment 9 Tom Henderson 2010-08-07 18:49:42 EDT
Created attachment 965 [details]
patch to fix

AODV needs to select a source address in RouteOutput() in cases in which it doesn't yet have a route, since the connection endpoint tuple needs to be set at socket connect() time.  This patch implements the following policy:
- if socket outbound interface is set, select first AODV address that matches the outbound interface;
- otherwise, select first AODV address found

The test suite routing-aodv-regression fails with this patch applied.  However, if you look at the current ns-3-dev pcap trace in this case, /src/routing/aodv/test/tcp-chain-test-0-0.pcap, you will see that TCP is not working correctly.  This is because the present unpatched code will cause the connection endpoint to be set to src address 127.0.0.1.  When the SYN ACK returns, there will be no matching endpoint, and TCP reset is generated.  With the patch, the TCP connection setup succeeds.  So, committing this patch will also require new tcp-chain pcap traces to be uploaded.

There may be certain multi-interface cases in which AODV picks one address that will later fail when, if it had picked the other interface, it may have succeeded.  A workaround in this case is to have the user perform route discovery before initiating the socket (prime the routing table with, for instance, a ping or UDP ping).  Maybe we should document this fact where we document limitations or caveats of this AODV model.
Comment 10 Tom Henderson 2010-08-07 18:50:23 EDT
Created attachment 966 [details]
revised test case for ns-3 TCP
Comment 11 Josh Pelkey 2010-08-10 13:05:08 EDT
I committed this patch.  I wasn't sure what you wanted to do with that revised test case, as it looks more like the aodv example.  I am closing this for now, but I will remind you about that revised test case you posted.

changeset: 6804b85fe140
Comment 12 Tom Henderson 2010-08-10 23:38:50 EDT
(In reply to comment #11)
> I committed this patch.  I wasn't sure what you wanted to do with that revised
> test case, as it looks more like the aodv example.  I am closing this for now,
> but I will remind you about that revised test case you posted.
> 
> changeset: 6804b85fe140

I do not care that much since the aodv tcp-chain-test covers this.  Probably a good thing to add is an NSC variant of the tcp-chain-test (which I separately tested but is not in the regression suite)