Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPv6: use correct timeout value after first NS message #334

Merged
merged 2 commits into from
Dec 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/ipv6/ndpv6.ml
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ module NeighborCache = struct
| Not_found ->
nc, []

let query nc ~now ~reachable_time ip =
let query nc ~now ~retrans_timer ip =
try
let nb = IpMap.find ip nc in
match nb.state with
Expand All @@ -659,7 +659,7 @@ module NeighborCache = struct
nc, Some dmac, []
with
| Not_found ->
let nb = {state = INCOMPLETE (Int64.add now reachable_time, 0); is_router = false} in
let nb = {state = INCOMPLETE (Int64.add now retrans_timer, 0); is_router = false} in
let nc = IpMap.add ip nb nc in
let dst = Ipaddr.Prefix.network_address solicited_node_prefix ip in
nc, None, [SendNS (`Specified, dst, ip)]
Expand Down Expand Up @@ -1110,7 +1110,7 @@ and send ~now ctx dst frame datav =
| false ->
let ctx, ip = next_hop ctx dst in
let neighbor_cache, mac, actions =
NeighborCache.query ctx.neighbor_cache ~now ~reachable_time:ctx.reachable_time ip in
NeighborCache.query ctx.neighbor_cache ~now ~retrans_timer:ctx.retrans_timer ip in
let ctx = {ctx with neighbor_cache} in
match mac with
| Some dmac ->
Expand Down
21 changes: 15 additions & 6 deletions test/test_ipv6.ml
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,38 @@ let listen ?(tcp = noop) ?(udp = noop) ?(default = noop) stack =

let udp_message = Cstruct.of_string "hello on UDP over IPv6"

let check_for_one_udp_packet netif ~src ~dst buf =
let check_for_one_udp_packet netif on_received_one ~src ~dst buf =
Alcotest.(check ip) "sender address" (Ipaddr.V6.of_string_exn "fc00::23") src;
Alcotest.(check ip) "receiver address" (Ipaddr.V6.of_string_exn "fc00::45") dst;
(match Udp_packet.Unmarshal.of_cstruct buf with
| Ok (_, payload) ->
Alcotest.(check cstruct) "payload is correct" udp_message payload
| Error m -> Alcotest.fail m);
(try Lwt.wakeup_later on_received_one () with _ -> () (* the first succeeds, the rest raise *));
(*after receiving 1 packet, disconnect stack so test can continue*)
V.disconnect netif

let send_forever sender receiver_address udp_message =
let rec loop () =
Printf.fprintf stderr "Udp.write\n%!";
Udp.write sender.udp ~dst:receiver_address ~dst_port:1234 udp_message
>|= Rresult.R.get_ok >>= fun () ->
Time.sleep_ns (Duration.of_ms 50) >>= fun () ->
loop () in
loop ()

let pass_udp_traffic () =
let sender_address = Ipaddr.V6.of_string_exn "fc00::23" in
let receiver_address = Ipaddr.V6.of_string_exn "fc00::45" in
let backend = B.create () in
get_stack backend sender_address >>= fun sender ->
get_stack backend receiver_address >>= fun receiver ->
let received_one, on_received_one = Lwt.task () in
Lwt.pick [
listen receiver ~udp:(check_for_one_udp_packet receiver.netif);
listen receiver ~udp:(check_for_one_udp_packet receiver.netif on_received_one);
listen sender;
(* Duration.of_ms 500 makes this test fail - why? *)
Time.sleep_ns (Duration.of_ms 1000) >>= fun () ->
Udp.write sender.udp ~dst:receiver_address ~dst_port:1234 udp_message
>|= Rresult.R.get_ok >>= fun () ->
send_forever sender receiver_address udp_message;
received_one; (* stop on the first packet *)
Time.sleep_ns (Duration.of_ms 3000) >>= fun () ->
Alcotest.fail "UDP packet should have been received";
]
Expand Down