tcp state transition in sloppy mode

Jingmin Zhou <[email protected]> Tue, 21 Jun 2016 14:15:00 -0700
Newsgroups gmane.os.openbsd.pf
Message-ID <CAAbDdZAgZtKoT1LC5Ujgx6wo7K701JXN1bzO6W8srWZ_z0D1-w@mail.gmail.com>
--001a1148a526598cf10535d0507a
Content-Type: text/plain; charset=UTF-8

Hi,

Recently we ran into some issues with pf sloppy mode with regards to
some long standing TCP connections. While reading pf code, we feel
puzzled by the way pf handles TCP packets in sloppy mode. Here are
some of our analysis.

Background: a TCP connection were established between two hosts (A
and B) before pf is enabled in sloppy mode. The connection is mostly
idle with periodic keep alive packets, i.e., PUSH-ACK and ACK packets
every few minutes. An pass rule matches this connection and allows
packet to pass through.

When a PUSH-ACK packet of the connection was observed from host A->B,
the pass rule lets pf.c:pf_create_state function to create a new
state for the connection. In the state, s->src.state = TCPS_SYN_SENT,
and s->dst.state = TCPS_CLOSED (line 3563 and 3564 in the code below).

3488 static __inline int

3489 pf_create_state(struct pf_pdesc *pd, struct pf_rule *r, struct pf_rule
*a,

3490     struct pf_rule *nr, struct pf_state_key **skw, struct pf_state_key
**sks,

3491     int *rewrite, struct pf_state **sm, int tag, struct pf_rule_slist
*rules,

3492     struct pf_rule_actions *act, struct pf_src_node *sns[PF_SN_MAX])

