mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-02-05 06:39:52 +00:00
Work on task #14494: Implement SO_BINDTODEVICE
TCP needs additional netif handling
This commit is contained in:
parent
c144e5b1ec
commit
5800cf51be
@ -272,7 +272,7 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
||||
|
||||
/* don't call tcp_abort here: we must not deallocate the pcb since
|
||||
that might not be expected when calling tcp_close */
|
||||
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
|
||||
tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
|
||||
pcb->local_port, pcb->remote_port);
|
||||
|
||||
tcp_pcb_purge(pcb);
|
||||
@ -513,7 +513,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
|
||||
tcp_backlog_accepted(pcb);
|
||||
if (send_rst) {
|
||||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
|
||||
tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
|
||||
tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
|
||||
}
|
||||
last_state = pcb->state;
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
@ -920,24 +920,28 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
|
||||
ip_addr_set(&pcb->remote_ip, ipaddr);
|
||||
pcb->remote_port = port;
|
||||
|
||||
/* check if we have a route to the remote host */
|
||||
if (ip_addr_isany(&pcb->local_ip)) {
|
||||
/* no local IP address set, yet. */
|
||||
const ip_addr_t *local_ip;
|
||||
ip_route_get_local_ip(&pcb->local_ip, &pcb->remote_ip, netif, local_ip);
|
||||
if ((netif == NULL) || (local_ip == NULL)) {
|
||||
/* Don't even try to send a SYN packet if we have no route
|
||||
since that will fail. */
|
||||
return ERR_RTE;
|
||||
}
|
||||
/* Use the address as local address of the pcb. */
|
||||
ip_addr_copy(pcb->local_ip, *local_ip);
|
||||
if (pcb->netif_idx != NETIF_NO_INDEX) {
|
||||
netif = netif_get_by_index(pcb->netif_idx);
|
||||
} else {
|
||||
netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
|
||||
if (netif == NULL) {
|
||||
/* Don't even try to send a SYN packet if we have no route
|
||||
since that will fail. */
|
||||
return ERR_RTE;
|
||||
/* check if we have a route to the remote host */
|
||||
if (ip_addr_isany(&pcb->local_ip)) {
|
||||
/* no local IP address set, yet. */
|
||||
const ip_addr_t *local_ip;
|
||||
ip_route_get_local_ip(&pcb->local_ip, &pcb->remote_ip, netif, local_ip);
|
||||
if ((netif == NULL) || (local_ip == NULL)) {
|
||||
/* Don't even try to send a SYN packet if we have no route
|
||||
since that will fail. */
|
||||
return ERR_RTE;
|
||||
}
|
||||
/* Use the address as local address of the pcb. */
|
||||
ip_addr_copy(pcb->local_ip, *local_ip);
|
||||
} else {
|
||||
netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
|
||||
if (netif == NULL) {
|
||||
/* Don't even try to send a SYN packet if we have no route
|
||||
since that will fail. */
|
||||
return ERR_RTE;
|
||||
}
|
||||
}
|
||||
}
|
||||
LWIP_ASSERT("netif != NULL", netif != NULL);
|
||||
@ -1213,8 +1217,8 @@ tcp_slowtmr_start:
|
||||
}
|
||||
|
||||
if (pcb_reset) {
|
||||
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
|
||||
pcb->local_port, pcb->remote_port);
|
||||
tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
|
||||
pcb->local_port, pcb->remote_port);
|
||||
}
|
||||
|
||||
err_arg = pcb->callback_arg;
|
||||
|
@ -224,6 +224,13 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
|
||||
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
|
||||
LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
|
||||
|
||||
/* check if PCB is bound to specific netif */
|
||||
if ((pcb->netif_idx != NETIF_NO_INDEX) &&
|
||||
(pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pcb->remote_port == tcphdr->src &&
|
||||
pcb->local_port == tcphdr->dest &&
|
||||
ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
|
||||
@ -250,6 +257,13 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
in the TIME-WAIT state. */
|
||||
for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
|
||||
|
||||
/* check if PCB is bound to specific netif */
|
||||
if ((pcb->netif_idx != NETIF_NO_INDEX) &&
|
||||
(pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pcb->remote_port == tcphdr->src &&
|
||||
pcb->local_port == tcphdr->dest &&
|
||||
ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&
|
||||
@ -516,14 +530,13 @@ aborted:
|
||||
inseg.p = NULL;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* If no matching PCB was found, send a TCP RST (reset) to the
|
||||
sender. */
|
||||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
|
||||
if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
|
||||
TCP_STATS_INC(tcp.proterr);
|
||||
TCP_STATS_INC(tcp.drop);
|
||||
tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
tcp_rst(NULL, ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
ip_current_src_addr(), tcphdr->dest, tcphdr->src);
|
||||
}
|
||||
pbuf_free(p);
|
||||
@ -565,7 +578,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
/* For incoming segments with the ACK flag set, respond with a
|
||||
RST. */
|
||||
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
|
||||
tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
tcp_rst((const struct tcp_pcb*)pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
ip_current_src_addr(), tcphdr->dest, tcphdr->src);
|
||||
} else if (flags & TCP_SYN) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
|
||||
@ -611,6 +624,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */
|
||||
/* inherit socket options */
|
||||
npcb->so_options = pcb->so_options & SOF_INHERITED;
|
||||
npcb->netif_idx = pcb->netif_idx;
|
||||
/* Register the new PCB so that we can begin receiving segments
|
||||
for it. */
|
||||
TCP_REG_ACTIVE(npcb);
|
||||
@ -663,7 +677,7 @@ tcp_timewait_input(struct tcp_pcb *pcb)
|
||||
should be sent in reply */
|
||||
if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) {
|
||||
/* If the SYN is in the window it is an error, send a reset */
|
||||
tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
ip_current_src_addr(), tcphdr->dest, tcphdr->src);
|
||||
return;
|
||||
}
|
||||
@ -813,7 +827,7 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
/* received ACK? possibly a half-open connection */
|
||||
else if (flags & TCP_ACK) {
|
||||
/* send a RST to bring the other side in a non-synchronized state. */
|
||||
tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
ip_current_src_addr(), tcphdr->dest, tcphdr->src);
|
||||
/* Resend SYN immediately (don't wait for rto timeout) to establish
|
||||
connection faster, but do not send more SYNs than we otherwise would
|
||||
@ -873,7 +887,7 @@ tcp_process(struct tcp_pcb *pcb)
|
||||
}
|
||||
} else {
|
||||
/* incorrect ACK number, send RST */
|
||||
tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
tcp_rst(pcb, ackno, seqno + tcplen, ip_current_dest_addr(),
|
||||
ip_current_src_addr(), tcphdr->dest, tcphdr->src);
|
||||
}
|
||||
} else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
|
||||
|
@ -94,6 +94,15 @@
|
||||
/* Forward declarations.*/
|
||||
static err_t tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif);
|
||||
|
||||
static struct netif* tcp_route(const struct tcp_pcb *pcb, const ip_addr_t *src, const ip_addr_t *dst)
|
||||
{
|
||||
if ((pcb != NULL) && (pcb->netif_idx != NETIF_NO_INDEX)) {
|
||||
return netif_get_by_index(pcb->netif_idx);
|
||||
} else {
|
||||
return ip_route(src, dst);
|
||||
}
|
||||
}
|
||||
|
||||
/** Allocate a pbuf and create a tcphdr at p->payload, used for output
|
||||
* functions other than the default tcp_output -> tcp_output_segment
|
||||
* (e.g. tcp_send_empty_ack, etc.)
|
||||
@ -959,7 +968,7 @@ tcp_send_empty_ack(struct tcp_pcb *pcb)
|
||||
}
|
||||
#endif
|
||||
|
||||
netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
|
||||
netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip);
|
||||
if (netif == NULL) {
|
||||
err = ERR_RTE;
|
||||
} else {
|
||||
@ -1040,7 +1049,7 @@ tcp_output(struct tcp_pcb *pcb)
|
||||
for (; useg->next != NULL; useg = useg->next);
|
||||
}
|
||||
|
||||
netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
|
||||
netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip);
|
||||
if (netif == NULL) {
|
||||
return ERR_RTE;
|
||||
}
|
||||
@ -1339,6 +1348,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
|
||||
* tcp_rst() has a number of arguments that are taken from a tcp_pcb for
|
||||
* most other segment output functions.
|
||||
*
|
||||
* @param pcb TCP pcb
|
||||
* @param seqno the sequence number to use for the outgoing segment
|
||||
* @param ackno the acknowledge number to use for the outgoing segment
|
||||
* @param local_ip the local IP address to send the segment from
|
||||
@ -1347,7 +1357,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
|
||||
* @param remote_port the remote TCP port to send the segment to
|
||||
*/
|
||||
void
|
||||
tcp_rst(u32_t seqno, u32_t ackno,
|
||||
tcp_rst(const struct tcp_pcb *pcb, 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)
|
||||
{
|
||||
@ -1379,7 +1389,7 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
||||
TCP_STATS_INC(tcp.xmit);
|
||||
MIB2_STATS_INC(mib2.tcpoutrsts);
|
||||
|
||||
netif = ip_route(local_ip, remote_ip);
|
||||
netif = tcp_route(pcb, local_ip, remote_ip);
|
||||
if (netif != NULL) {
|
||||
#if CHECKSUM_GEN_TCP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
|
||||
@ -1559,7 +1569,7 @@ tcp_keepalive(struct tcp_pcb *pcb)
|
||||
("tcp_keepalive: could not allocate memory for pbuf\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
|
||||
netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip);
|
||||
if (netif == NULL) {
|
||||
err = ERR_RTE;
|
||||
} else {
|
||||
@ -1653,7 +1663,7 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
|
||||
pcb->snd_nxt = snd_nxt;
|
||||
}
|
||||
|
||||
netif = ip_route(&pcb->local_ip, &pcb->remote_ip);
|
||||
netif = tcp_route(pcb, &pcb->local_ip, &pcb->remote_ip);
|
||||
if (netif == NULL) {
|
||||
err = ERR_RTE;
|
||||
} else {
|
||||
|
@ -451,7 +451,7 @@ err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags);
|
||||
|
||||
void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
|
||||
|
||||
void tcp_rst(u32_t seqno, u32_t ackno,
|
||||
void tcp_rst(const struct tcp_pcb* pcb, 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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user