Hi,
I often experience problems with connections in my state table that are
in 2/4 "state" (one side fully established, the other side, not yet). The
annoying thing about these states, is that they have a five day time-out.
I propose the following change to fr_tcp_age() to circumvent this. However,
the TCP fsm is a tricky thing, so I offer it here for review first.
I realize that this code might not be perfect in respect to retransmits.
Any thoughts?
Thanks,
Frank
Index: ip_state.c
===================================================================
RCS file: /home/cvs/firewall/firewall/usrlocal/ipfilter34/ipfilter34/ip_state.c,v
retrieving revision 1.4.4.1
diff -u -r1.4.4.1 ip_state.c
--- ip_state.c 19 Dec 2002 16:04:42 -0000 1.4.4.1
+++ ip_state.c 6 Jan 2003 12:21:37 -0000
@@ -1681,12 +1681,14 @@
* already established connections into the state table
* after a restart or reload of the filter rules; this
* does not work when a strict 'flags S keep state' is
- * used for tcp connections of course
+ * used for tcp connections of course. Use however
+ * a lower time-out, so the state disappears quickly
+ * if the other side does not pick it up
*/
if ((flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
/* we saw an A, guess 'dir' is in ESTABLISHED mode */
state[dir] = TCPS_ESTABLISHED;
- *age = fr_tcpidletimeout;
+ *age = fr_tcptimeout;
}
/*
* TODO: besides regular ACK packets we can have other
@@ -1707,7 +1709,15 @@
* which it received, SYN_SENT -> ESTABLISHED
*/
state[dir] = TCPS_ESTABLISHED;
- *age = fr_tcpidletimeout;
+ /* Use a long (5 day) timeout only if both sides
+ * are in established mode. This fixes long
+ * living states in 2/4 mode
+ */
+ if (ostate == TCPS_ESTABLISHED) {
+ *age = fr_tcpidletimeout;
+ } else {
+ *age = fr_tcptimeout;
+ }
} else if (flags & TH_FIN) {
/*
* We see an F from 'dir' which is in SYN_SENT
@@ -1735,7 +1745,15 @@
* SYN_RECEIVED -> ESTABLISHED
*/
state[dir] = TCPS_ESTABLISHED;
- *age = fr_tcpidletimeout;
+ /* Use a long (5 day) timeout only if both sides
+ * are in established mode. This fixes long
+ * living states in 2/4 mode
+ */
+ if (ostate == TCPS_ESTABLISHED) {
+ *age = fr_tcpidletimeout;
+ } else {
+ *age = fr_tcptimeout;
+ }
} else if (flags & TH_FIN) {
/*
* We see an F from 'dir' which is in SYN_RECEIVED