3493 {

         ...


3532     switch (pd->proto) {

3533     case IPPROTO_TCP:

             ...

3561         s->dst.seqhi = 1;

3562         s->dst.max_win = 1;

3563         s->src.state = TCPS_SYN_SENT;

3564         s->dst.state = TCPS_CLOSED;

3565         s->timeout = PFTM_TCP_FIRST_PACKET;

3566         break;

The second packet is an ACK packet from B to A. It eventually makes
pf enter into pf.c:pf_test_state function. A simplified code flow
is shown as below:

4320 int

4321 pf_test_state(struct pf_pdesc *pd, struct pf_state **state, u_short
*reason)

4322 {

         ...

4338     STATE_LOOKUP(pd->kif, &key, pd->dir, *state, pd->m);

4339

4340     if (pd->dir == (*state)->direction) {

4341         src = &(*state)->src;

4342         dst = &(*state)->dst;

4343     } else {

4344         src = &(*state)->dst;

4345         dst = &(*state)->src;

4346     }

4347

4348     switch (pd->virtual_proto) {

4349     case IPPROTO_TCP:

             ...

4369         if ((*state)->state_flags & PFSTATE_SLOPPY) {

4370             if (pf_tcp_track_sloppy(pd, src, dst, state, reason) ==

4371                 PF_DROP)

4372                 return (PF_DROP);

4373         } else {

         ...

4465 }

Please notice that src and dst are taken from state entry and are
swapped at line 4344 and 4345 before being passed into function
pf_tcp_track_sloppy. So the src has a state TCPS_CLOSED and dst
has a state TCPS_SYN_SENT in function pf_tcp_track_sloppy.

Below, a simplified pf_tcp_track_sloppy is shown. As we can see,
the ACK packet from B to A will match condition at line 4168. So
the state now changes to ESTABLISHED (A->B.src) and CLOSED (A->B.
dst).

4155 int

4156 pf_tcp_track_sloppy(struct pf_pdesc *pd, struct pf_state_peer *src,

4157     struct pf_state_peer *dst, struct pf_state **state, u_short
*reason)

4158 {

         ...

4167     if (th->th_flags & TH_ACK) {

4168         if (dst->state == TCPS_SYN_SENT) {

4169             dst->state = TCPS_ESTABLISHED;

4170             if (src->state == TCPS_ESTABLISHED &&

4171                 !SLIST_EMPTY(&(*state)->src_nodes) &&

4172                 pf_src_connlimit(state)) {

4173                 REASON_SET(reason, PFRES_SRCLIMIT);

4174                 return (PF_DROP);

4175             }

4176         } else if (dst->state == TCPS_CLOSING) {

4177             dst->state = TCPS_FIN_WAIT_2;

4178         } else if (src->state == TCPS_SYN_SENT &&

4179             dst->state < TCPS_SYN_SENT) {

4180             /*

4181              * Handle a special sloppy case where we only see one

4182              * half of the connection. If there is a ACK after

4183              * the initial SYN without ever seeing a packet from

4184              * the destination, set the connection to established.

4185              */

4186             dst->state = src->state = TCPS_ESTABLISHED;

4187             if (!SLIST_EMPTY(&(*state)->src_nodes) &&

4188                 pf_src_connlimit(state)) {

4189                 REASON_SET(reason, PFRES_SRCLIMIT);

4190                 return (PF_DROP);

4191             }

4192         } else if (src->state == TCPS_CLOSING &&

4193             dst->state == TCPS_ESTABLISHED &&

4194             dst->seqlo == 0) {

4195             /*

4196              * Handle the closing of half connections where we

4197              * don't see the full bidirectional FIN/ACK+ACK

4198              * handshake.

4199              */

4200             dst->state = TCPS_CLOSING;

4201         }

4202     }

         ...

4206     /* update expire time */

4207     (*state)->expire = time_uptime;

4208     if (src->state >= TCPS_FIN_WAIT_2 &&

4209         dst->state >= TCPS_FIN_WAIT_2)

4210         (*state)->timeout = PFTM_TCP_CLOSED;

4211     else if (src->state >= TCPS_CLOSING &&

4212         dst->state >= TCPS_CLOSING)

4213         (*state)->timeout = PFTM_TCP_FIN_WAIT;

4214     else if (src->state < TCPS_ESTABLISHED ||

4215         dst->state < TCPS_ESTABLISHED)

4216         (*state)->timeout = PFTM_TCP_OPENING;

4217     else if (src->state >= TCPS_CLOSING ||

4218         dst->state >= TCPS_CLOSING)

4219         (*state)->timeout = PFTM_TCP_CLOSING;

4220     else

4221         (*state)->timeout = PFTM_TCP_ESTABLISHED;

4222

4223     return (PF_PASS);

4224 }

There is a special condition at line 4178 and 4179, which only handles
two consecutive ACK packets from A to B. But it does not handle our case
where we got A->B and then B->A ACK packets.

Then the third ACK packet was observed from A to B. In function
tcp_track_sloppy, src->state is ESTABLISHED and dst->state is CLOSED.
The new packet does not match any ACK checks and the state of the
connection stays the same.

The consequence? The state stays in ESTABLISHED (A->B.src) and CLOSED
(A->B.dst). The timeout is thus set to PFTM_TCP_OPENING (30 seconds)
by line 4216. So the state quickly expired and was removed from state
table. The next keep alive packet sequence triggers the same actions
again.

It may not be a big issue but we feel a bit puzzled by the different
results of packet sequence. That is, two consecutive one way packets
will make the state into ESTABLISHED state in both directions, but
two way packets will make state into ESTABLISHED and CLOSED state
and hence expire quickly. Shall we handle the second case in a similar
way as the first case?

Thank you very much for your time!

Best wishes,
Jingmin

--001a1148a526598cf10535d0507a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><font face=3D"monospace, monospace">Hi,<br><br>Recently we=
 ran into some issues with pf sloppy mode with regards to=C2=A0</font><div>=
<font face=3D"monospace, monospace">some long standing TCP connections. Whi=
le reading pf code, we feel=C2=A0</font></div><div><font face=3D"monospace,=
 monospace">puzzled by the way pf handles TCP packets in sloppy mode. Here =
are=C2=A0</font></div><div><font face=3D"monospace, monospace">some of our =
analysis.<br><br>Background: a TCP connection were established between two =
hosts (A=C2=A0</font></div><div><font face=3D"monospace, monospace">and B) =
before pf is enabled in sloppy mode. The connection is mostly</font></div><=
div><font face=3D"monospace, monospace">idle with periodic keep alive packe=
ts, i.e., PUSH-ACK and ACK packets</font></div><div><font face=3D"monospace=
, monospace">every few minutes. An pass rule matches this connection and al=
lows</font></div><div><font face=3D"monospace, monospace">packet to pass th=
rough.<br><br>When a PUSH-ACK packet of the connection was observed from ho=
st A-&gt;B,</font></div><div><font face=3D"monospace, monospace">the pass r=
ule lets pf.c:pf_create_state function to create a new</font></div><div><fo=
nt face=3D"monospace, monospace">state for the connection. In the state, s-=
&gt;src.state =3D TCPS_SYN_SENT,</font></div><div><font face=3D"monospace, =
monospace">and s-&gt;dst.state =3D TCPS_CLOSED (line 3563 and 3564 in the c=
ode below).</font></div><div><font face=3D"monospace, monospace"><br></font=
></div><div><p style=3D"margin:0px;font-size:11px;line-height:normal;color:=
rgb(245,245,245);background-color:rgb(0,0,0)"><font face=3D"monospace, mono=
space"><span style=3D"color:rgb(175,173,36)">3488 </span><span style=3D"bac=
kground-color:rgb(4,51,255)">static</span><span style=3D""> __inline int</s=
pan></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">3489 </span><span style=3D"">pf_create_sta=
te(</span><span style=3D"background-color:rgb(229,33,0)">struct</span><span=
 style=3D""> pf_</span><span style=3D"background-color:rgb(229,33,0)">pdesc=
</span><span style=3D""> *pd, </span><span style=3D"background-color:rgb(22=
9,33,0)">struct</span><span style=3D""> pf_rule *</span><span style=3D"back=
ground-color:rgb(229,33,0)">r</span><span style=3D"">, </span><span style=
=3D"background-color:rgb(229,33,0)">struct</span><span style=3D""> pf_rule =
*a,</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">3490 </span><span style=3D"">=C2=A0 =C2=A0=
 </span><span style=3D"background-color:rgb(229,33,0)">struct</span><span s=
tyle=3D""> pf_rule *</span><span style=3D"background-color:rgb(229,33,0)">n=
r</span><span style=3D"">, </span><span style=3D"background-color:rgb(229,3=
3,0)">struct</span><span style=3D""> pf_state_key **</span><span style=3D"b=
ackground-color:rgb(229,33,0)">skw</span><span style=3D"">, </span><span st=
yle=3D"background-color:rgb(229,33,0)">struct</span><span style=3D""> pf_st=
ate_key **</span><span style=3D"background-color:rgb(229,33,0)">sks</span><=
span style=3D"">,</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">3491 </span><span style=3D"">=C2=A0 =C2=A0=
 int *rewrite, </span><span style=3D"background-color:rgb(229,33,0)">struct=
</span><span style=3D""> pf_state **</span><span style=3D"background-color:=
rgb(229,33,0)">sm</span><span style=3D"">, int tag, </span><span style=3D"b=
ackground-color:rgb(229,33,0)">struct</span><span style=3D""> pf_rule_</spa=
n><span style=3D"background-color:rgb(229,33,0)">slist</span><span style=3D=
""> *rules,</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">3492 </span><span style=3D"">=C2=A0 =C2=A0=
 </span><span style=3D"background-color:rgb(229,33,0)">struct</span><span s=
tyle=3D""> pf_rule_actions *act, </span><span style=3D"background-color:rgb=
(229,33,0)">struct</span><span style=3D""> pf_src_node *</span><span style=
=3D"background-color:rgb(229,33,0)">sns</span><span style=3D"">[PF_SN_MAX])=
</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(175,173,=
36);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span =
style=3D"">3493 </span><span style=3D"color:rgb(245,245,245)">{</span></fon=
t></p><p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(17=
5,173,36);background-color:rgb(0,0,0)"><span style=3D"color:rgb(245,245,245=
)"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0..=
.</font></span></p><p style=3D"margin:0px;font-size:11px;line-height:normal=
;color:rgb(175,173,36);background-color:rgb(0,0,0)"><span style=3D"color:rg=
b(245,245,245)"><font face=3D"monospace, monospace"><br></font></span></p><=
div><p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,=
245,245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><=
span style=3D"color:rgb(175,173,36)">3532 </span><span style=3D"">=C2=A0 =
=C2=A0 switch (pd-&gt;</span><span style=3D"background-color:rgb(229,33,0)"=
>proto</span><span style=3D"">) {</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">3533 </span><span style=3D"">=C2=A0 =C2=A0=
 case </span><span style=3D"background-color:rgb(229,33,0)">IPPROTO</span><=
span style=3D"">_TCP:</span></font></p><p style=3D"margin:0px;font-size:11p=
x;line-height:normal;color:rgb(245,245,245);background-color:rgb(0,0,0)"><s=
pan style=3D""><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0...</font></span></p><p style=3D"margin:0px;font-si=
ze:11px;line-height:normal;color:rgb(245,245,245);background-color:rgb(0,0,=
0)"><font face=3D"monospace, monospace"><span style=3D"color:rgb(175,173,36=
)">3561 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span st=
yle=3D"background-color:rgb(229,33,0)">s</span><span style=3D"">-&gt;dst.</=
span><span style=3D"background-color:rgb(229,33,0)">seqhi</span><span style=
=3D""> =3D 1;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">3562 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 </span><span style=3D"background-color:rgb(229,33,0)">s</spa=
n><span style=3D"">-&gt;dst.max_win =3D 1;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">3563 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 </span><span style=3D"background-color:rgb(229,33,0)">s</spa=
n><span style=3D"">-&gt;src.state </span><span style=3D"color:rgb(168,168,1=
68);background-color:rgb(4,51,255)">=3D TCPS_SYN_SENT</span><span style=3D"=
">;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">3564 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 </span><span style=3D"background-color:rgb(229,33,0)">s</spa=
n><span style=3D"">-&gt;dst.state =3D </span><span style=3D"background-colo=
r:rgb(229,33,0)">TCPS</span><span style=3D"">_CLOSED;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">3565 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 </span><span style=3D"background-color:rgb(229,33,0)">s</spa=
n><span style=3D"">-&gt;timeout =3D </span><span style=3D"background-color:=
rgb(229,33,0)">PFTM</span><span style=3D"">_TCP_FIRST_PACKET;</span></font>=
</p></div><div><p style=3D"margin:0px;font-size:11px;line-height:normal;col=
or:rgb(245,245,245);background-color:rgb(0,0,0)"><font face=3D"monospace, m=
onospace"><span style=3D"color:rgb(175,173,36)">3566 </span><span style=3D"=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;</span></font></p></div><div><font face=
=3D"monospace, monospace"><br></font></div><font face=3D"monospace, monospa=
ce">The second packet is an ACK packet from B to A. It eventually makes</fo=
nt></div><div><font face=3D"monospace, monospace">pf enter into pf.c:pf_tes=
t_state function. A simplified code flow</font></div><div><font face=3D"mon=
ospace, monospace">is shown as below:<br><br></font><p style=3D"margin:0px;=
font-size:11px;line-height:normal;color:rgb(175,173,36);background-color:rg=
b(0,0,0)"><font face=3D"monospace, monospace"><span style=3D"">4320 </span>=
<span style=3D"color:rgb(245,245,245);background-color:rgb(4,51,255)">int</=
span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4321 </span><span style=3D"color:rgb(168,1=
68,168);background-color:rgb(4,51,255)">pf_test_state</span><span style=3D"=
">(</span><span style=3D"background-color:rgb(229,33,0)">struct</span><span=
 style=3D""> pf_</span><span style=3D"background-color:rgb(229,33,0)">pdesc=
</span><span style=3D""> *pd, </span><span style=3D"background-color:rgb(22=
9,33,0)">struct</span><span style=3D""> pf_state **state, </span><span styl=
e=3D"background-color:rgb(229,33,0)">u</span><span style=3D"">_short *reaso=
n)</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(175,173,=
36);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span =
style=3D"">4322 </span><span style=3D"color:rgb(245,245,245)">{</span></fon=
t></p><p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(17=
5,173,36);background-color:rgb(0,0,0)"><span style=3D"color:rgb(245,245,245=
)"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0..=
.</font></span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4338 </span>=C2=A0 =C2=A0 STATE_LOOKUP(pd-=
&gt;<span style=3D"background-color:rgb(0,230,229)">kif</span>, &amp;key, p=
d-&gt;<span style=3D"background-color:rgb(229,33,0)">dir</span>, *state, pd=
-&gt;m);<br></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(175,173,=
36);background-color:rgb(0,0,0)"><span style=3D""><font face=3D"monospace, =
monospace">4339=C2=A0</font></span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4340 </span><span style=3D"">=C2=A0 =C2=A0=
 </span><span style=3D"background-color:rgb(4,51,255)">if</span><span style=
=3D""> (pd-&gt;</span><span style=3D"background-color:rgb(229,33,0)">dir</s=
pan><span style=3D""> =3D=3D (*state)-&gt;direction) {</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4341 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 src =3D &amp;(*state)-&gt;src;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4342 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 dst =3D &amp;(*state)-&gt;dst;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4343 </span><span style=3D"">=C2=A0 =C2=A0=
 } else {</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4344 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 src =3D &amp;(*state)-&gt;dst;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4345 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 dst =3D &amp;(*state)-&gt;src;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4346 </span><span style=3D"">=C2=A0 =C2=A0=
 }</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(175,173,=
36);background-color:rgb(0,0,0)"><span style=3D""><font face=3D"monospace, =
monospace">4347=C2=A0</font></span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4348 </span><span style=3D"">=C2=A0 =C2=A0=
 </span><span style=3D"background-color:rgb(4,51,255)">switch</span><span s=
tyle=3D""> (pd-&gt;virtual_</span><span style=3D"background-color:rgb(229,3=
3,0)">proto</span><span style=3D"">) {</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4349 </span><span style=3D"">=C2=A0 =C2=A0=
 case </span><span style=3D"background-color:rgb(229,33,0)">IPPROTO</span><=
span style=3D"">_TCP:</span></font></p><p style=3D"margin:0px;font-size:11p=
x;line-height:normal;color:rgb(245,245,245);background-color:rgb(0,0,0)"><s=
pan style=3D""><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0...</font></span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4369 </span>=C2=A0 =C2=A0 =C2=A0 =C2=A0 <s=
pan style=3D"background-color:rgb(4,51,255)">if</span> ((*state)-&gt;state_=
flags &amp; <span style=3D"background-color:rgb(229,33,0)">PFSTATE</span>_S=
LOPPY) {<br></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4370 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (pf_</span><span style=3D"background-color:=
rgb(229,33,0)">tcp</span><span style=3D"">_track_sloppy(pd, src, dst, state=
, reason) =3D=3D</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4371 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 PF_DROP)</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4372 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (PF_DROP);</span></font><=
/p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4373 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 } else {</span></font></p><p style=3D"margin:0px;font-size:1=
1px;line-height:normal;color:rgb(245,245,245);background-color:rgb(0,0,0)">=
<span style=3D""><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0...</font></span></p><div><p style=3D"margin:0px;font-size:11p=
x;line-height:normal;color:rgb(175,173,36);background-color:rgb(0,0,0)"><fo=
nt face=3D"monospace, monospace"><span style=3D"">4465 </span><span style=
=3D"color:rgb(245,245,245)">}</span></font></p></div><div><font face=3D"mon=
ospace, monospace"><br></font></div><font face=3D"monospace, monospace">Ple=
ase notice that src and dst are taken from state entry and are=C2=A0</font>=
</div><div><font face=3D"monospace, monospace">swapped at line 4344 and 434=
5 before being passed into function</font></div><div><font face=3D"monospac=
e, monospace">pf_tcp_track_sloppy. So the src has a state TCPS_CLOSED and d=
st</font></div><div><font face=3D"monospace, monospace">has a state TCPS_SY=
N_SENT in function pf_tcp_track_sloppy.</font></div><div><font face=3D"mono=
space, monospace"><br></font></div><div><font face=3D"monospace, monospace"=
>Below, a simplified pf_tcp_track_sloppy is shown. As we can see,</font></d=
iv><div><font face=3D"monospace, monospace">the ACK packet from B to A will=
 match condition at line 4168. So</font></div><div><font face=3D"monospace,=
 monospace">the state now changes to ESTABLISHED (A-&gt;B.src) and CLOSED (=
