The first Syn Flood attack occurred against Panix, the New York City area’s oldest and largest Internet Service Provider (ISP), on September 6, 1996, at about 5:30 p.m. The weakness in the connection-oriented TCP transportation protocol was known and understood for many years prior to the Panix attack, However, although Panix overcame this attack, the new threat SYN Flood made administrators worry.

TCP Background Information

TCP is a connection-oriented, reliable transport protocol.  TCP is responsible for hiding network intricacies from the upper layers.  A connection-oriented protocol implies that the two hosts participating in a  discussion must first establish a connection before data may be exchanged.  In TCP’s case, this is done with the three-way handshake.  Reliability can be  provided in a number of ways, but the only two we are concerned with are data  sequencing and acknowledgement.  TCP assigns sequence numbers to every byte in every segment and acknowledges all data bytes received from the other end . In order to exchange data using TCP, hosts must establish a connection. TCP establishes a connection in a 3 step process called the 3-way handshake. If machine A is running a client program and wishes to connect to a server program on machine B, the process is as follows:

Machine A send TCP segment with Syn flag on to machine B

Machine B answer with Syn/Ack that he accept to communicate with machine A

Machine A acknowledges with segment with Ack flag set and communication begin


To grant simultaneous access to the TCP module, TCP provides a user  interface called a port.  Ports are used by the kernel to identify network  processes.  They are strictly transport layer entities.  Together with an IP address, a TCP port provides an endpoint for network  communications.  In fact, at any given moment *all* Internet connections can be described by 4 numbers: the source IP address and source port and the destination IP address and destination port.  Servers are bound to  ‘well-known’ ports so that they may be located on a standard port on different systems.  For example, the telnet daemon sits on TCP port 23. For a copious treatment of the topic of SYN flooding, it is necessary to look at the memory structures that TCP creates when a client SYN arrives and the connection is pending (that is, a connection that is somewhere in the process of the three-way handshake and TCP is in the SYN_SENT or  SYN_RVCD state).


Under BSD style network code, for any given pending TCP connection  there are three memory structures that are allocated (we do not discuss the  process (proc) structure and file structure, but the reader should be aware that they exist as well):

Socket Structure (socket{}): Holds the information related to the local end of the communications link: protocol used, state information, addressing information, connection queues, buffers, and flags.

Internet Protocol Control Block Structure (inpcb{}): PCB’s are used at the transport layer by TCP (and UDP) to hold various pieces of information needed by TCP.  They hold: TCP state information, IP address information, port numbers, IP header prototype and options and a pointer to the routing table entry for the destination address.  PCB’s are created for a given TCP based server when the server calls listen(),

TCP Control Block Structure (tcpcb{}): The TCP control block contains TCP specific information such as timer information, sequence number information, flow control status, and OOB data.


Linux uses a different scheme of memory allocation to hold network information.  The socket structure is still used, but instead of the pcb{} and tcpcb{}, we have:

Sock Structure (sock{}): Protocol specific information, most of the data structures are TCP related.  This is a huge structure.

SK Structure (sk_buff{}): Holds more protocol specific information including packet header information, also contains a sock{}.

According to Alan Cox:

The inode is the inode holding the socket (this may be a dummy inode for non file system sockets like IP), the socket holds generic high level methods and the struct sock is the protocol specific object, although all but a few experimental high performance items use the same generic struct sock and support code. That holds chains of linear buffers (struct sk_buff’s).

[struct inode -> struct socket -> struct sock -> chains of sk_buff’s]

The Backlog Queue

These are large memory structures.  Every time a client SYN arrives on a valid port (a port where a TCP server is listen()ing), they must be  allocated.  If there were no limit, a busy host could easily exhaust all of it’s memory just trying to process TCP connections.  (This would be an even simpler DOS attack.)  However, there is an upper limit to amount of  concurrent connection requests a given TCP can have outstanding for a given socket.  This limit is the backlog and it is the length of the queue where incoming (as yet incomplete) connections are kept.  This queue limit  applies to both the number of incomplete connections (the 3-way handshake has not been completed) and the number of completed connections that have not  been pulled from the queue by the application by way of the accept() call. If this backlog limit is reached, we will see that TCP will silently  discard all incoming connection requests until the pending connections can  be dealt with.  The backlog is not a large value.  It does not have to be.  Normally TCP is quite expedient in connection establishment processing.  Even if a connection arrived while the queue was full, in all likelihood, when the lient retransmits it’s connection request segment, the receiving TCP will have room again in it’s queue.  Different TCP implementations have different backlog sizes.   Under BSD style networking code, there is also ‘grace’ margin of 3/2.  That is, TCP will allow up to backlog*3/2+1 connections.  This will allow a socket one connection even if it calls listen with a backlog of O.

TCP Input Processing

To see exactly where the attack works it is necessary to watch as  the receiving TCP processes an incoming segment.  The following is true for BSD style networking, and only processes relevant to this document are discussed.

