mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-08-04 21:44:38 +08:00
Work on dual-stack netconn
IPv6 netconns are created as IPADDR_TYPE_ANY raw/udp/tcp PCBs internally bind, connect and sendto now accept IPv6 mapped IPv4 addresses or IPv4 addresses as argument getaddr and receive functions now return IPv6 mapped IPv4 addresses instead of IPv4 addresses This behavior is close to BSD socket API
This commit is contained in:
parent
010f3550b6
commit
1712b06a64
@ -232,6 +232,14 @@ netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
|
|||||||
#endif /* LWIP_MPU_COMPATIBLE */
|
#endif /* LWIP_MPU_COMPATIBLE */
|
||||||
API_MSG_VAR_FREE(msg);
|
API_MSG_VAR_FREE(msg);
|
||||||
|
|
||||||
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
|
/* Dual-stack: Map IPv4 addresses to IPv6 mapped IPv4 */
|
||||||
|
if (NETCONNTYPE_ISIPV6(netconn_type(conn)) && IP_IS_V4(addr)) {
|
||||||
|
ip4_2_ipv6_mapped_ipv4(ip_2_ip6(addr), ip_2_ip4(addr));
|
||||||
|
IP_SET_TYPE(addr, IPADDR_TYPE_V6);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +258,7 @@ err_t
|
|||||||
netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port)
|
netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port)
|
||||||
{
|
{
|
||||||
API_MSG_VAR_DECLARE(msg);
|
API_MSG_VAR_DECLARE(msg);
|
||||||
|
ip_addr_t ipaddr;
|
||||||
err_t err;
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
@ -259,9 +268,27 @@ netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port)
|
|||||||
addr = IP4_ADDR_ANY;
|
addr = IP4_ADDR_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ip_addr_copy(ipaddr, *addr);
|
||||||
|
|
||||||
|
#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 0, use IP_ANY_TYPE to bind
|
||||||
|
*/
|
||||||
|
if ((netconn_get_ipv6only(conn) == 0) &&
|
||||||
|
ip_addr_cmp(&ipaddr, IP6_ADDR_ANY)) {
|
||||||
|
ip_addr_copy(ipaddr, *IP_ANY_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dual-stack: Unmap IPv6 mapped IPv4 addresses */
|
||||||
|
if (IP_IS_V6_VAL(ipaddr) && ip6_addr_isipv6mappedipv4(ip_2_ip6(&ipaddr))) {
|
||||||
|
unmap_ipv6_mapped_ipv4(ip_2_ip4(&ipaddr), ip_2_ip6(&ipaddr));
|
||||||
|
IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
|
|
||||||
API_MSG_VAR_ALLOC(msg);
|
API_MSG_VAR_ALLOC(msg);
|
||||||
API_MSG_VAR_REF(msg).conn = conn;
|
API_MSG_VAR_REF(msg).conn = conn;
|
||||||
API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr);
|
API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(&ipaddr);
|
||||||
API_MSG_VAR_REF(msg).msg.bc.port = port;
|
API_MSG_VAR_REF(msg).msg.bc.port = port;
|
||||||
err = netconn_apimsg(lwip_netconn_do_bind, &API_MSG_VAR_REF(msg));
|
err = netconn_apimsg(lwip_netconn_do_bind, &API_MSG_VAR_REF(msg));
|
||||||
API_MSG_VAR_FREE(msg);
|
API_MSG_VAR_FREE(msg);
|
||||||
@ -282,6 +309,7 @@ err_t
|
|||||||
netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port)
|
netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port)
|
||||||
{
|
{
|
||||||
API_MSG_VAR_DECLARE(msg);
|
API_MSG_VAR_DECLARE(msg);
|
||||||
|
ip_addr_t ipaddr;
|
||||||
err_t err;
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
@ -291,9 +319,27 @@ netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port)
|
|||||||
addr = IP4_ADDR_ANY;
|
addr = IP4_ADDR_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ip_addr_copy(ipaddr, *addr);
|
||||||
|
|
||||||
|
#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 0, use IP_ANY_TYPE to bind
|
||||||
|
*/
|
||||||
|
if ((netconn_get_ipv6only(conn) == 0) &&
|
||||||
|
ip_addr_cmp(&ipaddr, IP6_ADDR_ANY)) {
|
||||||
|
ip_addr_copy(ipaddr, *IP_ANY_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dual-stack: Unmap IPv6 mapped IPv4 addresses */
|
||||||
|
if (IP_IS_V6_VAL(ipaddr) && ip6_addr_isipv6mappedipv4(ip_2_ip6(&ipaddr))) {
|
||||||
|
unmap_ipv6_mapped_ipv4(ip_2_ip4(&ipaddr), ip_2_ip6(&ipaddr));
|
||||||
|
IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
|
|
||||||
API_MSG_VAR_ALLOC(msg);
|
API_MSG_VAR_ALLOC(msg);
|
||||||
API_MSG_VAR_REF(msg).conn = conn;
|
API_MSG_VAR_REF(msg).conn = conn;
|
||||||
API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr);
|
API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(&ipaddr);
|
||||||
API_MSG_VAR_REF(msg).msg.bc.port = port;
|
API_MSG_VAR_REF(msg).msg.bc.port = port;
|
||||||
err = netconn_apimsg(lwip_netconn_do_connect, &API_MSG_VAR_REF(msg));
|
err = netconn_apimsg(lwip_netconn_do_connect, &API_MSG_VAR_REF(msg));
|
||||||
API_MSG_VAR_FREE(msg);
|
API_MSG_VAR_FREE(msg);
|
||||||
@ -561,8 +607,18 @@ netconn_recv_data(struct netconn *conn, void **new_buf)
|
|||||||
#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
|
#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
|
||||||
#if (LWIP_UDP || LWIP_RAW)
|
#if (LWIP_UDP || LWIP_RAW)
|
||||||
{
|
{
|
||||||
|
struct netbuf* nbuf = (struct netbuf*)buf;
|
||||||
|
|
||||||
LWIP_ASSERT("buf != NULL", buf != NULL);
|
LWIP_ASSERT("buf != NULL", buf != NULL);
|
||||||
len = netbuf_len((struct netbuf *)buf);
|
len = netbuf_len(nbuf);
|
||||||
|
|
||||||
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
|
/* Dual-stack: Map IPv4 addresses to IPv6 mapped IPv4 */
|
||||||
|
if (NETCONNTYPE_ISIPV6(netconn_type(conn)) && IP_IS_V4_VAL(nbuf->addr)) {
|
||||||
|
ip4_2_ipv6_mapped_ipv4(ip_2_ip6(&nbuf->addr), ip_2_ip4(&nbuf->addr));
|
||||||
|
IP_SET_TYPE_VAL(nbuf->addr, IPADDR_TYPE_V6);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
}
|
}
|
||||||
#endif /* (LWIP_UDP || LWIP_RAW) */
|
#endif /* (LWIP_UDP || LWIP_RAW) */
|
||||||
|
|
||||||
@ -697,6 +753,15 @@ netconn_send(struct netconn *conn, struct netbuf *buf)
|
|||||||
LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
|
|
||||||
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
|
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
|
||||||
|
|
||||||
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
|
/* Dual-stack: Unmap IPv6 mapped IPv4 addresses */
|
||||||
|
if (IP_IS_V6_VAL(buf->addr) && ip6_addr_isipv6mappedipv4(ip_2_ip6(&buf->addr))) {
|
||||||
|
unmap_ipv6_mapped_ipv4(ip_2_ip4(&buf->addr), ip_2_ip6(&buf->addr));
|
||||||
|
IP_SET_TYPE_VAL(buf->addr, IPADDR_TYPE_V4);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||||
|
|
||||||
API_MSG_VAR_ALLOC(msg);
|
API_MSG_VAR_ALLOC(msg);
|
||||||
API_MSG_VAR_REF(msg).conn = conn;
|
API_MSG_VAR_REF(msg).conn = conn;
|
||||||
API_MSG_VAR_REF(msg).msg.b = buf;
|
API_MSG_VAR_REF(msg).msg.b = buf;
|
||||||
|
@ -545,13 +545,18 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
|
|||||||
static void
|
static void
|
||||||
pcb_new(struct api_msg *msg)
|
pcb_new(struct api_msg *msg)
|
||||||
{
|
{
|
||||||
|
enum lwip_ip_addr_type iptype;
|
||||||
|
|
||||||
LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
|
LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
|
||||||
|
|
||||||
|
/* IPv6: Dual-stack by default, unless netconn_set_ipv6only() is called */
|
||||||
|
iptype = NETCONNTYPE_ISIPV6(netconn_type(msg->conn))? IPADDR_TYPE_ANY : IPADDR_TYPE_V4;
|
||||||
|
|
||||||
/* Allocate a PCB for this connection */
|
/* Allocate a PCB for this connection */
|
||||||
switch(NETCONNTYPE_GROUP(msg->conn->type)) {
|
switch(NETCONNTYPE_GROUP(msg->conn->type)) {
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
case NETCONN_RAW:
|
case NETCONN_RAW:
|
||||||
msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
|
msg->conn->pcb.raw = raw_new_ip_type(iptype, msg->msg.n.proto);
|
||||||
if (msg->conn->pcb.raw != NULL) {
|
if (msg->conn->pcb.raw != NULL) {
|
||||||
raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
|
raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
|
||||||
}
|
}
|
||||||
@ -559,7 +564,7 @@ pcb_new(struct api_msg *msg)
|
|||||||
#endif /* LWIP_RAW */
|
#endif /* LWIP_RAW */
|
||||||
#if LWIP_UDP
|
#if LWIP_UDP
|
||||||
case NETCONN_UDP:
|
case NETCONN_UDP:
|
||||||
msg->conn->pcb.udp = udp_new();
|
msg->conn->pcb.udp = udp_new_ip_type(iptype);
|
||||||
if (msg->conn->pcb.udp != NULL) {
|
if (msg->conn->pcb.udp != NULL) {
|
||||||
#if LWIP_UDPLITE
|
#if LWIP_UDPLITE
|
||||||
if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) {
|
if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) {
|
||||||
@ -575,7 +580,7 @@ pcb_new(struct api_msg *msg)
|
|||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
case NETCONN_TCP:
|
case NETCONN_TCP:
|
||||||
msg->conn->pcb.tcp = tcp_new();
|
msg->conn->pcb.tcp = tcp_new_ip_type(iptype);
|
||||||
if (msg->conn->pcb.tcp != NULL) {
|
if (msg->conn->pcb.tcp != NULL) {
|
||||||
setup_tcp(msg->conn);
|
setup_tcp(msg->conn);
|
||||||
}
|
}
|
||||||
@ -589,15 +594,6 @@ pcb_new(struct api_msg *msg)
|
|||||||
if (msg->conn->pcb.ip == NULL) {
|
if (msg->conn->pcb.ip == NULL) {
|
||||||
msg->err = ERR_MEM;
|
msg->err = ERR_MEM;
|
||||||
}
|
}
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
|
||||||
else {
|
|
||||||
if (NETCONNTYPE_ISIPV6(msg->conn->type)) {
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1114,37 +1110,20 @@ lwip_netconn_do_bind(void *m)
|
|||||||
} else {
|
} else {
|
||||||
msg->err = ERR_VAL;
|
msg->err = ERR_VAL;
|
||||||
if (msg->conn->pcb.tcp != NULL) {
|
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) &&
|
|
||||||
(netconn_get_ipv6only(msg->conn) == 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)) {
|
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
case NETCONN_RAW:
|
case NETCONN_RAW:
|
||||||
msg->err = raw_bind(msg->conn->pcb.raw, ipaddr);
|
msg->err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr));
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_RAW */
|
#endif /* LWIP_RAW */
|
||||||
#if LWIP_UDP
|
#if LWIP_UDP
|
||||||
case NETCONN_UDP:
|
case NETCONN_UDP:
|
||||||
msg->err = udp_bind(msg->conn->pcb.udp, ipaddr, msg->msg.bc.port);
|
msg->err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
case NETCONN_TCP:
|
case NETCONN_TCP:
|
||||||
msg->err = tcp_bind(msg->conn->pcb.tcp, ipaddr, msg->msg.bc.port);
|
msg->err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
default:
|
default:
|
||||||
@ -1398,15 +1377,6 @@ lwip_netconn_do_send(void *m)
|
|||||||
} else {
|
} else {
|
||||||
msg->err = ERR_CONN;
|
msg->err = ERR_CONN;
|
||||||
if (msg->conn->pcb.tcp != NULL) {
|
if (msg->conn->pcb.tcp != NULL) {
|
||||||
|
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
|
||||||
/* Dual-stack: Unmap IPv6 mapped IPv4 addresses */
|
|
||||||
if (NETCONNTYPE_ISIPV6(netconn_type(msg->conn)) && ip6_addr_isipv6mappedipv4(ip_2_ip6(&msg->msg.b->addr))) {
|
|
||||||
unmap_ipv6_mapped_ipv4(ip_2_ip4(&msg->msg.b->addr), ip_2_ip6(&msg->msg.b->addr));
|
|
||||||
IP_SET_TYPE(&msg->msg.b->addr, IPADDR_TYPE_V4);
|
|
||||||
}
|
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
|
||||||
|
|
||||||
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
case NETCONN_RAW:
|
case NETCONN_RAW:
|
||||||
@ -1721,14 +1691,6 @@ lwip_netconn_do_getaddr(void *m)
|
|||||||
msg->conn->pcb.ip->remote_ip);
|
msg->conn->pcb.ip->remote_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
|
||||||
/* Dual-stack: Map IPv4 addresses to IPv6 */
|
|
||||||
if (NETCONNTYPE_ISIPV6(netconn_type(msg->conn)) && IP_IS_V4_VAL(API_EXPR_DEREF(msg->msg.ad.ipaddr))) {
|
|
||||||
ip4_2_ipv6_mapped_ipv4(ip_2_ip6(&API_EXPR_DEREF(msg->msg.ad.ipaddr)), ip_2_ip4(&API_EXPR_DEREF(msg->msg.ad.ipaddr)));
|
|
||||||
IP_SET_TYPE_VAL(API_EXPR_DEREF(msg->msg.ad.ipaddr), IPADDR_TYPE_V6);
|
|
||||||
}
|
|
||||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
|
||||||
|
|
||||||
msg->err = ERR_OK;
|
msg->err = ERR_OK;
|
||||||
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
|
@ -90,6 +90,7 @@ extern "C" {
|
|||||||
#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF3) == NETCONN_UDPLITE)
|
#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF3) == NETCONN_UDPLITE)
|
||||||
#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF3) == NETCONN_UDPNOCHKSUM)
|
#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF3) == NETCONN_UDPNOCHKSUM)
|
||||||
#else /* LWIP_IPV6 */
|
#else /* LWIP_IPV6 */
|
||||||
|
#define NETCONNTYPE_ISIPV6(t) (0)
|
||||||
#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE)
|
#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE)
|
||||||
#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM)
|
#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM)
|
||||||
#endif /* LWIP_IPV6 */
|
#endif /* LWIP_IPV6 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user