A-&gt;B.</font></div><div><font face=3D"monospace, monospace">dst).</font><=
/div><div><font face=3D"monospace, monospace"><br></font><p style=3D"margin=
:0px;font-size:11px;line-height:normal;color:rgb(175,173,36);background-col=
or:rgb(0,0,0)"><font face=3D"monospace, monospace"><span style=3D"">4155 </=
span><span style=3D"color:rgb(245,245,245);background-color:rgb(4,51,255)">=
int</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4156 </span><span style=3D"color:rgb(168,1=
68,168);background-color:rgb(4,51,255)">pf_tcp_track_sloppy</span><span sty=
le=3D"">(</span><span style=3D"background-color:rgb(229,33,0)">struct</span=
><span style=3D""> pf_</span><span style=3D"background-color:rgb(229,33,0)"=
>pdesc</span><span style=3D""> *pd, </span><span style=3D"background-color:=
rgb(229,33,0)">struct</span><span style=3D""> pf_state_peer *src,</span></f=
ont></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4157 </span><span style=3D"">=C2=A0 =C2=A0=
 </span><span style=3D"background-color:rgb(229,33,0)">struct</span><span s=
tyle=3D""> pf_state_peer *dst, </span><span style=3D"background-color:rgb(2=
29,33,0)">struct</span><span style=3D""> pf_state **state, </span><span sty=
le=3D"background-color:rgb(229,33,0)">u</span><span style=3D"">_short *reas=
on)</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(175,173,=
36);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span =
style=3D"">4158 </span><span style=3D"color:rgb(245,245,245)">{</span></fon=
t></p><p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(17=
5,173,36);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace">=
<span style=3D"color:rgb(245,245,245)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0..=
.</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4167 </span>=C2=A0 =C2=A0 if (th-&gt;th_fl=
ags &amp; TH_<span style=3D"background-color:rgb(229,33,0)">ACK</span>) {<b=
r></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4168 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 if (dst-&gt;state =3D=3D </span><span style=3D"background-co=
lor:rgb(229,33,0)">TCPS</span><span style=3D"">_SYN_SENT) {</span></font></=
p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4169 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst-&gt;state =3D </span><span style=3D"backgr=
ound-color:rgb(229,33,0)">TCPS</span><span style=3D"">_ESTABLISHED;</span><=
/font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4170 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (src-&gt;state =3D=3D </span><span style=3D=
"background-color:rgb(229,33,0)">TCPS</span><span style=3D"">_ESTABLISHED &=
amp;&amp;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4171 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 !</span><span style=3D"backgroun=
d-color:rgb(229,33,0)">SLIST</span><span style=3D"">_EMPTY(&amp;(*state)-&g=
t;src_nodes) &amp;&amp;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4172 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pf_src_</span><span style=3D"bac=
kground-color:rgb(229,33,0)">connlimit</span><span style=3D"">(state)) {</s=
pan></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4173 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 REASON_SET(reason, </span><span =
style=3D"background-color:rgb(229,33,0)">PFRES</span><span style=3D"">_</sp=
an><span style=3D"background-color:rgb(229,33,0)">SRCLIMIT</span><span styl=
e=3D"">);</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4174 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (PF_DROP);</span></font><=
/p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4175 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4176 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 } else if (dst-&gt;state =3D=3D </span><span style=3D"backgr=
ound-color:rgb(229,33,0)">TCPS</span><span style=3D"">_CLOSING) {</span></f=
ont></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4177 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst-&gt;state =3D </span><span style=3D"backgr=
ound-color:rgb(229,33,0)">TCPS</span><span style=3D"">_FIN_WAIT_2;</span></=
font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4178 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 } else if (src-&gt;state =3D=3D </span><span style=3D"backgr=
ound-color:rgb(229,33,0)">TCPS</span><span style=3D"">_SYN_SENT &amp;&amp;<=
/span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4179 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst-&gt;state &lt; </span><span style=3D"backg=
round-color:rgb(229,33,0)">TCPS</span><span style=3D"">_SYN_SENT) {</span><=
/font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4180 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /*</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4181=C2=A0</span><span style=3D""> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * Handle a special sloppy case where we =
only see one</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4182=C2=A0</span><span style=3D""> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * half of the connection. If there is a =
</span><span style=3D"background-color:rgb(229,33,0)">ACK</span><span style=
=3D""> after</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4183=C2=A0</span><span style=3D""> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * the initial SYN without ever seeing a =
packet from</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4184=C2=A0</span><span style=3D""> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * the destination, set the connection to=
 established.</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4185=C2=A0</span><span style=3D""> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4186 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst-&gt;state =3D src-&gt;state =3D </span><sp=
an style=3D"background-color:rgb(229,33,0)">TCPS</span><span style=3D"">_ES=
TABLISHED;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4187 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!</span><span style=3D"background-color:rg=
b(229,33,0)">SLIST</span><span style=3D"">_EMPTY(&amp;(*state)-&gt;src_node=
s) &amp;&amp;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4188 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pf_src_</span><span style=3D"bac=
kground-color:rgb(229,33,0)">connlimit</span><span style=3D"">(state)) {</s=
pan></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4189 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 REASON_SET(reason, </span><span =
style=3D"background-color:rgb(229,33,0)">PFRES</span><span style=3D"">_</sp=
an><span style=3D"background-color:rgb(229,33,0)">SRCLIMIT</span><span styl=
e=3D"">);</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4190 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return (PF_DROP);</span></font><=
/p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4191 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4192 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 } else if (src-&gt;state =3D=3D </span><span style=3D"backgr=
ound-color:rgb(229,33,0)">TCPS</span><span style=3D"">_CLOSING &amp;&amp;</=
span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4193 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst-&gt;state =3D=3D </span><span style=3D"bac=
kground-color:rgb(229,33,0)">TCPS</span><span style=3D"">_ESTABLISHED &amp;=
&amp;</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4194 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst-&gt;</span><span style=3D"background-color=
:rgb(229,33,0)">seqlo</span><span style=3D""> =3D=3D 0) {</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4195 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /*</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4196=C2=A0</span><span style=3D""> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * Handle the closing of half connections=
 where we</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4197=C2=A0</span><span style=3D""> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * don&#39;t see the full bidirectional F=
IN/</span><span style=3D"background-color:rgb(229,33,0)">ACK</span><span st=
yle=3D"">+</span><span style=3D"background-color:rgb(229,33,0)">ACK</span><=
/font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4198=C2=A0</span><span style=3D""> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * handshake.</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4199=C2=A0</span><span style=3D""> =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4200 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst-&gt;state =3D </span><span style=3D"backgr=
ound-color:rgb(229,33,0)">TCPS</span><span style=3D"">_CLOSING;</span></fon=
t></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4201 </span><span style=3D"">=C2=A0 =C2=A0=
 =C2=A0 =C2=A0 }</span></font></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;color:rgb(245,245,=
245);background-color:rgb(0,0,0)"><font face=3D"monospace, monospace"><span=
 style=3D"color:rgb(175,173,36)">4202 </span><span style=3D"">=C2=A0 =C2=A0=
 }</span></font></p><div><p style=3D"margin:0px;font-size:11px;line-height:=
normal;font-family:Monaco;color:rgb(245,245,245);background-color:rgb(0,0,0=
)"><span style=3D"color:rgb(175,173,36)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
..</span></p><p style=3D"margin:0px;font-size:11px;line-height:normal;font=
-family:Monaco;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span st=
yle=3D"color:rgb(175,173,36)">4206 </span><span style=3D"">=C2=A0 =C2=A0 /*=
 update expire time */</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4207 </span><span style=3D"">=C2=A0 =C2=A0 (*state)-&gt;exp=
ire =3D time_uptime;</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4208 </span><span style=3D"">=C2=A0 =C2=A0 if (src-&gt;stat=
e &gt;=3D </span><span style=3D"background-color:rgb(229,33,0)">TCPS</span>=
<span style=3D"">_FIN_WAIT_2 &amp;&amp;</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4209 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ds=
t-&gt;state &gt;=3D </span><span style=3D"background-color:rgb(229,33,0)">T=
CPS</span><span style=3D"">_FIN_WAIT_2)</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4210 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 </=
span><span style=3D"background-color:rgb(0,166,178)">(</span><span style=3D=
"">*state</span><span style=3D"background-color:rgb(0,166,178)">)</span><sp=
an style=3D"">-&gt;timeout =3D </span><span style=3D"background-color:rgb(2=
29,33,0)">PFTM</span><span style=3D"">_TCP_CLOSED;</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4211 </span><span style=3D"">=C2=A0 =C2=A0 else if (src-&gt=
;state &gt;=3D </span><span style=3D"background-color:rgb(229,33,0)">TCPS</=
span><span style=3D"">_CLOSING &amp;&amp;</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4212 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ds=
t-&gt;state &gt;=3D </span><span style=3D"background-color:rgb(229,33,0)">T=
CPS</span><span style=3D"">_CLOSING)</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4213 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 (*=
state)-&gt;timeout =3D </span><span style=3D"background-color:rgb(229,33,0)=
">PFTM</span><span style=3D"">_TCP_FIN_WAIT;</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4214 </span><span style=3D"">=C2=A0 =C2=A0 else if (src-&gt=
;state &lt; </span><span style=3D"background-color:rgb(229,33,0)">TCPS</spa=
n><span style=3D"">_ESTABLISHED ||</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4215 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ds=
t-&gt;state &lt; </span><span style=3D"background-color:rgb(229,33,0)">TCPS=
</span><span style=3D"">_ESTABLISHED)</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4216 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 (*=
state)-&gt;timeout =3D </span><span style=3D"background-color:rgb(229,33,0)=
">PFTM</span><span style=3D"">_TCP_OPENING;</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4217 </span><span style=3D"">=C2=A0 =C2=A0 else if (src-&gt=
;state &gt;=3D </span><span style=3D"background-color:rgb(229,33,0)">TCPS</=
span><span style=3D"">_CLOSING ||</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4218 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 ds=
t-&gt;state &gt;=3D </span><span style=3D"background-color:rgb(229,33,0)">T=
CPS</span><span style=3D"">_CLOSING)</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4219 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 (*=
state)-&gt;timeout =3D </span><span style=3D"background-color:rgb(229,33,0)=
">PFTM</span><span style=3D"">_TCP_CLOSING;</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4220 </span><span style=3D"">=C2=A0 =C2=A0 else</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4221 </span><span style=3D"">=C2=A0 =C2=A0 =C2=A0 =C2=A0 (*=
state)-&gt;timeout =3D </span><span style=3D"background-color:rgb(229,33,0)=
">PFTM</span><span style=3D"">_TCP_ESTABLISHED;</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(175,173,36);background-color:rgb(0,0,0)"><span style=3D"">4222=
=C2=A0</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(245,245,245);background-color:rgb(0,0,0)"><span style=3D"color:r=
gb(175,173,36)">4223 </span><span style=3D"">=C2=A0 =C2=A0 </span><span sty=
le=3D"background-color:rgb(4,51,255)">return</span><span style=3D""> (PF_PA=
SS);</span></p>
<p style=3D"margin:0px;font-size:11px;line-height:normal;font-family:Monaco=
;color:rgb(175,173,36);background-color:rgb(0,0,0)"><span style=3D"">4224 <=
/span><span style=3D"color:rgb(245,245,245)">}</span></p></div></div><div><=
span style=3D"color:rgb(245,245,245)"><br></span></div><div><span style=3D"=
"><font face=3D"monospace, monospace">There is a special condition at line =
4178 and 4179, which only handles</font></span></div><div><span style=3D"">=
<font face=3D"monospace, monospace">two consecutive=C2=A0</font></span><spa=
n style=3D"font-family:monospace,monospace">ACK packets from A to B. But it=
 does not handle our case</span></div><div><span style=3D"font-family:monos=
