mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-08-07 15:04:39 +08:00
TCP: Implement dual stack support using new IP_ANY_TYPE introduced at UDP
This commit is contained in:
parent
bd131e5e4b
commit
f9ce31f98b
@ -574,7 +574,6 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|||||||
lpcb->ttl = pcb->ttl;
|
lpcb->ttl = pcb->ttl;
|
||||||
lpcb->tos = pcb->tos;
|
lpcb->tos = pcb->tos;
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
lpcb->accept_any_ip_version = 0;
|
|
||||||
IP_SET_TYPE_VAL(lpcb->remote_ip, pcb->local_ip.type);
|
IP_SET_TYPE_VAL(lpcb->remote_ip, pcb->local_ip.type);
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
ip_addr_copy(lpcb->local_ip, pcb->local_ip);
|
ip_addr_copy(lpcb->local_ip, pcb->local_ip);
|
||||||
@ -593,40 +592,6 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|||||||
return (struct tcp_pcb *)lpcb;
|
return (struct tcp_pcb *)lpcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
|
||||||
/**
|
|
||||||
* Same as tcp_listen_with_backlog, but allows to accept IPv4 and IPv6
|
|
||||||
* connections, if the pcb's local address is set to ANY.
|
|
||||||
*/
|
|
||||||
struct tcp_pcb *
|
|
||||||
tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|
||||||
{
|
|
||||||
struct tcp_pcb *lpcb;
|
|
||||||
struct tcp_pcb_listen *l;
|
|
||||||
|
|
||||||
if (pcb->local_port != 0) {
|
|
||||||
/* Check that there's noone listening on this port already
|
|
||||||
(don't check the IP address since we'll set it to ANY */
|
|
||||||
for (l = tcp_listen_pcbs.listen_pcbs; l != NULL; l = l->next) {
|
|
||||||
if (l->local_port == pcb->local_port) {
|
|
||||||
/* this port is already used */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lpcb = tcp_listen_with_backlog(pcb, backlog);
|
|
||||||
if ((lpcb != NULL) &&
|
|
||||||
ip_addr_isany(&lpcb->local_ip)) {
|
|
||||||
/* The default behavior is to accept connections on either
|
|
||||||
* IPv4 or IPv6, if not bound. */
|
|
||||||
/* @see NETCONN_FLAG_IPV6_V6ONLY for changing this behavior */
|
|
||||||
((struct tcp_pcb_listen*)lpcb)->accept_any_ip_version = 1;
|
|
||||||
}
|
|
||||||
return lpcb;
|
|
||||||
}
|
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the state that tracks the available window space to advertise.
|
* Update the state that tracks the available window space to advertise.
|
||||||
*
|
*
|
||||||
@ -1535,26 +1500,29 @@ tcp_new(void)
|
|||||||
return tcp_alloc(TCP_PRIO_NORMAL);
|
return tcp_alloc(TCP_PRIO_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LWIP_IPV6
|
|
||||||
/**
|
/**
|
||||||
* Creates a new TCP-over-IPv6 protocol control block but doesn't
|
* Creates a new TCP protocol control block but doesn't
|
||||||
* place it on any of the TCP PCB lists.
|
* place it on any of the TCP PCB lists.
|
||||||
* The pcb is not put on any list until binding using tcp_bind().
|
* The pcb is not put on any list until binding using tcp_bind().
|
||||||
*
|
*
|
||||||
|
* @param IP address type, see IPADDR_TYPE_XX definitions.
|
||||||
* @return a new tcp_pcb that initially is in state CLOSED
|
* @return a new tcp_pcb that initially is in state CLOSED
|
||||||
*/
|
*/
|
||||||
struct tcp_pcb *
|
struct tcp_pcb *
|
||||||
tcp_new_ip6(void)
|
tcp_new_ip_type(u8_t type)
|
||||||
{
|
{
|
||||||
struct tcp_pcb * pcb;
|
struct tcp_pcb * pcb;
|
||||||
pcb = tcp_alloc(TCP_PRIO_NORMAL);
|
pcb = tcp_alloc(TCP_PRIO_NORMAL);
|
||||||
#if LWIP_IPV4
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
IP_SET_TYPE_VAL(pcb->local_ip, IPADDR_TYPE_V6);
|
if(pcb != NULL) {
|
||||||
IP_SET_TYPE_VAL(pcb->remote_ip, IPADDR_TYPE_V6);
|
IP_SET_TYPE_VAL(pcb->local_ip, type);
|
||||||
#endif /* LWIP_IPV4 */
|
IP_SET_TYPE_VAL(pcb->remote_ip, type);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
LWIP_UNUSED_ARG(type);
|
||||||
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
return pcb;
|
return pcb;
|
||||||
}
|
}
|
||||||
#endif /* LWIP_IPV6 */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to specify the argument that should be passed callback
|
* Used to specify the argument that should be passed callback
|
||||||
|
@ -262,18 +262,15 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
prev = NULL;
|
prev = NULL;
|
||||||
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
||||||
if (lpcb->local_port == tcphdr->dest) {
|
if (lpcb->local_port == tcphdr->dest) {
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) {
|
||||||
if (lpcb->accept_any_ip_version) {
|
/* found an ANY TYPE (IPv4/IPv6) match */
|
||||||
/* found an ANY-match */
|
|
||||||
#if SO_REUSE
|
#if SO_REUSE
|
||||||
lpcb_any = lpcb;
|
lpcb_any = lpcb;
|
||||||
lpcb_prev = prev;
|
lpcb_prev = prev;
|
||||||
#else /* SO_REUSE */
|
#else /* SO_REUSE */
|
||||||
break;
|
break;
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
} else
|
} else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) {
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
|
||||||
if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) {
|
|
||||||
if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) {
|
if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) {
|
||||||
/* found an exact match */
|
/* found an exact match */
|
||||||
break;
|
break;
|
||||||
|
@ -317,9 +317,6 @@ struct tcp_pcb_listen {
|
|||||||
u8_t backlog;
|
u8_t backlog;
|
||||||
u8_t accepts_pending;
|
u8_t accepts_pending;
|
||||||
#endif /* TCP_LISTEN_BACKLOG */
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
|
||||||
u8_t accept_any_ip_version;
|
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if LWIP_EVENT_API
|
#if LWIP_EVENT_API
|
||||||
@ -343,6 +340,7 @@ err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
|
|||||||
|
|
||||||
/* Application program's interface: */
|
/* Application program's interface: */
|
||||||
struct tcp_pcb * tcp_new (void);
|
struct tcp_pcb * tcp_new (void);
|
||||||
|
struct tcp_pcb * tcp_new_ip_type (u8_t type);
|
||||||
|
|
||||||
void tcp_arg (struct tcp_pcb *pcb, void *arg);
|
void tcp_arg (struct tcp_pcb *pcb, void *arg);
|
||||||
void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept);
|
void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept);
|
||||||
@ -401,18 +399,6 @@ err_t tcp_output (struct tcp_pcb *pcb);
|
|||||||
|
|
||||||
const char* tcp_debug_state_str(enum tcp_state s);
|
const char* tcp_debug_state_str(enum tcp_state s);
|
||||||
|
|
||||||
#if LWIP_IPV6
|
|
||||||
struct tcp_pcb * tcp_new_ip6 (void);
|
|
||||||
#endif /* LWIP_IPV6 */
|
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
|
||||||
struct tcp_pcb * tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog);
|
|
||||||
#define tcp_listen_dual(pcb) tcp_listen_dual_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG)
|
|
||||||
#else /* LWIP_IPV4 && LWIP_IPV6 */
|
|
||||||
#define tcp_listen_dual_with_backlog(pcb, backlog) tcp_listen_with_backlog(pcb, backlog)
|
|
||||||
#define tcp_listen_dual(pcb) tcp_listen(pcb)
|
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user