A packet arrives and is de multiplexed up the protocol stack to TCP. The TCP state is LISTEN:

  • Get header information: TCP retrieves the TCP and IP headers and stores the information in memory.
  • Verify the TCP checksum: The standard Internet checksum is applied to the segment.  If it  fails, no ACK is sent, and the segment is dropped, assuming the client will retransmit it.
  • Locate the PCB{}: TCP locates the pcb{} associated with the connection.  If it is not found, TCP drops the segment and sends a RST.  (Aside: This is how TCP handles connections that arrive on ports with no server listen()ing.)  If the PCB{} exists, but the state is CLOSED, the server has not called  connect() or listen().  The segment is dropped, but no RST is sent.  The client is expected to retransmit it’s connection request.  We will see this occurence when we discuss the ‘Linux Anomaly’.
  • Create new socket: When a segment arrives for a listen()ing socket, a slave socket is created.  This is where a socket{}, tcpcb{}, and another pcb{} are created. TCP is not committed to the connection at this point, so a flag is set to cause TCP to drop the socket (and destroy the memory structures) if an error is encountered.  If the backlog limit is reached, TCP considers this  an error, and the connection is refused.  We will see that this is exactly  why the attack works.
  • Otherwise, the new socket’s TCP state is LISTEN, and  the completion of the passive open is attempted Drop if RST, ACK, or no SYN: If the segment contains a RST, it is dropped.  If it contains an ACK, it is dropped, a RST is sent and the memory structures torn down (the ACK makes no sense for the connection at this point, and is considered an error).  If the segment does not have the SYN bit on, it is dropped.  If the segment contains a SYN, processing continues.
  • Address processing, etc: TCP then gets the clients address information into a buffer and connects it’s pcb{} to the client, processes any TCP options, and initializes it’s initial send sequence (ISS) number.
  • ACK the SYN: TCP sends a SYN, ISS and an ACK to the client.  The connection establishment timer is set for 75 seconds at this point. The state changes  to SYN_RCVD.  Now. TCP is commited to the socket.  We will see that this  is state the target TCP will be in when in the throes of the attack because the expected client response is never received.  The state remains SYN_RCVD until the connection establishment timer expires, in which case the all the memory structures associated with the connection are destroyed, and the  socket returns to the LISTEN state.

The Attack

A TCP connection is initiated with a client issuing a request to a  server with the SYN flag on in the TCP header.  Normally the server will  issue a SYN/ACK back to the client identified by the 32-bit source address in the IP header.  The client will then send an ACK to the server (as we  saw in figure 1 above) and data transfer can commence.  When the client IP address is spoofed to be that of an unreachable, host, however, the targetted TCP cannot complete the 3-way handshake and will keep trying until it times  out.  That is the basis for the attack. The attacking host sends a few (we saw that as little as 6 is  enough) SYN requests to the target TCP port (for example, the telnet daemon). The attacking host also must make sure that the source IP-address is spoofed to be that of another, currently unreachable host (the target TCP will be  sending it’s response to this address).  IP (by way of ICMP) will inform TCP  that the host is unreachable, but TCP considers these errors to be transient and leaves the resolution of them up to IP (reroute the packets, etc)  effectively ignoring them.  The IP-address must be unreachable because the  attacker does not want *any* host to recieve the SYN/ACKs that will be coming from the target TCP, which  would elicit a RST from that host (as we saw in TCP input above).  This would foil the attack.  The process is as follows:


Attacking host sends a multitude of SYN requests to the target  to fill it’s backlog queue with pending connections.   The target responds with SYN/ACKs to what it believes is the source of the incoming SYNs.  During this time all further requests to this TCP port will be ignored.  The target port is flooded.





End-Host Countermeasures

Increasing TCP Backlog: Because the basic attack mechanism relies on overflowing a host’s backlog of connecting sockets, an obvious end host-based solution is to simply increase the backlog, as is already done for very popular server applications. In at least some popular TCP implementations, this solution is known to be a poor one because of the use of linear list traversal in the functions that attempt to free state associated with stale connection attempts. Increasing the backlog is typically possible through altering the listen() call of an application and setting an operating system kernel parameter named SOMAXCONN, which sets an upper bound on the size of the backlog that an application can request. This step by itself should not be seriously considered as a means to defend against SYN flooding attacks—even in operating systems that can efficiently support large backlogs—because an attacker who can generate attack segments will most likely be able to scale to larger orders than the backlog supportable by a host.

Reducing the SYN-RECEIVED Timer: Another simple end host-based mechanism is to put a tighter limit on the amount of time between when a TCB enters the SYN-RECEIVED state and when it may be reaped for not advancing. The obvious disadvantage to this mechanism is that in cases of aggressive attacks that impose some amount of congestion loss in either the SYN-ACK or handshake-completing ACK packets, legitimate connection TCBs may be reaped as hosts are in the process of retransmitting these segments. Furthermore, there is only a linear relationship between the reduction that an administrator makes in the SYN-RECEIVED timer and the corresponding increase in packet rate that the adversary must make in order to continue attacking the server. Other alternative end-host solutions make it much more difficult for an attack to remain viable. For these reasons, a reduction in the SYN-RECEIVED timer is not an advisable defense against SYN flooding attacks.