pace,monospace">where we got A-&gt;B and then B-&gt;A ACK packets.</span></=
div><div><span style=3D"font-family:monospace,monospace"><br></span></div><=
div><span style=3D"font-family:monospace,monospace">Then the third ACK pack=
et was observed from A to B. In function=C2=A0</span></div><div><span style=
=3D"font-family:monospace,monospace">tcp_track_sloppy, src-&gt;state is EST=
ABLISHED and dst-&gt;state is CLOSED.</span></div><div><span style=3D"font-=
family:monospace,monospace">The new packet does not match any ACK checks an=
d the state of the=C2=A0</span></div><div><span style=3D"font-family:monosp=
ace,monospace">connection stays the same</span><span style=3D"font-family:m=
onospace,monospace">.=C2=A0</span></div><div><span style=3D""><font face=3D=
"monospace, monospace"><br></font></span></div><div><span style=3D""><font =
face=3D"monospace, monospace">The consequence? The state stays in ESTABLISH=
ED (A-&gt;B.src) and CLOSED</font></span></div><div><span style=3D""><font =
face=3D"monospace, monospace">(A-&gt;B.dst)</font></span><span style=3D"fon=
t-family:monospace,monospace">. The timeout is thus set to PFTM_TCP_OPENING=
 (30 seconds)</span></div><div><span style=3D"font-family:monospace,monospa=
