| 11906 | } |
| 11907 | |
| 11908 | static int |
| 11909 | bbr_window_update_needed(struct tcpcb *tp, struct socket *so, uint32_t recwin, int32_t maxseg) |
| 11910 | { |
| 11911 | /* |
| 11912 | * "adv" is the amount we could increase the window, taking into |
| 11913 | * account that we are limited by TCP_MAXWIN << tp->rcv_scale. |
| 11914 | */ |
| 11915 | int32_t adv; |
| 11916 | int32_t oldwin; |
| 11917 | |
| 11918 | adv = recwin; |
| 11919 | if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt)) { |
| 11920 | oldwin = (tp->rcv_adv - tp->rcv_nxt); |
| 11921 | if (adv > oldwin) |
| 11922 | adv -= oldwin; |
| 11923 | else { |
| 11924 | /* We can't increase the window */ |
| 11925 | adv = 0; |
| 11926 | } |
| 11927 | } else |
| 11928 | oldwin = 0; |
| 11929 | |
| 11930 | /* |
| 11931 | * If the new window size ends up being the same as or less |
| 11932 | * than the old size when it is scaled, then don't force |
| 11933 | * a window update. |
| 11934 | */ |
| 11935 | if (oldwin >> tp->rcv_scale >= (adv + oldwin) >> tp->rcv_scale) |
| 11936 | return (0); |
| 11937 | |
| 11938 | if (adv >= (2 * maxseg) && |
| 11939 | (adv >= (so->so_rcv.sb_hiwat / 4) || |
| 11940 | recwin <= (so->so_rcv.sb_hiwat / 8) || |
| 11941 | so->so_rcv.sb_hiwat <= 8 * maxseg)) { |
| 11942 | return (1); |
| 11943 | } |
| 11944 | if (2 * adv >= (int32_t) so->so_rcv.sb_hiwat) |
| 11945 | return (1); |
| 11946 | return (0); |
| 11947 | } |
| 11948 | |
| 11949 | /* |
| 11950 | * Return 0 on success and a errno on failure to send. |