Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137289964
D46066.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D46066.diff
View Options
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -2208,10 +2208,7 @@
}
} else {
TCPSTAT_INC(tcps_badrst);
- /* Send challenge ACK. */
- tcp_respond(tp, mtod(m, void *), th, m,
- tp->rcv_nxt, tp->snd_nxt, TH_ACK);
- tp->last_ack_sent = tp->rcv_nxt;
+ tcp_send_challenge_ack(tp, th, m);
m = NULL;
}
}
@@ -2233,10 +2230,7 @@
rstreason = BANDLIM_UNLIMITED;
} else {
tcp_ecn_input_syn_sent(tp, thflags, iptos);
- /* Send challenge ACK. */
- tcp_respond(tp, mtod(m, void *), th, m, tp->rcv_nxt,
- tp->snd_nxt, TH_ACK);
- tp->last_ack_sent = tp->rcv_nxt;
+ tcp_send_challenge_ack(tp, th, m);
m = NULL;
}
goto drop;
@@ -2474,10 +2468,7 @@
TCPSTAT_INC(tcps_rcvghostack);
else
TCPSTAT_INC(tcps_rcvacktooold);
- /* Send a challenge ACK. */
- tcp_respond(tp, mtod(m, void *), th, m,
- tp->rcv_nxt, tp->snd_nxt, TH_ACK);
- tp->last_ack_sent = tp->rcv_nxt;
+ tcp_send_challenge_ack(tp, th, m);
m = NULL;
goto drop;
}
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2181,6 +2181,45 @@
lgb->tlb_errno = output_ret;
}
+/*
+ * Send a challenge ack (no data, no SACK option), but not more than
+ * tcp_ack_war_cnt per tcp_ack_war_time_window (per TCP connection).
+ */
+void
+tcp_send_challenge_ack(struct tcpcb *tp, struct tcphdr *th, struct mbuf *m)
+{
+ sbintime_t now;
+ bool send_challenge_ack;
+
+ if (tcp_ack_war_time_window == 0 || tcp_ack_war_cnt == 0) {
+ /* ACK war protection is disabled. */
+ send_challenge_ack = true;
+ } else {
+ /* Start new epoch, if the previous one is already over. */
+ now = getsbinuptime();
+ if (tp->t_challenge_ack_end < now) {
+ tp->t_challenge_ack_cnt = 0;
+ tp->t_challenge_ack_end = now +
+ tcp_ack_war_time_window * SBT_1MS;
+ }
+ /*
+ * Send a challenge ACK, if less than tcp_ack_war_cnt have been
+ * sent in the current epoch.
+ */
+ if (tp->t_challenge_ack_cnt < tcp_ack_war_cnt) {
+ send_challenge_ack = true;
+ tp->t_challenge_ack_cnt++;
+ } else {
+ send_challenge_ack = false;
+ }
+ }
+ if (send_challenge_ack) {
+ tcp_respond(tp, mtod(m, void *), th, m, tp->rcv_nxt,
+ tp->snd_nxt, TH_ACK);
+ tp->last_ack_sent = tp->rcv_nxt;
+ }
+}
+
/*
* Create a new TCP control block, making an empty reassembly queue and hooking
* it to the argument protocol control block. The `inp' parameter must have
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -465,6 +465,11 @@
/* TCP Fast Open */
uint8_t t_tfo_client_cookie_len; /* TFO client cookie length */
uint32_t t_end_info_status; /* Status flag of end info */
+ sbintime_t t_challenge_ack_end; /* End of the challenge ack epoch */
+ uint32_t t_challenge_ack_cnt; /* Number of challenge ACKs sent in
+ * current epoch
+ */
+
unsigned int *t_tfo_pending; /* TFO server pending counter */
union {
uint8_t client[TCP_FASTOPEN_MAX_COOKIE_LEN];
@@ -1460,6 +1465,7 @@
void tcp_state_change(struct tcpcb *, int);
void tcp_respond(struct tcpcb *, void *,
struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, uint16_t);
+void tcp_send_challenge_ack(struct tcpcb *, struct tcphdr *, struct mbuf *);
bool tcp_twcheck(struct inpcb *, struct tcpopt *, struct tcphdr *,
struct mbuf *, int);
void tcp_setpersist(struct tcpcb *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 23, 2:46 AM (4 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25945460
Default Alt Text
D46066.diff (3 KB)
Attached To
Mode
D46066: tcp: implement throttling of challenge ACKs
Attached
Detach File
Event Timeline
Log In to Comment