mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
Networking: UDP and TCP MSS depends on the IP header size (as well as the link layer header size) and cannot be represented with a single value.
This commit is contained in:
@@ -122,7 +122,7 @@ void icmpv6_input(FAR struct net_driver_s *dev)
|
||||
|
||||
if (picmp->type == ICMPv6_NEIGHBOR_SOLICITATION)
|
||||
{
|
||||
if (net_ipv6addr_cmp(picmp->icmpv6data, dev->d_ipaddr))
|
||||
if (net_ipv6addr_cmp(picmp->icmpv6data, dev->d_ipv6addr))
|
||||
{
|
||||
if (picmp->options[0] == ICMPv6_OPTION_SOURCE_LINK_ADDRESS)
|
||||
{
|
||||
@@ -142,7 +142,7 @@ void icmpv6_input(FAR struct net_driver_s *dev)
|
||||
picmp->reserved1 = picmp->reserved2 = picmp->reserved3 = 0;
|
||||
|
||||
net_ipv6addr_copy(picmp->destipaddr, picmp->srcipaddr);
|
||||
net_ipv6addr_copy(picmp->srcipaddr, dev->d_ipaddr);
|
||||
net_ipv6addr_copy(picmp->srcipaddr, dev->d_ipv6addr);
|
||||
|
||||
picmp->options[0] = ICMPv6_OPTION_TARGET_LINK_ADDRESS;
|
||||
picmp->options[1] = 1; /* Options length, 1 = 8 bytes. */
|
||||
@@ -166,7 +166,7 @@ void icmpv6_input(FAR struct net_driver_s *dev)
|
||||
picmp->type = ICMPv6_ECHO_REPLY;
|
||||
|
||||
net_ipv6addr_copy(picmp->destipaddr, picmp->srcipaddr);
|
||||
net_ipv6addr_copy(picmp->srcipaddr, dev->d_ipaddr);
|
||||
net_ipv6addr_copy(picmp->srcipaddr, dev->d_ipv6addr);
|
||||
|
||||
picmp->icmpv6chksum = 0;
|
||||
picmp->icmpv6chksum = ~icmpv6_chksum(dev);
|
||||
|
||||
@@ -259,7 +259,7 @@ static uint16_t psock_connect_interrupt(FAR struct net_driver_s *dev,
|
||||
*/
|
||||
|
||||
DEBUGASSERT(pstate->tc_conn);
|
||||
pstate->tc_conn->mss = TCP_INITIAL_MSS(dev);
|
||||
pstate->tc_conn->mss = TCP_IPv4_INITIAL_MSS(dev);
|
||||
#endif
|
||||
|
||||
/* Wake up the waiting thread */
|
||||
|
||||
+2
-2
@@ -599,7 +599,7 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
|
||||
conn->nrtx = 0;
|
||||
conn->lport = tcp->destport;
|
||||
conn->rport = tcp->srcport;
|
||||
conn->mss = TCP_INITIAL_MSS(dev);
|
||||
conn->mss = TCP_IPv4_INITIAL_MSS(dev);
|
||||
net_ipv4addr_copy(conn->u.ipv4.raddr, net_ip4addr_conv32(ip->srcipaddr));
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
net_ipv4addr_copy(conn->u.ipv4.laddr, net_ip4addr_conv32(ip->destipaddr));
|
||||
@@ -780,7 +780,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn,
|
||||
conn->tcpstateflags = TCP_SYN_SENT;
|
||||
tcp_initsequence(conn->sndseq);
|
||||
|
||||
conn->mss = MIN_TCP_INITIAL_MSS;
|
||||
conn->mss = MIN_IPv4_TCP_INITIAL_MSS;
|
||||
conn->unacked = 1; /* TCP length of the SYN is one. */
|
||||
conn->nrtx = 0;
|
||||
conn->timer = 1; /* Send the SYN next time around. */
|
||||
|
||||
+25
-11
@@ -95,10 +95,11 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void tcp_input(FAR struct net_driver_s *dev,
|
||||
FAR struct tcp_hdr_s *tcp, unsigned int tcpiplen)
|
||||
static void tcp_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
||||
{
|
||||
FAR struct tcp_hdr_s *tcp;
|
||||
FAR struct tcp_conn_s *conn = NULL;
|
||||
unsigned int tcpiplen;
|
||||
unsigned int hdrlen;
|
||||
uint16_t tmp16;
|
||||
uint16_t flags;
|
||||
@@ -113,6 +114,16 @@ static void tcp_input(FAR struct net_driver_s *dev,
|
||||
g_netstats.tcp.recv++;
|
||||
#endif
|
||||
|
||||
/* Get a pointer to the TCP header. The TCP header lies just after the
|
||||
* the link layer header and the IP header.
|
||||
*/
|
||||
|
||||
tcp = (FAR struct tcp_hdr_s *)&dev->d_buf[iplen + NET_LL_HDRLEN(dev)];
|
||||
|
||||
/* Get the size of the IP header and the TCP header */
|
||||
|
||||
tcpiplen = iplen + TCP_HDRLEN;
|
||||
|
||||
/* Get the size of the link layer header, the IP header, and the TCP header */
|
||||
|
||||
hdrlen = tcpiplen + NET_LL_HDRLEN(dev);
|
||||
@@ -240,11 +251,13 @@ static void tcp_input(FAR struct net_driver_s *dev,
|
||||
else if (opt == TCP_OPT_MSS &&
|
||||
dev->d_buf[hdrlen + 1 + i] == TCP_OPT_MSS_LEN)
|
||||
{
|
||||
uint16_t tcp_mss = TCP_MSS(dev, iplen);
|
||||
|
||||
/* An MSS option with the right option length. */
|
||||
|
||||
tmp16 = ((uint16_t)dev->d_buf[hdrlen + 2 + i] << 8) |
|
||||
(uint16_t)dev->d_buf[hdrlen + 3 + i];
|
||||
conn->mss = tmp16 > TCP_MSS(dev) ? TCP_MSS(dev) : tmp16;
|
||||
conn->mss = tmp16 > tcp_mss ? tcp_mss : tmp16;
|
||||
|
||||
/* And we are done processing options. */
|
||||
|
||||
@@ -326,10 +339,10 @@ found:
|
||||
|
||||
/* d_len will contain the length of the actual TCP data. This is
|
||||
* calculated by subtracting the length of the TCP header (in
|
||||
* len) and the length of the IP header (20 bytes).
|
||||
* len) and the length of the IP header.
|
||||
*/
|
||||
|
||||
dev->d_len -= (len + IPv4_HDRLEN);
|
||||
dev->d_len -= (len + iplen);
|
||||
|
||||
/* First, check if the sequence number of the incoming packet is
|
||||
* what we're expecting next. If not, we send out an ACK with the
|
||||
@@ -530,12 +543,14 @@ found:
|
||||
else if (opt == TCP_OPT_MSS &&
|
||||
dev->d_buf[hdrlen + 1 + i] == TCP_OPT_MSS_LEN)
|
||||
{
|
||||
uint16_t tcp_mss = TCP_MSS(dev, iplen);
|
||||
|
||||
/* An MSS option with the right option length. */
|
||||
|
||||
tmp16 =
|
||||
(dev->d_buf[hdrlen + 2 + i] << 8) |
|
||||
dev->d_buf[hdrlen + 3 + i];
|
||||
conn->mss = tmp16 > TCP_MSS(dev) ? TCP_MSS(dev) : tmp16;
|
||||
conn->mss = tmp16 > tcp_mss ? tcp_mss : tmp16;
|
||||
|
||||
/* And we are done processing options. */
|
||||
|
||||
@@ -697,7 +712,8 @@ found:
|
||||
* When the application is called, the d_len field
|
||||
* contains the length of the incoming data. The application can
|
||||
* access the incoming data through the global pointer
|
||||
* d_appdata, which usually points hdrlen bytes into the d_buf array.
|
||||
* d_appdata, which usually points hdrlen bytes into the d_buf
|
||||
* array.
|
||||
*
|
||||
* If the application wishes to send any data, this data should be
|
||||
* put into the d_appdata and the length of the data should be
|
||||
@@ -871,8 +887,7 @@ drop:
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
void tcp_ipv4_input(FAR struct net_driver_s *dev)
|
||||
{
|
||||
unsigned int offset = IPv4_HDRLEN + NET_LL_HDRLEN(dev);
|
||||
tcp_input(dev, (FAR struct tcp_hdr_s *)&dev->d_buf[offset], IPv4TCP_HDRLEN);
|
||||
tcp_input(dev, IPv4_HDRLEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -896,8 +911,7 @@ void tcp_ipv4_input(FAR struct net_driver_s *dev)
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
void tcp_ipv6_input(FAR struct net_driver_s *dev)
|
||||
{
|
||||
unsigned int offset = IPv6_HDRLEN + NET_LL_HDRLEN(dev);
|
||||
tcp_input(dev, (FAR struct tcp_hdr_s *)&dev->d_buf[offset], IPv6TCP_HDRLEN);
|
||||
tcp_input(dev, IPv6_HDRLEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+3
-2
@@ -351,6 +351,7 @@ void tcp_ack(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
|
||||
uint8_t ack)
|
||||
{
|
||||
struct tcp_iphdr_s *pbuf = BUF;
|
||||
uint16_t tcp_mss = TCP_IPv4_MSS(dev);
|
||||
|
||||
/* Save the ACK bits */
|
||||
|
||||
@@ -360,8 +361,8 @@ void tcp_ack(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
|
||||
|
||||
pbuf->optdata[0] = TCP_OPT_MSS;
|
||||
pbuf->optdata[1] = TCP_OPT_MSS_LEN;
|
||||
pbuf->optdata[2] = TCP_MSS(dev) / 256;
|
||||
pbuf->optdata[3] = TCP_MSS(dev) & 255;
|
||||
pbuf->optdata[2] = tcp_mss >> 8;
|
||||
pbuf->optdata[3] = tcp_mss & 0xff;
|
||||
dev->d_len = IPv4TCP_HDRLEN + TCP_OPT_MSS_LEN;
|
||||
pbuf->tcpoffset = ((TCP_HDRLEN + TCP_OPT_MSS_LEN) / 4) << 4;
|
||||
|
||||
|
||||
+19
-12
@@ -93,10 +93,11 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int udp_input(FAR struct net_driver_s *dev, FAR struct udp_hdr_s *udp,
|
||||
unsigned int udpiplen)
|
||||
static int udp_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
||||
{
|
||||
FAR struct udp_hdr_s *udp;
|
||||
FAR struct udp_conn_s *conn;
|
||||
unsigned int udpiplen;
|
||||
unsigned int hdrlen;
|
||||
int ret = OK;
|
||||
|
||||
@@ -106,6 +107,20 @@ static int udp_input(FAR struct net_driver_s *dev, FAR struct udp_hdr_s *udp,
|
||||
g_netstats.udp.recv++;
|
||||
#endif
|
||||
|
||||
/* Get a pointer to the UDP header. The UDP header lies just after the
|
||||
* the link layer header and the IP header.
|
||||
*/
|
||||
|
||||
udp = (FAR struct udp_hdr_s *)&dev->d_buf[iplen + NET_LL_HDRLEN(dev)];
|
||||
|
||||
/* Get the size of the IP header and the UDP header */
|
||||
|
||||
udpiplen = iplen + UDP_HDRLEN;
|
||||
|
||||
/* Get the size of the link layer header, the IP header, and the UDP header */
|
||||
|
||||
hdrlen = udpiplen + NET_LL_HDRLEN(dev);
|
||||
|
||||
/* UDP processing is really just a hack. We don't do anything to the UDP/IP
|
||||
* headers, but let the UDP application do all the hard work. If the
|
||||
* application sets d_sndlen, it has a packet to send.
|
||||
@@ -113,10 +128,6 @@ static int udp_input(FAR struct net_driver_s *dev, FAR struct udp_hdr_s *udp,
|
||||
|
||||
dev->d_len -= udpiplen;
|
||||
|
||||
/* Get the size of the link layer header, the IP header, and the UDP header */
|
||||
|
||||
hdrlen = udpiplen + NET_LL_HDRLEN(dev);
|
||||
|
||||
#ifdef CONFIG_NET_UDP_CHECKSUMS
|
||||
dev->d_appdata = &dev->d_buf[hdrlen];
|
||||
|
||||
@@ -219,9 +230,7 @@ static int udp_input(FAR struct net_driver_s *dev, FAR struct udp_hdr_s *udp,
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
int udp_ipv4_input(FAR struct net_driver_s *dev)
|
||||
{
|
||||
unsigned int offset = IPv4_HDRLEN + NET_LL_HDRLEN(dev);
|
||||
return udp_input(dev, (FAR struct udp_hdr_s *)&dev->d_buf[offset],
|
||||
IPv4UDP_HDRLEN);
|
||||
return udp_input(dev, IPv4_HDRLEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -247,9 +256,7 @@ int udp_ipv4_input(FAR struct net_driver_s *dev)
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
int udp_ipv6_input(FAR struct net_driver_s *dev)
|
||||
{
|
||||
unsigned int offset = IPv6_HDRLEN + NET_LL_HDRLEN(dev);
|
||||
return udp_input(dev, (FAR struct udp_hdr_s *)&dev->d_buf[offset],
|
||||
IPv6UDP_HDRLEN);
|
||||
return udp_input(dev, IPv6_HDRLEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user