]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/commitdiff
Applied patch by James Smith to implement IPV6_V6ONLY support in
authorJames Smith <jsmith@ecoscentric.com>
Tue, 3 Jul 2012 19:16:04 +0000 (13:16 -0600)
committerIvan Delamer <delamer@inicotech.com>
Tue, 3 Jul 2012 19:16:04 +0000 (13:16 -0600)
sockets and netconns.

Change-Id: I2ecd8e218703114890b2d678cc1ccf997a16f5e3

src/api/api_msg.c
src/api/sockets.c
src/include/lwip/api.h
src/include/lwip/sockets.h

index d46cd13e04490434f6eaba8e558eb5849f0559a1..7ec9cfbaabc74d47ed9490b01b888f3868de421f 100644 (file)
@@ -1076,11 +1076,23 @@ lwip_netconn_do_listen(struct api_msg_msg *msg)
     if (msg->conn->pcb.tcp != NULL) {
       if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
         if (msg->conn->state == NETCONN_NONE) {
+          struct tcp_pcb* lpcb;
+#if LWIP_IPV6
+          if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) {
+#if TCP_LISTEN_BACKLOG
+            lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
+#else  /* TCP_LISTEN_BACKLOG */
+            lpcb = tcp_listen_dual(msg->conn->pcb.tcp);
+#endif /* TCP_LISTEN_BACKLOG */
+          } else
+#endif /* LWIP_IPV6 */
+          {
 #if TCP_LISTEN_BACKLOG
-          struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
+            lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
 #else  /* TCP_LISTEN_BACKLOG */
-          struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp);
+            lpcb = tcp_listen(msg->conn->pcb.tcp);
 #endif /* TCP_LISTEN_BACKLOG */
+          }
           if (lpcb == NULL) {
             /* in this case, the old pcb is still allocated */
             msg->err = ERR_MEM;
index 1b236a8499000e5038d2694aaa549158173d3dce..8a05aed6c96e746159bd0217c4b9cad865d9fe30 100644 (file)
@@ -1664,6 +1664,24 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
     }  /* switch (optname) */
     break;
 #endif /* LWIP_TCP */
+
+#if LWIP_IPV6
+/* Level: IPPROTO_IPV6 */
+  case IPPROTO_IPV6:
+    switch (optname) {
+    case IPV6_V6ONLY:
+      if (*optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+    default:
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n",
+                                  s, optname));
+      err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_IPV6 */
+
 #if LWIP_UDP && LWIP_UDPLITE
 /* Level: IPPROTO_UDPLITE */
   case IPPROTO_UDPLITE:
@@ -1902,6 +1920,23 @@ lwip_getsockopt_internal(void *arg)
     }  /* switch (optname) */
     break;
 #endif /* LWIP_TCP */
+
+#if LWIP_IPV6
+/* Level: IPPROTO_IPV6 */
+  case IPPROTO_IPV6:
+    switch (optname) {
+    case IPV6_V6ONLY:
+      *(int*)optval = ((sock->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) ? 1 : 0);
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY) = %d\n",
+                  s, *(int *)optval));
+      break;
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_IPV6 */
+
 #if LWIP_UDP && LWIP_UDPLITE
   /* Level: IPPROTO_UDPLITE */
   case IPPROTO_UDPLITE:
@@ -2081,6 +2116,24 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
     }  /* switch (optname) */
     break;
 #endif /* LWIP_TCP */
+
+#if LWIP_IPV6
+/* Level: IPPROTO_IPV6 */
+  case IPPROTO_IPV6:
+    switch (optname) {
+    case IPV6_V6ONLY:
+      if (optlen < sizeof(int)) {
+        err = EINVAL;
+      }
+      break;
+      default:
+        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n",
+                    s, optname));
+        err = ENOPROTOOPT;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_IPV6 */
+
 #if LWIP_UDP && LWIP_UDPLITE
 /* Level: IPPROTO_UDPLITE */
   case IPPROTO_UDPLITE:
@@ -2310,6 +2363,27 @@ lwip_setsockopt_internal(void *arg)
     }  /* switch (optname) */
     break;
 #endif /* LWIP_TCP*/
+
+#if LWIP_IPV6
+/* Level: IPPROTO_IPV6 */
+  case IPPROTO_IPV6:
+    switch (optname) {
+    case IPV6_V6ONLY:
+      if (*(int*)optval) {
+        sock->conn->flags |= NETCONN_FLAG_IPV6_V6ONLY;
+      } else {
+        sock->conn->flags &= ~NETCONN_FLAG_IPV6_V6ONLY;
+      }
+      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n",
+                  s, ((sock->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) ? 1 : 0)));
+      break;
+    default:
+      LWIP_ASSERT("unhandled optname", 0);
+      break;
+    }  /* switch (optname) */
+    break;
+#endif /* LWIP_IPV6 */
+
 #if LWIP_UDP && LWIP_UDPLITE
   /* Level: IPPROTO_UDPLITE */
   case IPPROTO_UDPLITE:
index 4c985800848923288b229a6c5bd70f073c998aa2..ac58eebbba2fbd1e4355bea7e7abe5c5dcaf749b 100644 (file)
@@ -73,6 +73,12 @@ extern "C" {
 /** If a nonblocking write has been rejected before, poll_tcp needs to
     check if the netconn is writable again */
 #define NETCONN_FLAG_CHECK_WRITESPACE         0x10
+#if LWIP_IPV6
+/** If this flag is set then only IPv6 communication is allowed on the
+    netconn. As per RFC#3493 this features defaults to OFF allowing
+    dual-stack usage by default. */
+#define NETCONN_FLAG_IPV6_V6ONLY              0x20
+#endif /* LWIP_IPV6 */
 
 
 /* Helpers to process several netconn_types by the same code */
index 697f200d60fc73e0493a9ddfa396f21850bdd72f..73461374b26b8abab0121579d3283d6ae5a871f0 100644 (file)
@@ -148,6 +148,9 @@ struct linger {
 #define IPPROTO_IP      0
 #define IPPROTO_TCP     6
 #define IPPROTO_UDP     17
+#if LWIP_IPV6
+#define IPPROTO_IPV6    41
+#endif /* LWIP_IPV6 */
 #define IPPROTO_UDPLITE 136
 
 /* Flags we can use with send and recv. */
@@ -175,6 +178,13 @@ struct linger {
 #define TCP_KEEPCNT    0x05    /* set pcb->keep_cnt   - Use number of probes sent for get/setsockopt */
 #endif /* LWIP_TCP */
 
+#if LWIP_IPV6
+/*
+ * Options for level IPPROTO_IPV6
+ */
+#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */
+#endif /* LWIP_IPV6 */
+
 #if LWIP_UDP && LWIP_UDPLITE
 /*
  * Options for level IPPROTO_UDPLITE