SYN Caches: The SYN cache data structure is robust to attackers attempting to overflow its buckets because it uses the initiator’s local port number and some secret bits in the hash value. Because stacks are a more effective data structure to search than a simple linked list, stacks that use a SYN cache can have improved speed, even when not under attack. Under Lemon’s tests, during an active attack a host using a SYN cache was able to establish legitimate connections with only about a 15-percent increase in latency.

SYN Cookies: In contrast to the SYN cache approach, the SYN cookies technique causes absolutely zero state to be generated by a received SYN. Instead, the most basic data comprising the connection state is compressed into the bits of the sequence number used in the SYN-ACK. Since for a legitimate connection, an ACK segment will be received that echoes this sequence number (actually the sequence number plus one), the basic TCB data can be regenerated and a full TCB can safely be instantiated by decompressing the Acknowledgement field. This decompression can be effective even under heavy attack because there is no storage load whatsoever on the listener, only a computational load to encode data into the SYN-ACK sequence numbers. The downside is that not all TCB data can fit into the 32-bit Sequence Number field, so some TCP options required for high performance might be disabled. Another problem is that SYN-ACKs are not retransmitted (because retransmission would require state), altering the TCP synchronization procedures from RFC 793.

Hybrid Approaches: A hybrid approach combines two or more of the single defense techniques described previously. For instance, some end-host operating systems implement both a large backlog and SYN cookies, but enable SYN cookies only when the amount of the backlog that is occupied exceeds some threshold, allowing them to normally operate without the disadvantages of SYN cookies, but also allowing them to fail over to the SYN-cookie behavior and be strongly protected when an attack occurs.


Network-Based Countermeasures

Filtering: The most basic network-level defense is application of the filtering techniques described in RFC 2827 [7]. Using ingress filtering, an ISP refuses to further route packets coming from an end site with IP source addresses that do not belong to that end site. Ingress filtering would be highly effective at preventing SYN flooding attacks that rely on spoofed IP packets. However, it is not currently reliable because ingress filtering policies are not universally deployed. Ingress filtering is also wholly ineffective against SYN flooding attacks that use a distributed army of controlled hosts that each directly attack. Ingress filtering is also a mechanism that an end site wishing to defend itself most often has no control over, because it has no influence upon the policies employed by ISPs around the world.

Firewalls and Proxies: A firewall or proxy machine inside the network can buffer end hosts from SYN flooding attacks through two methods, by either spoofing SYN-ACKs to the initiators or spoofing ACKs to the listener

Active Monitor: An active monitor is a device that can observe and inject traffic to the listener, but is not necessarily within the routing path itself, like a firewall is. One type of active monitor acts like the ACK-spoofing firewall/proxy of Figure 6, with the added capability of spoofing RSTs immediately if it sees SYNs from source addresses that it knows to be used by attackers [9]. Active monitors are useful because they may be cheaper or easier to deploy than firewall-based or filtering solutions, and can still protect entire networks of listeners without requiring every listener’s operating system to implement an end-host solution.


Defenses in Practice

Both end-host and network-based solutions to the SYN flooding attack have merits. Both types of defense are frequently employed, and they generally do not interfere when used in combination. Because SYN flooding targets end hosts rather than attempting to exhaust the network capacity, it seems logical that all end hosts should implement defenses, and that network-based techniques are an optional second line of defense that a site can employ.

End-host mechanisms are present in current versions of most common operating systems. Some implement SYN caches, others use SYN cookies after a threshold of backlog usage is crossed, and still others adapt the SYN-RECEIVED timer and number of retransmission attempts for SYN-ACKs.

Because some techniques are known to be ineffective (increasing backlogs and reducing the SYN-RECEIVED timer), these techniques should definitely not be relied upon. Based on experimentation and analysis (and the author’s opinion), SYN caches seem like the best end-host mechanism available.

This choice is motivated by the facts that they are capable of withstanding heavy attacks, they are free from the negative effects of SYN cookies, and they do not need any heuristics for threshold setting as in many hybrid approaches.

Among network-based solutions, there does not seem to be any strong argument for SYN-ACK spoofing firewall/proxies. Because these spoofing proxies split the TCP connection, they may disable some high-performance or other TCP options, and there seems to be little advantage to this approach over ACK-spoofing firewall/proxies. Active monitors should be used when a firewall/proxy solution is administratively impossible or too expensive to deploy. Ingress and egress filtering is frequently done today (but not ubiquitous), and is a commonly accepted practice as part of being a good neighbor on the Internet. Because filtering does not cope with distributed networks of drones that use direct attacks, it needs to be supplemented with other mechanisms, and must not be relied upon by an end host.