Skip to content

Commit

Permalink
fixed bug where in case of out of order packets the ack and window we…
Browse files Browse the repository at this point in the history
…re set incorrectly
  • Loading branch information
balrajsingh committed Jun 6, 2015
1 parent 6208809 commit fe8f63b
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 21 deletions.
23 changes: 7 additions & 16 deletions tcp/segment.ml
Expand Up @@ -96,11 +96,6 @@ module Rx(Time:V1_LWT.TIME) = struct
try (S.max_elt q).syn
with Not_found -> false *)

(* Determine the transmit window, from the last segment *)
let window q =
try (S.max_elt q).window
with Not_found -> 0

let is_empty q = S.is_empty q.segs

(* Given an input segment, the window information, and a receive
Expand Down Expand Up @@ -138,22 +133,18 @@ module Rx(Time:V1_LWT.TIME) = struct
q.segs <- waiting;
(* If the segment has an ACK, tell the transmit side *)
let tx_ack =
if seg.ack then begin
if seg.ack && (Sequence.geq seg.ack_number (Window.ack_seq q.wnd)) then begin
StateTick.tick q.state (State.Recv_ack seg.ack_number);
let win = window ready in
let data_in_flight = Window.tx_inflight q.wnd in
let seq_has_changed = (Window.ack_seq q.wnd) <> seg.ack_number in
let win_has_changed = (Window.ack_win q.wnd) <> win in
if ((data_in_flight && (Window.ack_serviced q.wnd || not seq_has_changed)) ||
let ack_has_advanced = (Window.ack_seq q.wnd) <> seg.ack_number in
let win_has_changed = (Window.ack_win q.wnd) <> seg.window in
if ((data_in_flight && (Window.ack_serviced q.wnd || not ack_has_advanced)) ||
(not data_in_flight && win_has_changed)) then begin
Window.set_ack_serviced q.wnd false;
Window.set_ack_seq q.wnd seg.ack_number;
Window.set_ack_win q.wnd win;
Lwt_mvar.put q.tx_ack (seg.ack_number, win)
Window.set_ack_seq_win q.wnd seg.ack_number seg.window;
Lwt_mvar.put q.tx_ack ((Window.ack_seq q.wnd), (Window.ack_win q.wnd))
end else begin
if (Sequence.gt seg.ack_number (Window.ack_seq q.wnd)) then
Window.set_ack_seq q.wnd seg.ack_number;
Window.set_ack_win q.wnd win;
Window.set_ack_seq_win q.wnd seg.ack_number seg.window;
return_unit
end
end else return_unit in
Expand Down
6 changes: 3 additions & 3 deletions tcp/window.ml
Expand Up @@ -134,10 +134,10 @@ let ack_seq t = t.ack_seq
let ack_win t = t.ack_win

let set_ack_serviced t v = t.ack_serviced <- v
let set_ack_seq t s =
let set_ack_seq_win t s w =
MProf.Counter.increase count_ackd_segs (Sequence.(sub s t.ack_seq |> to_int));
t.ack_seq <- s
let set_ack_win t w = t.ack_win <- w
t.ack_seq <- s;
t.ack_win <- w

(* TODO: scale the window down so we can advertise it correctly with
window scaling on the wire *)
Expand Down
3 changes: 1 addition & 2 deletions tcp/window.mli
Expand Up @@ -44,8 +44,7 @@ val ack_seq : t -> Sequence.t
val ack_win : t -> int

val set_ack_serviced : t -> bool -> unit
val set_ack_seq : t -> Sequence.t -> unit
val set_ack_win : t -> int -> unit
val set_ack_seq_win : t -> Sequence.t -> int -> unit

(* rx_wnd: number of bytes we are willing to accept *)
val rx_wnd : t -> int32
Expand Down

0 comments on commit fe8f63b

Please sign in to comment.