DennisCGc wrote:
Solar wrote:
You mean you never encountered an unspecified source address, invalid CRC, too-large / too-small package, or any other inconsistency with what the RFC's tell you?
No, the format is the same as said in the rfcs, the "fields" are the same.
That's true. The specification says that these are packets that conform to TCP, and does not specify what you should do with other packets, that include TCP packets with errors and non-TCP packets. Also, seeing the checksum is correct doesn't mean the packet is valid TCP. The entire point of the CRC is not to call the others non-tcp, it's to more or less guarantee the integrity of this packet as a TCP packet with those fields. Most, if not all, of the other "deviations" are caused by bugs or by software actually not implementing TCP.
The only thing you should learn from this style of packet sending, is that you should check, double check and triple-check every byte you get, for validity. Is the source address not from a network explicitly connected to a different cable (IP spoofing), is there an invalid combination of flags (or, check all the valid combinations and if none is found, drop it), is the checksum correct, is this the Nth SYN packet from a certain host within X seconds, is this packet part of a connection, if it isn't, how did it get here, if it is, does the sequence number correspond, check for holes, go-back-N and SR implementation choices, fast retransmission, delay timers...
The point of this sentence was to show you TCP is hard. The only thing you should really learn from it is that you must always distrust things you cannot be 100% perfectly sure of, and keep every possible input value within reasonability.
Also, you have a lot of implementation-defined points, and you need a high-quality timer (with very little overhead) for the packet sending.
You might want to make it a dedicated TCP-only timer (one that keeps a list and always appends to the end, which is faster than searching through it).
As I've got an idea how to, follow me:
You implement a timer with an add function and a remove function. Each timer is a static 30seconds. That means, 3000 hundreds of a second. You have an int in there. It represents the most recent time you added a packet, or if none, the current time minus 3000 (or zero, make that a kludge). You have a function that can tell you what the hundredths-count of the moment is.
Adding a packet takes the current time minus the last-time-added time, giving you the time between the last packet added and this one in hundreds of a second. Add this one to the end of the list with that delay.
Removing a packet is hard. Because you'd have to traverse the list, it's also unpractical, because it's not O(1). This timer should scale very well, so let's not add an O(n) function to it.
Instead of actually removing it, you add it to a list of removed-packets. This sounds really crooked, but it works nicely.
Every time you get a timer pulse you loop through all the packets with time_to_finish < 10 (nobody shoots a tenth of a second, and this prevents you from requesting a hundredth second delay). You compare its identifier with the one at the top of the removed-stack. If they are equal, you remove both and don't resend. If it is not equal, the packet was not responded to within the 30s limit. Resend the packet, increase its count and add it to the back of the list with the add-function.
Note that this algorithm assumes you use go-back-N. In selective repeat the acks can appear in any order, so the order of the remove-list can not be guaranteed. However, it's only really useful to use SR on low-bandwidth lines on which the order can be changed.
I didn't mean that ::) , but the changes in TCP/IP, how could the OS work with it ?
Since TCP/IP is the most used protocol, a change of the protocol should not be toleranted, that's what I think.
Let's try using some of the reserved fields. Add an option field. Change the meaning of one of the fields. There are so many examples of people doing this... (think Cisco with their QoS ideas).