Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_stacks/rack.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 13,110 Lines • ▼ Show 20 Lines | rack_timer_audit(struct tcpcb *tp, struct tcp_rack *rack, struct sockbuf *sb) | ||||
rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); | rack_timer_cancel(tp, rack, rack->r_ctl.rc_rcvtime, __LINE__); | ||||
rack_start_hpts_timer(rack, tp, tcp_get_usecs(NULL), 0, 0, 0); | rack_start_hpts_timer(rack, tp, tcp_get_usecs(NULL), 0, 0, 0); | ||||
} | } | ||||
static void | static void | ||||
rack_do_win_updates(struct tcpcb *tp, struct tcp_rack *rack, uint32_t tiwin, uint32_t seq, uint32_t ack, uint32_t cts, uint32_t high_seq) | rack_do_win_updates(struct tcpcb *tp, struct tcp_rack *rack, uint32_t tiwin, uint32_t seq, uint32_t ack, uint32_t cts, uint32_t high_seq) | ||||
{ | { | ||||
if ((SEQ_LT(tp->snd_wl1, seq) || | |||||
(tp->snd_wl1 == seq && (SEQ_LT(tp->snd_wl2, ack) || | |||||
(tp->snd_wl2 == ack && tiwin > tp->snd_wnd))))) { | |||||
/* keep track of pure window updates */ | |||||
if ((tp->snd_wl2 == ack) && (tiwin > tp->snd_wnd)) | |||||
KMOD_TCPSTAT_INC(tcps_rcvwinupd); | |||||
tp->snd_wnd = tiwin; | tp->snd_wnd = tiwin; | ||||
rack_validate_fo_sendwin_up(tp, rack); | rack_validate_fo_sendwin_up(tp, rack); | ||||
tp->snd_wl1 = seq; | tp->snd_wl1 = seq; | ||||
tp->snd_wl2 = ack; | tp->snd_wl2 = ack; | ||||
if (tp->snd_wnd > tp->max_sndwnd) | if (tp->snd_wnd > tp->max_sndwnd) | ||||
tp->max_sndwnd = tp->snd_wnd; | tp->max_sndwnd = tp->snd_wnd; | ||||
rack->r_wanted_output = 1; | |||||
} else if ((tp->snd_wl2 == ack) && (tiwin < tp->snd_wnd)) { | |||||
tp->snd_wnd = tiwin; | |||||
rack_validate_fo_sendwin_up(tp, rack); | |||||
tp->snd_wl1 = seq; | |||||
tp->snd_wl2 = ack; | |||||
} else { | |||||
/* Not a valid win update */ | |||||
return; | |||||
} | |||||
if (tp->snd_wnd > tp->max_sndwnd) | |||||
tp->max_sndwnd = tp->snd_wnd; | |||||
if (tp->snd_wnd < (tp->snd_max - high_seq)) { | if (tp->snd_wnd < (tp->snd_max - high_seq)) { | ||||
/* The peer collapsed the window */ | /* The peer collapsed the window */ | ||||
rack_collapsed_window(rack); | rack_collapsed_window(rack); | ||||
} else if (rack->rc_has_collapsed) | } else if (rack->rc_has_collapsed) | ||||
rack_un_collapse_window(rack); | rack_un_collapse_window(rack); | ||||
/* Do we exit persists? */ | /* Do we exit persists? */ | ||||
if ((rack->rc_in_persist != 0) && | if ((rack->rc_in_persist != 0) && | ||||
(tp->snd_wnd >= min((rack->r_ctl.rc_high_rwnd/2), | (tp->snd_wnd >= min((rack->r_ctl.rc_high_rwnd/2), | ||||
▲ Show 20 Lines • Show All 186 Lines • ▼ Show 20 Lines | #ifdef TCP_ACCOUNTING | ||||
uint64_t rdstc; | uint64_t rdstc; | ||||
#endif | #endif | ||||
int segsiz; | int segsiz; | ||||
struct timespec ts; | struct timespec ts; | ||||
struct tcp_rack *rack; | struct tcp_rack *rack; | ||||
struct tcp_ackent *ae; | struct tcp_ackent *ae; | ||||
uint32_t tiwin, ms_cts, cts, acked, acked_amount, high_seq, win_seq, the_win, win_upd_ack; | uint32_t tiwin, ms_cts, cts, acked, acked_amount, high_seq, win_seq, the_win, win_upd_ack; | ||||
int cnt, i, did_out, ourfinisacked = 0; | int cnt, i, did_out, ourfinisacked = 0; | ||||
int win_up_req = 0; | |||||
struct tcpopt to_holder, *to = NULL; | struct tcpopt to_holder, *to = NULL; | ||||
int win_up_req = 0; | |||||
int nsegs = 0; | int nsegs = 0; | ||||
int under_pacing = 1; | int under_pacing = 1; | ||||
int recovery = 0; | int recovery = 0; | ||||
int idx; | int idx; | ||||
#ifdef TCP_ACCOUNTING | #ifdef TCP_ACCOUNTING | ||||
sched_pin(); | sched_pin(); | ||||
#endif | #endif | ||||
rack = (struct tcp_rack *)tp->t_fb_ptr; | rack = (struct tcp_rack *)tp->t_fb_ptr; | ||||
▲ Show 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | if (ae->ack_val_set == ACK_BEHIND) { | ||||
counter_u64_add(rack_reorder_seen, 1); | counter_u64_add(rack_reorder_seen, 1); | ||||
rack->r_ctl.rc_reorder_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); | rack->r_ctl.rc_reorder_ts = tcp_tv_to_usectick(&rack->r_ctl.act_rcv_time); | ||||
} | } | ||||
} else if (ae->ack_val_set == ACK_DUPACK) { | } else if (ae->ack_val_set == ACK_DUPACK) { | ||||
/* Case D */ | /* Case D */ | ||||
rack_strike_dupack(rack); | rack_strike_dupack(rack); | ||||
} else if (ae->ack_val_set == ACK_RWND) { | } else if (ae->ack_val_set == ACK_RWND) { | ||||
/* Case C */ | /* Case C */ | ||||
win_up_req = 1; | win_up_req = 1; | ||||
win_upd_ack = ae->ack; | win_upd_ack = ae->ack; | ||||
win_seq = ae->seq; | win_seq = ae->seq; | ||||
the_win = tiwin; | the_win = tiwin; | ||||
rack_do_win_updates(tp, rack, the_win, win_seq, win_upd_ack, cts, high_seq); | |||||
} else { | } else { | ||||
/* Case A */ | /* Case A */ | ||||
if (SEQ_GT(ae->ack, tp->snd_max)) { | if (SEQ_GT(ae->ack, tp->snd_max)) { | ||||
/* | /* | ||||
* We just send an ack since the incoming | * We just send an ack since the incoming | ||||
* ack is beyond the largest seq we sent. | * ack is beyond the largest seq we sent. | ||||
*/ | */ | ||||
if ((tp->t_flags & TF_ACKNOW) == 0) { | if ((tp->t_flags & TF_ACKNOW) == 0) { | ||||
ctf_ack_war_checks(tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt); | ctf_ack_war_checks(tp, &rack->r_ctl.challenge_ack_ts, &rack->r_ctl.challenge_ack_cnt); | ||||
if (tp->t_flags && TF_ACKNOW) | if (tp->t_flags && TF_ACKNOW) | ||||
rack->r_wanted_output = 1; | rack->r_wanted_output = 1; | ||||
} | } | ||||
} else { | } else { | ||||
nsegs++; | nsegs++; | ||||
/* If the window changed setup to update */ | /* If the window changed setup to update */ | ||||
if (tiwin != tp->snd_wnd) { | if (tiwin != tp->snd_wnd) { | ||||
win_up_req = 1; | |||||
win_upd_ack = ae->ack; | win_upd_ack = ae->ack; | ||||
win_seq = ae->seq; | win_seq = ae->seq; | ||||
the_win = tiwin; | the_win = tiwin; | ||||
rack_do_win_updates(tp, rack, the_win, win_seq, win_upd_ack, cts, high_seq); | |||||
} | } | ||||
#ifdef TCP_ACCOUNTING | #ifdef TCP_ACCOUNTING | ||||
/* Account for the acks */ | /* Account for the acks */ | ||||
if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { | if (tp->t_flags2 & TF2_TCP_ACCOUNTING) { | ||||
tp->tcp_cnt_counters[CNT_OF_ACKS_IN] += (((ae->ack - high_seq) + segsiz - 1) / segsiz); | tp->tcp_cnt_counters[CNT_OF_ACKS_IN] += (((ae->ack - high_seq) + segsiz - 1) / segsiz); | ||||
} | } | ||||
counter_u64_add(tcp_cnt_counters[CNT_OF_ACKS_IN], | counter_u64_add(tcp_cnt_counters[CNT_OF_ACKS_IN], | ||||
(((ae->ack - high_seq) + segsiz - 1) / segsiz)); | (((ae->ack - high_seq) + segsiz - 1) / segsiz)); | ||||
Show All 32 Lines | if (rdstc > ts_val) { | ||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
#ifdef TCP_ACCOUNTING | #ifdef TCP_ACCOUNTING | ||||
ts_val = get_cyclecount(); | ts_val = get_cyclecount(); | ||||
#endif | #endif | ||||
acked_amount = acked = (high_seq - tp->snd_una); | acked_amount = acked = (high_seq - tp->snd_una); | ||||
if (win_up_req) { | |||||
rack_do_win_updates(tp, rack, the_win, win_seq, win_upd_ack, cts, high_seq); | |||||
} | |||||
if (acked) { | if (acked) { | ||||
if (rack->sack_attack_disable == 0) | if (rack->sack_attack_disable == 0) | ||||
rack_do_decay(rack); | rack_do_decay(rack); | ||||
if (acked >= segsiz) { | if (acked >= segsiz) { | ||||
/* | /* | ||||
* You only get credit for | * You only get credit for | ||||
* MSS and greater (and you get extra | * MSS and greater (and you get extra | ||||
* credit for larger cum-ack moves). | * credit for larger cum-ack moves). | ||||
▲ Show 20 Lines • Show All 7,071 Lines • Show Last 20 Lines |