ce">by line=C2=A0</span><span style=3D"font-family:monospace,monospace">421=
6. So the state quickly expired and was removed from state</span></div><div=
><span style=3D"font-family:monospace,monospace">table.=C2=A0</span><span s=
tyle=3D"font-family:monospace,monospace">The next keep alive packet sequenc=
e triggers the same actions</span></div><div><span style=3D"font-family:mon=
ospace,monospace">again.</span></div><div><span style=3D""><font face=3D"mo=
nospace, monospace"><br></font></span></div><div><span style=3D""><font fac=
e=3D"monospace, monospace">It may not be a big issue but we feel a bit puzz=
led by the different</font></span></div><div><span style=3D""><font face=3D=
"monospace, monospace">results=C2=A0</font></span><span style=3D"font-famil=
y:monospace,monospace">of packet sequence. That is, two consecutive one way=
 packets=C2=A0</span></div><div><span style=3D"font-family:monospace,monosp=
ace">will make=C2=A0</span><font face=3D"monospace, monospace">the state in=
to ESTABLISHED state in both directions, but=C2=A0</font></div><div><font f=
ace=3D"monospace, monospace">two=C2=A0</font><span style=3D"font-family:mon=
ospace,monospace">way=C2=A0</span><span style=3D"font-family:monospace,mono=
space">packets=C2=A0</span><span style=3D"font-family:monospace,monospace">=
will make state into ESTABLISHED and CLOSED state=C2=A0</span></div><div><s=
pan style=3D"font-family:monospace,monospace">and hence expire=C2=A0</span>=
<span style=3D"font-family:monospace,monospace">quickly. Shall we handle th=
e second case in a similar</span></div><div><span style=3D"font-family:mono=
space,monospace">way as the first case?</span></div><div><span style=3D"fon=
t-family:monospace,monospace"><br></span></div><div><span style=3D"font-fam=
ily:monospace,monospace">Thank you very much for your time!</span></div><di=
v><span style=3D"font-family:monospace,monospace"><br></span></div><div><sp=
an style=3D"font-family:monospace,monospace">Best wishes,</span></div><div>=
<span style=3D"font-family:monospace,monospace">Jingmin</span></div><div><s=
pan style=3D"font-family:monospace,monospace"><br></span></div><div><span s=
tyle=3D"font-family:monospace,monospace"><br></span></div><div><span style=
=3D"font-family:monospace,monospace"><br></span></div></div>

--001a1148a526598cf10535d0507a--