TCP: Implement dual stack support using new IP_ANY_TYPE introduced at UDP

This commit is contained in:
Dirk Ziegelmeier 2016-03-02 23:14:33 +01:00
parent bd131e5e4b
commit f9ce31f98b
3 changed files with 15 additions and 64 deletions

View File

@ -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

View File

@ -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;

View File

@ -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