diff --git a/src/core/tcp.c b/src/core/tcp.c index 8712d76c..f72597bb 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -880,10 +880,11 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, #endif /* SO_REUSE */ } - iss = tcp_next_iss(); + iss = tcp_next_iss(pcb); pcb->rcv_nxt = 0; pcb->snd_nxt = iss; pcb->lastack = iss - 1; + pcb->snd_wl2 = iss - 1; pcb->snd_lbb = iss - 1; /* Start with a window that does not need scaling. When window scaling is enabled and used, the window is enlarged when both sides agree on scaling. */ @@ -1491,7 +1492,6 @@ struct tcp_pcb * tcp_alloc(u8_t prio) { struct tcp_pcb *pcb; - u32_t iss; pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); if (pcb == NULL) { @@ -1554,11 +1554,6 @@ tcp_alloc(u8_t prio) pcb->sv = 3000 / TCP_SLOW_INTERVAL; pcb->rtime = -1; pcb->cwnd = 1; - iss = tcp_next_iss(); - pcb->snd_wl2 = iss; - pcb->snd_nxt = iss; - pcb->lastack = iss; - pcb->snd_lbb = iss; pcb->tmr = tcp_ticks; pcb->last_timer = tcp_timer_ctr; @@ -1826,12 +1821,18 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) * @return u32_t pseudo random sequence number */ u32_t -tcp_next_iss(void) +tcp_next_iss(struct tcp_pcb *pcb) { +#ifdef LWIP_HOOK_TCP_ISN + return LWIP_HOOK_TCP_ISN(&pcb->local_ip, pcb->local_port, &pcb->remote_ip, pcb->remote_port); +#else /* LWIP_HOOK_TCP_ISN */ static u32_t iss = 6510; + LWIP_UNUSED_ARG(pcb); + iss += tcp_ticks; /* XXX */ return iss; +#endif /* LWIP_HOOK_TCP_ISN */ } #if TCP_CALCULATE_EFF_SEND_MSS diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 7f42f577..3d3ae33a 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -542,6 +542,7 @@ static void tcp_listen_input(struct tcp_pcb_listen *pcb) { struct tcp_pcb *npcb; + u32_t iss; err_t rc; if (flags & TCP_RST) { @@ -589,6 +590,11 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) npcb->state = SYN_RCVD; npcb->rcv_nxt = seqno + 1; npcb->rcv_ann_right_edge = npcb->rcv_nxt; + iss = tcp_next_iss(npcb); + npcb->snd_wl2 = iss; + npcb->snd_nxt = iss; + npcb->lastack = iss; + npcb->snd_lbb = iss; npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ npcb->callback_arg = pcb->callback_arg; #if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG diff --git a/src/include/lwip/ip_addr.h b/src/include/lwip/ip_addr.h index bce65edd..def2d08c 100644 --- a/src/include/lwip/ip_addr.h +++ b/src/include/lwip/ip_addr.h @@ -66,7 +66,7 @@ enum lwip_ip_addr_type { * A union struct for both IP version's addresses. * ATTENTION: watch out for its size when adding IPv6 address scope! */ -typedef struct _ip_addr { +typedef struct ip_addr { union { ip6_addr_t ip6; ip4_addr_t ip4; diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index d350f3ce..98180c62 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -2410,6 +2410,29 @@ * @{ */ +/** + * LWIP_HOOK_TCP_ISN: + * Hook for generation of the Initial Sequence Number (ISN) for a new TCP + * connection. The default lwIP ISN generation algorithm is very basic and may + * allow for TCP spoofing attacks. This hook provides the means to implement + * the standardized ISN generation algorithm from RFC 6528, or any other + * desired algorithm (e.g., it can be set to LWIP_RAND()), as a replacement. + * Called from tcp_connect() and tcp_listen_input() when an ISN is needed for + * a new TCP connection, if TCP support (@ref LWIP_TCP) is enabled.\n + * Signature: u32_t my_hook_tcp_isn(const ip_addr_t* local_ip, u16_t local_port, const ip_addr_t* remote_ip, u16_t remote_port); + * - it may be necessary to use "struct ip_addr" (ip4_addr, ip6_addr) instead of "ip_addr_t" in function declarations\n + * Arguments: + * - local_ip: pointer to the local IP address of the connection + * - local_port: local port number of the connection (host-byte order) + * - remote_ip: pointer to the remote IP address of the connection + * - remote_port: remote port number of the connection (host-byte order)\n + * Return value: + * - the 32-bit Initial Sequence Number to use for the new TCP connection. + */ +#ifdef __DOXYGEN__ +#define LWIP_HOOK_TCP_ISN(local_ip, local_port, remote_ip, remote_port) +#endif + /** * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): * - called from ip_input() (IPv4) diff --git a/src/include/lwip/priv/tcp_priv.h b/src/include/lwip/priv/tcp_priv.h index f0eeb450..f68a856a 100644 --- a/src/include/lwip/priv/tcp_priv.h +++ b/src/include/lwip/priv/tcp_priv.h @@ -452,7 +452,7 @@ void tcp_rst(u32_t seqno, u32_t ackno, const ip_addr_t *local_ip, const ip_addr_t *remote_ip, u16_t local_port, u16_t remote_port); -u32_t tcp_next_iss(void); +u32_t tcp_next_iss(struct tcp_pcb *pcb); err_t tcp_keepalive(struct tcp_pcb *pcb); err_t tcp_zero_window_probe(struct tcp_pcb *pcb);