Dominance of TAO
T/TCP is not subjective to packet sniffing more easily than TCP. But after being sniffed, it's indeed much easier for a cracker to fake T/TCP connections than TCP ones, due to TAO mechanism.
The Numbers Game
Current TAO mechanism is really too simple. There is only one requirement to pass TAO test: received CC value is larger than cached CC value on the server. Even worse, CC is an unsigned 32-bit integer which is, according to RFC1644, initialized to 1 when the machine starts up. As a result, a fabricated large value (such as 2^32 -1) has a nearly definite chance of passing TAO test. This can be a serious security hole. Therefore, TAO mechanism should be enhanced.
- Make CC a socket variable instead of a global one
- Make CC randomly initialized
SYN cookie cannot be used with T/TCP since no TCP options can be saved when SYN cookie are in use. However, it's an inherent problem in SYN cookie and not a fault at all of T/TCP. With SYN cookie, no TCP extensions with TCP options are possible, not only T/TCP. Generally, there are two ways to defend against SYN flooding: SYN cache and SYN cookie. With SYN cache, the amount of memory for states is reduced greatly, thus making SYN flooding much more expensive but never eradicating the possibility. SYN cookie eliminates the need for storing states with the price of losing any TCP option.
Failed TAO resulting in queued data
According to RFC1644, when TAO fails, the protocol falls back to TCP but the data sent in the SYN packet is queued to decrease overhead and increase throughput. However, deliberately failing TAO during SYN flooding can be quite easy but destructive. In order for T/TCP to be safer and completely back compatible with TCP, the data should be discarded and sent again after the 3-way handshake succeeds.
This attack is completely based upon "Dominance of TAO". If TAO can't be dominated as claimed above, "Trust Relationship" attack on T/TCP is, at least, as difficult as on standard TCP.
Duplicate delivery is an inherent problem in RPC, which is called "Server Crash". Fairly speaking, T/TCP shouldn't be blamed for it.
"Server Crash" can happen in two ways:
- After receiving and before execution
- After execution and before responding
Unfortunately, the client can't tell any difference between those two kinds of server crashes. All it knows is response timeout.
Facing this problem, 3 choices are available:
- The client waits until the server finishes reboot, after which the client resends the request. This technique is called "at least once semantics".
- The client gives up and reports failure. This technique is called "at most once semantics".
- No special action is taken. The client gets no help or guarantee. On the server side, RPC may be executed many times, or not at all. Obviously, the merit is ease of implementation.
The above 3 choices are not ideal. The ideal one is "exactly once semantics" which is very difficult to realize.
- The client assigns a sequence number to every packet it transmits. And the server stores the latest sequence number it receives from the client.
- The client sets a certain bit when marking a packet retransmitted.
In real-life implementations, it's the application layer that shoulders the responsibility.