lwip: Enable IPV6_ONLY option for UDP sockets (BSD & netconn)

* setsockopt(s, IPV6_ONLY, &one, sizeof(int)) will disable IPV6-only
  mode. Incoming/outgoing IPV4 packets are dropped.

* Otherwise, sockets bound to IPV6_ANY_ADDR can receive unicast packets
  for IPV4 or IPV6.

* sendto() a IPV6-mapped-IPV4 address on a UDP socket works correctly
  (not supported for RAW or TCP sockets.)

* getaddrinfo() option AI_V4MAPPED is implemented.

As well as extending support to TCP & RAW, there is some potential improvement
to dropping incoming packets - the drop happens a bit late in the process and
there is no "ICMP port unreachable" response sent.
This commit is contained in:
Angus Gratton
2017-07-07 19:27:00 +08:00
committed by Angus Gratton
parent 961180617e
commit 04a2cefb26
5 changed files with 67 additions and 11 deletions

View File

@@ -180,6 +180,16 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
return;
}
#if LWIP_IPV6
/* This should be eventually moved to a flag on the UDP PCB, and this drop can happen
more correctly in udp_input(). This will also allow icmp_dest_unreach() to be called. */
if (conn->flags & NETCONN_FLAG_IPV6_V6ONLY && !ip_current_is_v6()) {
LWIP_DEBUGF(API_MSG_DEBUG, ("recv_udp: Dropping IPv4 UDP packet (IPv6-only socket)"));
pbuf_free(p);
return;
}
#endif
buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
if (buf == NULL) {
pbuf_free(p);
@@ -1388,6 +1398,12 @@ lwip_netconn_do_send(void *m)
if (ERR_IS_FATAL(msg->conn->last_err)) {
msg->err = msg->conn->last_err;
#if LWIP_IPV4 && LWIP_IPV6
} else if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) &&
IP_IS_V4MAPPEDV6(&msg->msg.b->addr)) {
LWIP_DEBUGF(API_MSG_DEBUG, ("lwip_netconn_do_send: Dropping IPv4 packet on IPv6-only socket"));
msg->err = ERR_VAL;
#endif /* LWIP_IPV4 && LWIP_IPV6 */
} else {
msg->err = ERR_CONN;
if (msg->conn->pcb.tcp != NULL) {