In article <[EMAIL PROTECTED]> you write:

>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

What types of connections are these? A misbehaving OS?

>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

Some years ago I proposed the code that is now unused between #ifdef
#endif in my own CVS tree:

@@ -1835,6 +1848,15 @@
                 */
                if (!fsm && (flags & (TH_FIN|TH_SYN|TH_RST|TH_ACK)) == TH_ACK) {
                        /* we saw an A, guess 'dir' is in ESTABLISHED mode */
+#ifdef ADV
+                       state[dir] = TCPS_ESTABLISHED;
+                       if (ostate >= TCPS_ESTABLISHED)
+                               /*
+                                * only when the other side is ESTABLISHED
+                                * already, increase timeout
+                                */
+                               *age = fr_tcpidletimeout;
+#endif
                        if (state[1 - dir] == TCPS_CLOSED ||
                            state[1 - dir] == TCPS_ESTABLISHED) {
                                state[dir] = TCPS_ESTABLISHED;

I think the lower fr_tcptimeout value should only be set when the other
side is not TCPS_ESTABLISHED yet. So I suggest adding an 'if (ostate ==
...)' clause here as is done in the other parts of your proposed patch.

B.t.w., I don't see this piece of 'official' ipfilter code:

                        if (state[1 - dir] == TCPS_CLOSED ||
                            state[1 - dir] == TCPS_ESTABLISHED) {
                                state[dir] = TCPS_ESTABLISHED;

in your code before the 'TODO: besides regular ACK packets' comment.

>@@ -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

This will cause problems for connections in 4/3 state; that's the state
of a TCP connection where only the three handshake packets have been
sent. Such 'silent' but fully established TCP connections will now be
terminated in fr_tcptimeout time. If five days is indeed undesirable for
such connections I would suggest the same timeout as used for
half-closed connections (2 hours by default).

>@@ -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
>

This part looks OK to me.

Arjan

-- 
Arjan de Vet, Eindhoven, The Netherlands               <[EMAIL PROTECTED]>
URL : http://www.iae.nl/users/devet/            <[EMAIL PROTECTED]>
Work: http://www.madison-gurkha.com/  (Security, Open Source, Education)

Reply via email to