diff --git a/tcp/segment.ml b/tcp/segment.ml index 448d550f9..851d06667 100644 --- a/tcp/segment.ml +++ b/tcp/segment.ml @@ -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 @@ -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 diff --git a/tcp/window.ml b/tcp/window.ml index 9ff05b282..a55e69fcb 100644 --- a/tcp/window.ml +++ b/tcp/window.ml @@ -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 *) diff --git a/tcp/window.mli b/tcp/window.mli index 47f9405d4..8eed32430 100644 --- a/tcp/window.mli +++ b/tcp/window.mli @@ -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