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->tos = pcb->tos;
#if LWIP_IPV4 && LWIP_IPV6
lpcb->accept_any_ip_version = 0;
IP_SET_TYPE_VAL(lpcb->remote_ip, pcb->local_ip.type);
#endif /* LWIP_IPV4 && LWIP_IPV6 */
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;
}
#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.
*
@ -1535,26 +1500,29 @@ tcp_new(void)
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.
* 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
*/
struct tcp_pcb *
tcp_new_ip6(void)
tcp_new_ip_type(u8_t type)
{
struct tcp_pcb * pcb;
pcb = tcp_alloc(TCP_PRIO_NORMAL);
#if LWIP_IPV4
IP_SET_TYPE_VAL(pcb->local_ip, IPADDR_TYPE_V6);
IP_SET_TYPE_VAL(pcb->remote_ip, IPADDR_TYPE_V6);
#endif /* LWIP_IPV4 */
#if LWIP_IPV4 && LWIP_IPV6
if(pcb != NULL) {
IP_SET_TYPE_VAL(pcb->local_ip, type);
IP_SET_TYPE_VAL(pcb->remote_ip, type);
}
#else
LWIP_UNUSED_ARG(type);
#endif /* LWIP_IPV4 && LWIP_IPV6 */
return pcb;
}
#endif /* LWIP_IPV6 */
/**
* 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;
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
if (lpcb->local_port == tcphdr->dest) {
#if LWIP_IPV4 && LWIP_IPV6
if (lpcb->accept_any_ip_version) {
/* found an ANY-match */
if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) {
/* found an ANY TYPE (IPv4/IPv6) match */
#if SO_REUSE
lpcb_any = lpcb;
lpcb_prev = prev;
#else /* SO_REUSE */
break;
#endif /* SO_REUSE */
} else
#endif /* LWIP_IPV4 && LWIP_IPV6 */
if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) {
} else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) {
if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) {
/* found an exact match */
break;

View File

@ -317,9 +317,6 @@ struct tcp_pcb_listen {
u8_t backlog;
u8_t accepts_pending;
#endif /* TCP_LISTEN_BACKLOG */
#if LWIP_IPV4 && LWIP_IPV6
u8_t accept_any_ip_version;
#endif /* LWIP_IPV4 && LWIP_IPV6 */
};
#if LWIP_EVENT_API
@ -343,6 +340,7 @@ err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
/* Application program's interface: */
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_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);
#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
}
#endif