summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2006-09-28 18:02:46 +0000
committerandre <andre@FreeBSD.org>2006-09-28 18:02:46 +0000
commit5eae8ee0ac0d71104053a951c861a1d656250a3f (patch)
treeaab2aebc6b768d1b92e9fb1ebf178208ce201920
parentb09219dff2053b3bc306fe8d2389cb38d1e84280 (diff)
downloadFreeBSD-src-5eae8ee0ac0d71104053a951c861a1d656250a3f.zip
FreeBSD-src-5eae8ee0ac0d71104053a951c861a1d656250a3f.tar.gz
When tcp_output() receives an error upon sending a packet it reverts parts
of its internal state to ignore the failed send and try again a bit later. If the error is EPERM the packet got blocked by the local firewall and the revert may cause the session to get stuck and retry indefinitely. This way we treat it like a packet loss and let the retransmit timer and timeouts do their work over time. The correct behavior is to drop a connection that gets an EPERM error. However this _may_ introduce some POLA problems and a two commit approach was chosen. Discussed with: glebius PR: kern/25986 PR: kern/102653
-rw-r--r--sys/netinet/tcp_output.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 0ea53e2..6833e7e 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1137,9 +1137,18 @@ timer:
/*
* We know that the packet was lost, so back out the
* sequence number advance, if any.
+ *
+ * If the error is EPERM the packet got blocked by the
+ * local firewall. Normally we should terminate the
+ * connection but the blocking may have been spurious
+ * due to a firewall reconfiguration cycle. So we treat
+ * it like a packet loss and let the retransmit timer and
+ * timeouts do their work over time.
+ * XXX: It is a POLA question whether calling tcp_drop right
+ * away would be the really correct behavior instead.
*/
- if ((tp->t_flags & TF_FORCEDATA) == 0 ||
- !callout_active(tp->tt_persist)) {
+ if (error != EPERM && ((tp->t_flags & TF_FORCEDATA) == 0 ||
+ !callout_active(tp->tt_persist))) {
/*
* No need to check for TH_FIN here because
* the TF_SENTFIN flag handles that case.
@@ -1155,6 +1164,10 @@ timer:
tp->snd_nxt -= len;
}
}
+ if (error == EPERM) {
+ tp->t_softerror = error;
+ return (error);
+ }
out:
SOCKBUF_UNLOCK_ASSERT(&so->so_snd); /* Check gotos. */
OpenPOWER on IntegriCloud