On Mon, Jun 13, 2005 at 06:57:50PM -0700, Michael Coulter wrote:
> pf: BAD state: TCP linux_server:43541 linux_server:43541
> other_server:443 [lo=1144898851 high=1144915311 win=5840
> modulator=389869126 wscale=0] [lo=2177039318 high=2177044306 win=16560
> modulator=1496631458 wscale=0] 4:4 R seq=2177039318 ack=1144898851
> len=0 ackskew=0 pkts=29:17 dir=in,rev
> pf: State failure on: |
>
> Should there be more info on the second line ? Am I seeing an unhandled
> case in the debug output ?
The second line should contain at least one digit indicating which of
the comparisons failed. You get none, which I haven't seen before.
Looking at the source, there's only one way this can happen, if
((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
(pd->flags & PFDESC_IP_REAS) == 0)) {
is false. Yet, you have seq=2177039318 in the first line, which equals
src->seqlo. So, orig_seq must be != seq, which can happen due to
if (seq == end) {
/* Ease sequencing restrictions on no data packets */
seq = src->seqlo;
end = seq;
}
Can you patch pf.c like
printf(" seq=%u ack=%u len=%u ackskew=%d pkts=%d:%d "
- "dir=%s,%s\n", seq, ack, pd->p_len, ackskew,
+ "dir=%s,%s\n", orig_seq, ack, pd->p_len, ackskew,
(*state)->packets[0], (*state)->packets[1],
direction == PF_IN ? "in" : "out",
direction == (*state)->direction ? "fwd" : "rev");
and capture another message?
We demand a precise match on th_seq for RSTs to make it harder for
spoofers to reset connections guessing sequence numbers. For some
reason, one of the peers is sending a RST with an off-by-some th_seq.
How far off we'll see in the next message from the patched kernel.
> Couple of other questions here, can I find out
> what interface this check is happening on ? And what exactly do "in" and
> "rev" mean here ?
"in" means the state entry was created for an incoming packet (pass in
keep state) on some interface (vs. outgoing). "rev" means the packet
being blocked (and logged in the message) was flowing in the reverse
direction compared to the initial one, i.e. outgoing in this case.
The interface is not immediately visible, but if you create if-bound
states and compare the log message with your state entries (pfctl
-vvss), you see the interface in the matching state entry.
Daniel