Skip to content

Commit

Permalink
net/tcp: Support initial sequence number described in RFC 6528
Browse files Browse the repository at this point in the history
Signed-off-by: Zhe Weng <[email protected]>
  • Loading branch information
wengzhe authored and xiaoxiang781216 committed Nov 6, 2023
1 parent 5096a2c commit d1c73b6
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 13 deletions.
11 changes: 11 additions & 0 deletions net/tcp/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,17 @@ config NET_TCP_CC_NEWRENO
The TCP Congestion Control defines four congestion control algorithms,
slow start, congestion avoidance, fast retransmit, and fast recovery.

config NET_TCP_ISN_RFC6528
bool "Use Initial Sequence Number Algorithm from RFC 6528"
default n
depends on CRYPTO
---help---
Initial Sequence Number Generation Algorithm from RFC 6528:
ISN = M + F(localip, localport, remoteip, remoteport, secretkey)

M is the 4 microsecond timer, and F() is a pseudorandom
function (PRF) which is MD5 (suggested by RFC 6528).

config NET_TCP_WINDOW_SCALE
bool "Enable TCP/IP Window Scale Option"
default n
Expand Down
2 changes: 1 addition & 1 deletion net/tcp/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@ uint32_t tcp_addsequence(FAR uint8_t *seqno, uint16_t len);
*
****************************************************************************/

void tcp_initsequence(FAR uint8_t *seqno);
void tcp_initsequence(FAR struct tcp_conn_s *conn);

/****************************************************************************
* Name: tcp_nextsequence
Expand Down
19 changes: 11 additions & 8 deletions net/tcp/tcp_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,7 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev,
conn->rport = tcp->srcport;
conn->tcpstateflags = TCP_SYN_RCVD;

tcp_initsequence(conn->sndseq);
tcp_initsequence(conn);
#if !defined(CONFIG_NET_TCP_WRITE_BUFFERS)
conn->rexmit_seq = tcp_getsequence(conn->sndseq);
#endif
Expand Down Expand Up @@ -1506,13 +1506,6 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
*/

conn->tcpstateflags = TCP_SYN_SENT;
tcp_initsequence(conn->sndseq);

/* Save initial sndseq to rexmit_seq, otherwise it will be zero */

#if !defined(CONFIG_NET_TCP_WRITE_BUFFERS)
conn->rexmit_seq = tcp_getsequence(conn->sndseq);
#endif

conn->tx_unacked = 1; /* TCP length of the SYN is one. */
conn->nrtx = 0;
Expand All @@ -1528,6 +1521,16 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
conn->sndseq_max = 0;
#endif

/* Set initial sndseq when we have both local/remote addr and port */

tcp_initsequence(conn);

/* Save initial sndseq to rexmit_seq, otherwise it will be zero */

#if !defined(CONFIG_NET_TCP_WRITE_BUFFERS)
conn->rexmit_seq = tcp_getsequence(conn->sndseq);
#endif

#ifdef CONFIG_NET_TCP_CC_NEWRENO
/* Initialize the variables of congestion control. */

Expand Down
75 changes: 71 additions & 4 deletions net/tcp/tcp_seqno.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,84 @@
#include <nuttx/config.h>
#if defined(CONFIG_NET) && defined(CONFIG_NET_TCP)

#include <stdint.h>
#include <crypto/md5.h>
#include <debug.h>
#include <stdint.h>

#include <nuttx/clock.h>
#include <nuttx/net/netconfig.h>
#include <nuttx/net/netdev.h>

#include "devif/devif.h"
#include "tcp/tcp.h"
#include "utils/utils.h"

/****************************************************************************
* Private Data
****************************************************************************/

/* g_tcpsequence is used to generate initial TCP sequence numbers */
/* These fields are used to generate initial TCP sequence numbers */

#ifdef CONFIG_NET_TCP_ISN_RFC6528
/* RFC 6528, Section 3: Key lengths of 128 bits should be adequate. */

static uint32_t g_tcp_isnkey[4];
#else
static uint32_t g_tcpsequence;
#endif

/****************************************************************************
* Private Functions
****************************************************************************/

/****************************************************************************
* Name: tcp_isn_rfc6528
*
* Description:
* Calculate the initial sequence number described in RFC 6528.
* ISN = M + F(localip, localport, remoteip, remoteport, secretkey)
*
****************************************************************************/

#ifdef CONFIG_NET_TCP_ISN_RFC6528
static uint32_t tcp_isn_rfc6528(FAR struct tcp_conn_s *conn)
{
const size_t addrlen = net_ip_domain_select(conn->domain,
sizeof(in_addr_t), sizeof(net_ipv6addr_t));
MD5_CTX ctx;
uint32_t digest[MD5_DIGEST_LENGTH / 4];
uint32_t m;

/* Make sure we have a secret key */

if (g_tcp_isnkey[0] == 0)
{
net_getrandom(g_tcp_isnkey, sizeof(g_tcp_isnkey));
}

/* M is the 4 microsecond timer */

m = TICK2USEC(clock_systime_ticks()) / 4;

/* F() is suggested to be MD5 */

md5init(&ctx);

/* Calculate F(localip, localport, remoteip, remoteport, secretkey) */

md5update(&ctx, net_ip_binding_laddr(&conn->u, conn->domain), addrlen);
md5update(&ctx, &conn->lport, sizeof(conn->lport));
md5update(&ctx, net_ip_binding_raddr(&conn->u, conn->domain), addrlen);
md5update(&ctx, &conn->rport, sizeof(conn->rport));
md5update(&ctx, g_tcp_isnkey, sizeof(g_tcp_isnkey));

md5final((FAR uint8_t *)digest, &ctx);

/* ISN = M + F(localip, localport, remoteip, remoteport, secretkey) */

return m + digest[0];
}
#endif

/****************************************************************************
* Public Functions
Expand Down Expand Up @@ -142,8 +203,11 @@ uint32_t tcp_addsequence(FAR uint8_t *seqno, uint16_t len)
*
****************************************************************************/

void tcp_initsequence(FAR uint8_t *seqno)
void tcp_initsequence(FAR struct tcp_conn_s *conn)
{
#ifdef CONFIG_NET_TCP_ISN_RFC6528
tcp_setsequence(conn->sndseq, tcp_isn_rfc6528(conn));
#else
/* If g_tcpsequence is already initialized, just copy it */

if (g_tcpsequence == 0)
Expand All @@ -164,7 +228,8 @@ void tcp_initsequence(FAR uint8_t *seqno)
}
}

tcp_setsequence(seqno, g_tcpsequence);
tcp_setsequence(conn->sndseq, g_tcpsequence);
#endif
}

/****************************************************************************
Expand All @@ -180,7 +245,9 @@ void tcp_initsequence(FAR uint8_t *seqno)

void tcp_nextsequence(void)
{
#ifndef CONFIG_NET_TCP_ISN_RFC6528
g_tcpsequence++;
#endif
}

#endif /* CONFIG_NET && CONFIG_NET_TCP */

0 comments on commit d1c73b6

Please sign in to comment.