Skip to content

Commit

Permalink
If there are no ready segments, leave the tx window alone
Browse files Browse the repository at this point in the history
Before, we set it to size zero, preventing us from sending any further
data. See: mirage#140
  • Loading branch information
talex5 committed Jun 5, 2015
1 parent 36edd11 commit 18f4946
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions tcp/segment.ml
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ module Rx(Time:V1_LWT.TIME) = struct
with Not_found -> false *)

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

let is_empty q = S.is_empty q.segs

Expand Down Expand Up @@ -140,7 +140,7 @@ module Rx(Time:V1_LWT.TIME) = struct
let tx_ack =
if seg.ack then begin
StateTick.tick q.state (State.Recv_ack seg.ack_number);
let win = window ready in
let win = window ~default:(Window.ack_win q.wnd) 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
Expand Down

2 comments on commit 18f4946

@yomimono
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In context, I think ready in window ready refers to received segments, which doesn't seem like a great place to get our advertised receive window from (since our ability to process the incoming data should inform this, rather than the remote end's ability to process incoming data).

@talex5
Copy link
Owner Author

@talex5 talex5 commented on 18f4946 Jun 6, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I'm confused. ready is the received segment, but I thought win was being used to set our transmit window? The code just below does:

       let win_has_changed = (Window.ack_win q.wnd) <> win in
       ...
       Lwt_mvar.put q.tx_ack (seg.ack_number, win)

Window.tx_ack does:

(* An ACK was received - use it to adjust cwnd *)
let tx_ack t r win =
  set_tx_wnd t win;
  ...

Window.tx_ack is called from Segment.Tx.rto_t, which gets win as:

let win = Window.ack_win q.wnd in

So what's the difference between ack_win and tx_win?

Please sign in to comment.