In response to your second set of questions - the sequence numbers on the double syns are generally that close - I haven't seen any that are wildly different. I'll just have to try to hunt down problems on that machine (bad TCP stack or something) or try to get the client fixed/upgraded by the company.
-David
Daniel Hartmeier wrote:
On Fri, Apr 11, 2003 at 11:03:57AM -0400, David Powers wrote:
1. Has anyone ever seen a client try to double start a connection before with almost no time elapsing?
No, using the same quadruple of source/destination address/port for two concurrent connections (with different sequence numbers) is not valid. The RFC requires that each peer waits 2MSL (maximum segment lifetime, about 60 seconds) before re-using the same quadruple for another connection.
It looks like there is something seriously wrong with that client. And it's not just a problem in a userland process, as the TCP/IP stack should never send out such packets. Can you verify it's really the client sending out those two concurrent SYNs, or could it be some appliance in between (may the one doing NAT) that might be introducing the second SYN? What kind of program is "RealTik", running on what OS?
2. Where are the RST packets from the client going? The states are listed as FIN_WAIT_2, which indicates that the firewall got the RST packet and is waiting for a close from both sides. My state rules pass in on flags S for TCP and modulate state, which seems to work dandy for everything else I've tried.
The first SYN from the client is creating the state entry, and it defines the valid sequence number windows. The second outgoing SYN obviously matches the windows (it's close enough) and gets passed. (BTW, if you repeat the procedure, are the two initial sequence numbers of the two SYNs always that close?)
The external host, too, uses the first SYN as reference.
As soon as pf sees the peer's SYN+ACK, it narrows the windows for th_seq and th_ack.
But the client obviously uses the second SYN as reference, and issues RSTs for the peer's SYN+ACKs. But since they don't match pf's windows, they get blocked.
I don't see how the client could ever successfully establish a connection with the external peer like that. pf in OpenBSD 3.3 and -current will send a RST when it sees such mismatching packets during the TCP handshake, which should prevent the retransmissions in your case, too. But as long as the client sends two concurrent SYNs and expects the _second_ to matter (while both pf and most peers will use the first one), I don't see how a connection could be established. How does the client establish a connection if you disable pf?
3. On the assumption that this is caused by the broken client behavior interacting poorly with state tracking, should I attempt to fix it by adding rules to pass out quick TCP packets with only RST set? Seems like a hack, but if the client is broken there may be no other way.
As soon as there is a state entry, packets that match the addresses/ports quadruple will no longer cause ruleset evaluation. Either the sequence numbers match (then the packet is passed), or they don't (then the packet is dropped), with an RST issued by recent pf, if it happens during the TCP handshake.
So I guess you'd have to filter those connections statelessly (not create state with 'keep/modulate state').
But it might be worth investigating why the client is acting this way, and whether it can be fixed.
Daniel
