From bee5515e9a8e2dc1401b911908d02f54291907ac Mon Sep 17 00:00:00 2001 From: Dirk Ziegelmeier Date: Thu, 3 Mar 2016 22:52:04 +0100 Subject: [PATCH] netconn API: Reimplement dual-stack API to be socket-like. When IPv6 ANY address is used and the NETCONN_FLAG_IPV6_V6ONLY is NOT set, bind/listen on/to IP_ANY_TYPE --- src/api/api_msg.c | 47 ++++++++++++++++++++++++++++-------------- src/include/lwip/api.h | 12 ++--------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c index a4b78b2a..f12c0059 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -523,11 +523,7 @@ pcb_new(struct api_msg_msg *msg) #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: - if(NETCONNTYPE_ANYIP(msg->conn->type)) { - msg->conn->pcb.udp = udp_new_ip_type(IPADDR_TYPE_ANY); - } else { - msg->conn->pcb.udp = udp_new(); - } + msg->conn->pcb.udp = udp_new(); if (msg->conn->pcb.udp != NULL) { #if LWIP_UDPLITE if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) { @@ -543,11 +539,7 @@ pcb_new(struct api_msg_msg *msg) #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: - if(NETCONNTYPE_ANYIP(msg->conn->type)) { - msg->conn->pcb.tcp = tcp_new_ip_type(IPADDR_TYPE_ANY); - } else { - msg->conn->pcb.tcp = tcp_new(); - } + msg->conn->pcb.tcp = tcp_new(); if (msg->conn->pcb.tcp != NULL) { setup_tcp(msg->conn); } @@ -564,7 +556,8 @@ pcb_new(struct api_msg_msg *msg) #if LWIP_IPV4 && LWIP_IPV6 else { if (NETCONNTYPE_ISIPV6(msg->conn->type)) { - IP_SET_TYPE_VAL(msg->conn->pcb.ip->local_ip, IPADDR_TYPE_V6); + /* Convert IPv4 PCB manually to an IPv6 PCB */ + IP_SET_TYPE_VAL(msg->conn->pcb.ip->local_ip, IPADDR_TYPE_V6); IP_SET_TYPE_VAL(msg->conn->pcb.ip->remote_ip, IPADDR_TYPE_V6); } } @@ -1087,20 +1080,37 @@ lwip_netconn_do_bind(struct api_msg_msg *msg) } else { msg->err = ERR_VAL; if (msg->conn->pcb.tcp != NULL) { + const ip_addr_t *ipaddr = API_EXPR_REF(msg->msg.bc.ipaddr); + +#if LWIP_IPV4 && LWIP_IPV6 + /* "Socket API like" dual-stack support: If IP to bind to is IP6_ADDR_ANY, + * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to bind + */ + if (ip_addr_cmp(ipaddr, IP6_ADDR_ANY) && + ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0)) { + /* change PCB type to IPADDR_TYPE_ANY */ + IP_SET_TYPE_VAL(msg->conn->pcb.ip->local_ip, IPADDR_TYPE_ANY); + IP_SET_TYPE_VAL(msg->conn->pcb.ip->remote_ip, IPADDR_TYPE_ANY); + + /* bind to IPADDR_TYPE_ANY */ + ipaddr = IP_ANY_TYPE; + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: - msg->err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); + msg->err = raw_bind(msg->conn->pcb.raw, ipaddr); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: - msg->err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); + msg->err = udp_bind(msg->conn->pcb.udp, ipaddr, msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: - msg->err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); + msg->err = tcp_bind(msg->conn->pcb.tcp, ipaddr, msg->msg.bc.port); break; #endif /* LWIP_TCP */ default: @@ -1275,9 +1285,14 @@ lwip_netconn_do_listen(struct api_msg_msg *msg) msg->err = ERR_VAL; } else { #if LWIP_IPV4 && LWIP_IPV6 - if (ip_addr_isany_val(msg->conn->pcb.tcp->local_ip) && + /* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY, + * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen + */ + if (ip_addr_cmp(API_EXPR_REF(msg->msg.bc.ipaddr), IP6_ADDR_ANY) && ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0)) { - IP_SET_TYPE_VAL(msg->conn->pcb.tcp->local_ip, IPADDR_TYPE_ANY); + /* change PCB type to IPADDR_TYPE_ANY */ + IP_SET_TYPE_VAL(msg->conn->pcb.tcp->local_ip, IPADDR_TYPE_ANY); + IP_SET_TYPE_VAL(msg->conn->pcb.tcp->remote_ip, IPADDR_TYPE_ANY); } #endif /* LWIP_IPV4 && LWIP_IPV6 */ diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index 33c36e04..9ef9e78a 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -79,9 +79,6 @@ extern "C" { #endif /* LWIP_IPV6 */ -#define NETCONN_TYPE_IP_ANY 0x04 -#define NETCONNTYPE_ANYIP(t) (((t)&NETCONN_TYPE_IP_ANY) != 0) - /* Helpers to process several netconn_types by the same code */ #define NETCONNTYPE_GROUP(t) ((t)&0xF0) #define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0) @@ -115,15 +112,10 @@ enum netconn_type { #endif /* LWIP_IPV6 */ /* NETCONN_RAW Group */ - NETCONN_RAW = 0x40, + NETCONN_RAW = 0x40 #if LWIP_IPV6 - NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6, /* 0x48 */ + , NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */ #endif /* LWIP_IPV6 */ - - /* NETCONN dual stack */ - NETCONN_TCP_IPANY = NETCONN_TCP | NETCONN_TYPE_IP_ANY, /* 0x14 */ - NETCONN_UDP_IPANY = NETCONN_UDP | NETCONN_TYPE_IP_ANY /* 0x24 */ -/* NETCONN_RAW_IPANY = NETCONN_RAW | NETCONN_TYPE_IP_ANY, */ /* 0x44 */ }; /** Current state of the netconn. Non-TCP netconns are always