The anatomy of a TCP
connection
TCP is equipped with
6 ``flags'', which may be ON or OFF. These flags are:
FIN
``Controlled'' connection close
SYN
Open new connection
RST
``Immediate'' connection close
PSH
Instruct receiver host to push the data up
to the application rather
than just queue
it
ACK
``Acknowledge'' a previous packet
URG
``Urgent'' data which needs to be
processed immediately
In this example,
your client is 5.6.7.8, and the port assigned to you
dynamically is 1049. The server is 1.2.3.4, port 80.
You begin the
connection attempt:
5.6.7.8:1049 ->
1.2.3.4:80 SYN=ON
The server receives
this packet and understands that someone wants to form a
new connection. A response is sent:
1.2.3.4:80 ->
5.6.7.8:1049 SYN=ON ACK=ON
The client receives
the response, and informs that the response is received
5.6.7.8:1049 ->
1.2.3.4:80 ACK=ON
Here, the connection
is opened. This is called a three-way handshake. Its
purpose is to verify to BOTH hosts that they have a
working connection
between them.
The internet being
what it is, unreliable and flooded, there are provisions
to compensate for packet loss.
If the client sends
out the initial SYN without receiving a SYN+ACK within a
few seconds, it'll resend the SYN.
If the server sends
out the SYN+ACK without receiving an ACK in a few
seconds, it'll resend the SYN+ACK packet.
The latter is
actually the reason that SYN flooding works so well. If you
send out SYN packets from lots of different
ports, this will tie up a lot of
resources on the server. If you also refuse to respond
to the returned
SYN+ACK packets, the
server will KEEP these connections for a long time,
resending the SYN+ACK packets. Some servers will not
accept new connections
while there are enough connections currently
forming; this is why SYN
flooding works.
All packets
transmitted in either direction after the three-way handshake
will have the ACK bit set. Stateless packet
filters make use of this in the
so called ``established'' filters: They will
only let packets through that
have the ACK bit set. This way, no packet may
pass through in a certain
direction that could form a new connection. Typically,
you don't allow
outside hosts to open new connections to inside
hosts by requiring the ACK
bit set on these packets.
When the time has
come to close the connection, there are two ways of doing
it: Using the FIN flag, or using the RST flag.
Using FIN flags, both
implementations are required to send out FIN flags to
indicate that they
want to close the connection, and then send out
acknowledgements to these
FINs, indicating that they understood that the
other end wants to close the
connection. When sending out RST's,
the connection is closed forcefully, and
you don't really get an indication of whether
the other end understood your
reset order, or that it has in fact received all
data that you sent to it.
The FIN way of
closing the connection also exposes you to a
denial-of-service situation, since the TCP stack needs to
remember the
closed connection for a fairly long time, in case
the other end hasn't
received one of the FIN packets.
If sufficiently many
connections are opened and closed, you may end up
having ``closed'' connections in all your
connection slots. This way, you
wouldn't be able to dynamically allocate more
connections, seeing that
they're all used. Different OSes
handle this situation differently.