tcp: Remove incomplete support for TCP reassembly
This commit is contained in:
parent
45699e2701
commit
68b526b335
@ -212,17 +212,6 @@
|
|||||||
|
|
||||||
#define IP_TTL 64
|
#define IP_TTL 64
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TCP_REASSEMBLY
|
|
||||||
# ifndef CONFIG_NET_TCP_REASS_MAXAGE
|
|
||||||
/* The maximum time an IP fragment should wait in the reassembly
|
|
||||||
* buffer before it is dropped. Units are deci-seconds, the range
|
|
||||||
* of the timer is 8-bits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
# define CONFIG_NET_TCP_REASS_MAXAGE (20 * 10) /* 20 seconds */
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Network drivers often receive packets with garbage at the end
|
/* Network drivers often receive packets with garbage at the end
|
||||||
* and are longer than the size of packet in the TCP header. The
|
* and are longer than the size of packet in the TCP header. The
|
||||||
* following "fudge" factor increases the size of the I/O buffering
|
* following "fudge" factor increases the size of the I/O buffering
|
||||||
|
33
net/Kconfig
33
net/Kconfig
@ -276,39 +276,6 @@ config NET_IPv4
|
|||||||
---help---
|
---help---
|
||||||
Build in support for IPv4.
|
Build in support for IPv4.
|
||||||
|
|
||||||
config NET_IPv4_REASSEMBLY
|
|
||||||
bool "IPv4 reassembly"
|
|
||||||
default n
|
|
||||||
depends on NET_IPv4 && EXPERIMENTAL && NET_ETHERNET
|
|
||||||
---help---
|
|
||||||
Enable support for IP packet reassembly of fragmented IP packets.
|
|
||||||
|
|
||||||
This features requires an additional amount of RAM to hold a single
|
|
||||||
reassembly buffer. The reassembly buffer is of the same size as the
|
|
||||||
MTU of the selected device.
|
|
||||||
|
|
||||||
REVISIT: There are multiple issues with the current implementation:
|
|
||||||
1. IPv4 reassembly in its current form is untested (and, hence,
|
|
||||||
depends on CONFIG_EXPERIMENTAL).
|
|
||||||
2. Currently this feature can only work with Ethernet due to internal
|
|
||||||
definitions that depend on Ethernet configuration settings (and,
|
|
||||||
hence, depends on CONFIG_NET_ETHERNET).
|
|
||||||
3. Since there is only a single reassembly buffer, IPv4 reassembly
|
|
||||||
cannot be used in a context where multiple network devices may be
|
|
||||||
concurrently re-assemblying packets.
|
|
||||||
|
|
||||||
if NET_IPv4_REASSEMBLY
|
|
||||||
|
|
||||||
config NET_IPv4_REASS_MAXAGE
|
|
||||||
int "IP fragment timeout"
|
|
||||||
default 200
|
|
||||||
---help---
|
|
||||||
The maximum time an IP fragment should wait in the reassembly buffer
|
|
||||||
before it is dropped. Units are deci-seconds, the range of the timer
|
|
||||||
is 8-bits. Default: 20 seconds.
|
|
||||||
|
|
||||||
endif # NET_IPv4_REASSEMBLY
|
|
||||||
|
|
||||||
config NET_IPv6
|
config NET_IPv6
|
||||||
bool "IPv6"
|
bool "IPv6"
|
||||||
default n
|
default n
|
||||||
|
@ -279,12 +279,6 @@ extern "C"
|
|||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
|
||||||
/* Reassembly timer (units: deci-seconds) */
|
|
||||||
|
|
||||||
EXTERN uint8_t g_reassembly_timer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -62,12 +62,6 @@
|
|||||||
struct net_stats_s g_netstats;
|
struct net_stats_s g_netstats;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
|
||||||
/* Reassembly timer (units: deci-seconds) */
|
|
||||||
|
|
||||||
uint8_t g_reassembly_timer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -818,16 +818,6 @@ int devif_timer(FAR struct net_driver_s *dev, int delay,
|
|||||||
#endif
|
#endif
|
||||||
int bstop = false;
|
int bstop = false;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
|
||||||
/* Increment the timer used by the IP reassembly logic */
|
|
||||||
|
|
||||||
if (g_reassembly_timer != 0 &&
|
|
||||||
g_reassembly_timer < CONFIG_NET_IPv4_REASS_MAXAGE)
|
|
||||||
{
|
|
||||||
g_reassembly_timer += hsec;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NET_TCP_HAVE_STACK
|
#ifdef NET_TCP_HAVE_STACK
|
||||||
/* Traverse all of the active TCP connections and perform the
|
/* Traverse all of the active TCP connections and perform the
|
||||||
* timer action.
|
* timer action.
|
||||||
|
@ -111,205 +111,15 @@
|
|||||||
/* Macros */
|
/* Macros */
|
||||||
|
|
||||||
#define BUF ((FAR struct ipv4_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
#define BUF ((FAR struct ipv4_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
||||||
#define FBUF ((FAR struct ipv4_hdr_s *)&g_reassembly_buffer[0])
|
|
||||||
|
|
||||||
/* IP fragment re-assembly.
|
|
||||||
*
|
|
||||||
* REVISIT: There are multiple issues with the current implementation:
|
|
||||||
* 1. IPv4 reassembly is untested.
|
|
||||||
* 2. Currently can only work with Ethernet due to the definition of
|
|
||||||
* IPv4_REASS_BUFSIZE.
|
|
||||||
* 3. Since there is only a single reassembly buffer, IPv4 reassembly cannot
|
|
||||||
* be used in a context where multiple network devices may be concurrently
|
|
||||||
* re-assembling packets.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define IP_MF 0x20 /* See IP_FLAG_MOREFRAGS */
|
|
||||||
#define IPv4_REASS_BUFSIZE (CONFIG_NET_ETH_PKTSIZE - ETH_HDRLEN)
|
|
||||||
#define IPv4_REASS_LASTFRAG 0x01
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
|
||||||
|
|
||||||
static uint8_t g_reassembly_buffer[IPv4_REASS_BUFSIZE];
|
|
||||||
static uint8_t g_reassembly_bitmap[IPv4_REASS_BUFSIZE / (8 * 8)];
|
|
||||||
|
|
||||||
static const uint8_t g_bitmap_bits[8] =
|
|
||||||
{
|
|
||||||
0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint16_t g_reassembly_len;
|
|
||||||
static uint8_t g_reassembly_flags;
|
|
||||||
|
|
||||||
#endif /* CONFIG_NET_IPv4_REASSEMBLY */
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: devif_reassembly
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* IP fragment reassembly: not well-tested.
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
|
||||||
static uint8_t devif_reassembly(FAR struct net_driver_s *dev)
|
|
||||||
{
|
|
||||||
FAR struct ipv4_hdr_s *ipv4 = BUF;
|
|
||||||
FAR struct ipv4_hdr_s *fipv4 = FBUF;
|
|
||||||
uint16_t offset;
|
|
||||||
uint16_t len;
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
/* If g_reassembly_timer is zero, no packet is present in the buffer, so
|
|
||||||
* we write the IP header of the fragment into the reassembly buffer. The
|
|
||||||
* timer is updated with the maximum age.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!g_reassembly_timer)
|
|
||||||
{
|
|
||||||
memcpy(g_reassembly_buffer, &ipv4->vhl, IPv4_HDRLEN);
|
|
||||||
g_reassembly_timer = CONFIG_NET_IPv4_REASS_MAXAGE;
|
|
||||||
g_reassembly_flags = 0;
|
|
||||||
|
|
||||||
/* Clear the bitmap. */
|
|
||||||
|
|
||||||
memset(g_reassembly_bitmap, 0, sizeof(g_reassembly_bitmap));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the incoming fragment matches the one currently present
|
|
||||||
* in the reassembly buffer. If so, we proceed with copying the
|
|
||||||
* fragment into the buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (net_ipv4addr_hdrcmp(ipv4->srcipaddr, fipv4->srcipaddr) &&
|
|
||||||
net_ipv4addr_hdrcmp(ipv4->destipaddr, fipv4->destipaddr) &&
|
|
||||||
ipv4->ipid[0] == fipv4->ipid[0] && ipv4->ipid[1] == fipv4->ipid[1])
|
|
||||||
{
|
|
||||||
len = ((uint16_t)ipv4->len[0] << 8) + (uint16_t)ipv4->len[1] -
|
|
||||||
(uint16_t)(ipv4->vhl & 0x0f) * 4;
|
|
||||||
offset = (((ipv4->ipoffset[0] & 0x3f) << 8) + ipv4->ipoffset[1]) * 8;
|
|
||||||
|
|
||||||
/* If the offset or the offset + fragment length overflows the
|
|
||||||
* reassembly buffer, we discard the entire packet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (offset > IPv4_REASS_BUFSIZE || offset + len > IPv4_REASS_BUFSIZE)
|
|
||||||
{
|
|
||||||
g_reassembly_timer = 0;
|
|
||||||
goto nullreturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the fragment into the reassembly buffer, at the right offset. */
|
|
||||||
|
|
||||||
memcpy(&g_reassembly_buffer[IPv4_HDRLEN + offset],
|
|
||||||
(FAR char *)ipv4 + (int)((ipv4->vhl & 0x0f) * 4), len);
|
|
||||||
|
|
||||||
/* Update the bitmap. */
|
|
||||||
|
|
||||||
if (offset / (8 * 8) == (offset + len) / (8 * 8))
|
|
||||||
{
|
|
||||||
/* If the two endpoints are in the same byte, we only update that byte. */
|
|
||||||
|
|
||||||
g_reassembly_bitmap[offset / (8 * 8)] |=
|
|
||||||
g_bitmap_bits[(offset / 8) & 7] &
|
|
||||||
~g_bitmap_bits[((offset + len) / 8) & 7];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* If the two endpoints are in different bytes, we update the bytes
|
|
||||||
* in the endpoints and fill the stuff in between with 0xff.
|
|
||||||
*/
|
|
||||||
|
|
||||||
g_reassembly_bitmap[offset / (8 * 8)] |=
|
|
||||||
g_bitmap_bits[(offset / 8) & 7];
|
|
||||||
|
|
||||||
for (i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i)
|
|
||||||
{
|
|
||||||
g_reassembly_bitmap[i] = 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_reassembly_bitmap[(offset + len) / (8 * 8)] |=
|
|
||||||
~g_bitmap_bits[((offset + len) / 8) & 7];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If this fragment has the More Fragments flag set to zero, we know that
|
|
||||||
* this is the last fragment, so we can calculate the size of the entire
|
|
||||||
* packet. We also set the IP_REASS_FLAG_LASTFRAG flag to indicate that
|
|
||||||
* we have received the final fragment.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((ipv4->ipoffset[0] & IP_MF) == 0)
|
|
||||||
{
|
|
||||||
g_reassembly_flags |= IPv4_REASS_LASTFRAG;
|
|
||||||
g_reassembly_len = offset + len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally, we check if we have a full packet in the buffer. We do this
|
|
||||||
* by checking if we have the last fragment and if all bits in the bitmap
|
|
||||||
* are set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (g_reassembly_flags & IPv4_REASS_LASTFRAG)
|
|
||||||
{
|
|
||||||
/* Check all bytes up to and including all but the last byte in
|
|
||||||
* the bitmap.
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = 0; i < g_reassembly_len / (8 * 8) - 1; ++i)
|
|
||||||
{
|
|
||||||
if (g_reassembly_bitmap[i] != 0xff)
|
|
||||||
{
|
|
||||||
goto nullreturn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the last byte in the bitmap. It should contain just the
|
|
||||||
* right amount of bits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (g_reassembly_bitmap[g_reassembly_len / (8 * 8)] !=
|
|
||||||
(uint8_t)~g_bitmap_bits[g_reassembly_len / 8 & 7])
|
|
||||||
{
|
|
||||||
goto nullreturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we have come this far, we have a full packet in the buffer,
|
|
||||||
* so we allocate a ipv4 and copy the packet into it. We also reset
|
|
||||||
* the timer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
g_reassembly_timer = 0;
|
|
||||||
memcpy(ipv4, fipv4, g_reassembly_len);
|
|
||||||
|
|
||||||
/* Pretend to be a "normal" (i.e., not fragmented) IP packet from
|
|
||||||
* now on.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ipv4->ipoffset[0] = ipv4->ipoffset[1] = 0;
|
|
||||||
ipv4->len[0] = g_reassembly_len >> 8;
|
|
||||||
ipv4->len[1] = g_reassembly_len & 0xff;
|
|
||||||
ipv4->ipchksum = 0;
|
|
||||||
ipv4->ipchksum = ~(ipv4_chksum(dev));
|
|
||||||
|
|
||||||
return g_reassembly_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nullreturn:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_NET_IPv4_REASSEMBLY */
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -396,11 +206,6 @@ int ipv4_input(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
if ((ipv4->ipoffset[0] & 0x3f) != 0 || ipv4->ipoffset[1] != 0)
|
if ((ipv4->ipoffset[0] & 0x3f) != 0 || ipv4->ipoffset[1] != 0)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NET_IPv4_REASSEMBLY
|
|
||||||
dev->d_len = devif_reassembly(dev);
|
|
||||||
if (dev->d_len == 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_NET_STATISTICS
|
#ifdef CONFIG_NET_STATISTICS
|
||||||
g_netstats.ipv4.drop++;
|
g_netstats.ipv4.drop++;
|
||||||
g_netstats.ipv4.fragerr++;
|
g_netstats.ipv4.fragerr++;
|
||||||
@ -408,7 +213,6 @@ int ipv4_input(FAR struct net_driver_s *dev)
|
|||||||
nwarn("WARNING: IP fragment dropped\n");
|
nwarn("WARNING: IP fragment dropped\n");
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the destination IP address in a friendlier form */
|
/* Get the destination IP address in a friendlier form */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user