be applied. Could you re-send it as a compressed file to make sure that
Post by Joan LledóPORT: Use always interruptible functions for waiting
Return SYS_ARCH_INTR when a waiting thread is cancelled
POLL: Use always interruptible functions for waiting
Fix some debug messages
MAX_SOCKETS: Protect the socket list every time it's read
All but AUTOCONF: Converted to DOS format to mach lwip sources
All: Remove fuzziness
---
debian/patches/bug-36167 | 8 +-
debian/patches/errno | 20 +-
debian/patches/max_sockets | 75 +-
debian/patches/poll | 146 ++--
debian/patches/port | 1943 +++++++++++++++++++++-----------------------
debian/patches/posix | 1733 ++++++++++++++++++++-------------------
6 files changed, 1917 insertions(+), 2008 deletions(-)
diff --git a/debian/patches/bug-36167 b/debian/patches/bug-36167
index 4220301..e0a6d92 100644
--- a/debian/patches/bug-36167
+++ b/debian/patches/bug-36167
@@ -1,10 +1,8 @@
Already upstream
-diff --git a/src/core/tcp.c b/src/core/tcp.c
-index 7103a52..ccfa3c1 100644
--- a/src/core/tcp.c
+++ b/src/core/tcp.c
pcb->rcv_wnd = TCP_WND_MAX(pcb);
} else if (pcb->rcv_wnd == 0) {
/* rcv_wnd overflowed */
@@ -13,11 +11,9 @@ index 7103a52..ccfa3c1 100644
/* In passive close, we allow this, since the FIN bit is added to rcv_wnd
by the stack itself, since it is not mandatory for an application
to call tcp_recved() for the FIN bit, but e.g. the netconn API does so. */
-diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h
-index 3845b9f..fb7fa17 100644
--- a/src/include/lwip/tcp.h
+++ b/src/include/lwip/tcp.h
/* for compatibility with older implementation */
#define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6)
diff --git a/debian/patches/errno b/debian/patches/errno
index 1cf5d42..9aed02a 100644
--- a/debian/patches/errno
+++ b/debian/patches/errno
@@ -1,10 +1,8 @@
Already upstream
-Index: lwip/src/api/sockets.c
-===================================================================
---- lwip.orig/src/api/sockets.c
-+++ lwip/src/api/sockets.c
+--- a/src/api/sockets.c
++++ b/src/api/sockets.c
/** error happened for this socket, set by event_callback(), tested by select */
u16_t errevent;
/** last error that occurred on this socket (in fact, all our errnos fit into an u8_t) */
@@ -13,7 +11,7 @@ Index: lwip/src/api/sockets.c
/** counter of how many threads are waiting for this socket using select */
SELWAIT_T select_waiting;
};
#define sock_set_errno(sk, e) do { \
const int sockerr = (e); \
@@ -22,7 +20,7 @@ Index: lwip/src/api/sockets.c
set_errno(sockerr); \
} while (0)
static void lwip_getsockopt_callback(void *arg);
static void lwip_setsockopt_callback(void *arg);
#endif
@@ -33,7 +31,7 @@ Index: lwip/src/api/sockets.c
#if LWIP_IPV4 && LWIP_IPV6
static void
int
lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
{
@@ -42,7 +40,7 @@ Index: lwip/src/api/sockets.c
struct lwip_sock *sock = get_socket(s);
#if !LWIP_TCPIP_CORE_LOCKING
LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
* same argument as lwip_getsockopt, either called directly or through callback
*/
@@ -55,7 +53,7 @@ Index: lwip/src/api/sockets.c
struct lwip_sock *sock = tryget_socket(s);
if (!sock) {
return EBADF;
int
lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
{
@@ -64,7 +62,7 @@ Index: lwip/src/api/sockets.c
struct lwip_sock *sock = get_socket(s);
#if !LWIP_TCPIP_CORE_LOCKING
LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
* same argument as lwip_setsockopt, either called directly or through callback
*/
diff --git a/debian/patches/max_sockets b/debian/patches/max_sockets
index 53b4555..1862444 100644
--- a/debian/patches/max_sockets
+++ b/debian/patches/max_sockets
@@ -33,7 +33,7 @@ Won't get to upstream
* in seconds. (does not require sockets.c, and will affect tcp.c)
--- a/src/api/sockets.c
+++ b/src/api/sockets.c
/** Contains all internal pointers and states used for a socket */
struct lwip_sock {
@@ -46,7 +46,7 @@ Won't get to upstream
/** sockets currently are built on netconns, each socket has one netconn */
struct netconn *conn;
/** data that was left from the previous read */
static void lwip_socket_drop_registered_memberships(int s);
#endif /* LWIP_IGMP */
@@ -60,7 +60,7 @@ Won't get to upstream
/** The global list of tasks waiting for select */
static struct lwip_select_cb *select_cb_list;
/** This counter is increased from lwip_select when the list is changed
s -= LWIP_SOCKET_OFFSET;
@@ -76,10 +76,13 @@ Won't get to upstream
}
+#if LWIP_SOCKET_OPEN_COUNT
++ SYS_ARCH_DECL_PROTECT(lev);
++ SYS_ARCH_PROTECT(lev);
+ for(sock = sockets; sock != NULL; sock = sock->next) {
+ if(sock->count == s)
+ break;
+ }
++ SYS_ARCH_UNPROTECT(lev);
+#else /* LWIP_SOCKET_OPEN_COUNT */
sock = &sockets[s];
+#endif /* LWIP_SOCKET_OPEN_COUNT */
@@ -89,9 +92,14 @@ Won't get to upstream
LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s + LWIP_SOCKET_OFFSET));
set_errno(EBADF);
return NULL;
+ static struct lwip_sock *
tryget_socket(int s)
{
++#if LWIP_SOCKET_OPEN_COUNT
++ struct lwip_sock *sock;
++#endif /* LWIP_SOCKET_OPEN_COUNT */
++
s -= LWIP_SOCKET_OFFSET;
- if ((s < 0) || (s >= NUM_SOCKETS)) {
+ if ((s < 0)
@@ -102,11 +110,13 @@ Won't get to upstream
return NULL;
}
+#if LWIP_SOCKET_OPEN_COUNT
-+ struct lwip_sock *sock;
++ SYS_ARCH_DECL_PROTECT(lev);
++ SYS_ARCH_PROTECT(lev);
+ for(sock = sockets; sock != NULL; sock = sock->next) {
+ if(sock->count == s)
+ break;
+ }
++ SYS_ARCH_UNPROTECT(lev);
+ return sock;
+#else /* LWIP_SOCKET_OPEN_COUNT */
if (!sockets[s].conn) {
@@ -117,7 +127,7 @@ Won't get to upstream
}
/**
alloc_socket(struct netconn *newconn, int accepted)
{
int i;
@@ -199,33 +209,34 @@ Won't get to upstream
}
/** Free a socket. The socket's netconn must have been
- static void
free_socket(struct lwip_sock *sock, int is_tcp)
{
-- void *lastdata;
--
-- lastdata = sock->lastdata;
-+ void *lastdata = sock->lastdata;
+ void *lastdata;
+#if LWIP_SOCKET_OPEN_COUNT
+ struct lwip_sock **it = &sockets;
-+
-+ while(*it != sock) it = &(*it)->next;
-+ *it = (*it)->next;
-+ mem_free(sock);
-+#else /* LWIP_SOCKET_OPEN_COUNT */
++#endif /* LWIP_SOCKET_OPEN_COUNT */
+
+ lastdata = sock->lastdata;
sock->lastdata = NULL;
- sock->lastoffset = 0;
sock->err = 0;
+
/* Protect socket array */
- SYS_ARCH_SET(sock->conn, NULL);
- /* don't use 'sock' after this line, as another task might have allocated it */
+- SYS_ARCH_SET(sock->conn, NULL);
++ SYS_ARCH_DECL_PROTECT(lev);
++ SYS_ARCH_PROTECT(lev);
++ sock->conn = NULL;
++#if LWIP_SOCKET_OPEN_COUNT
++ while(*it != sock) it = &(*it)->next;
++ *it = (*it)->next;
++ mem_free(sock);
+#endif /* LWIP_SOCKET_OPEN_COUNT */
++ SYS_ARCH_UNPROTECT(lev);
+ /* don't use 'sock' after this line, as another task might have allocated it */
if (lastdata != NULL) {
- if (is_tcp) {
sock_set_errno(sock, ENFILE);
return -1;
}
@@ -238,12 +249,12 @@ Won't get to upstream
--- a/port/include/lwipopts.h
+++ b/port/include/lwipopts.h
@@ -26,6 +26,9 @@
- /* Don't rename Sockets API functions */
- #define LWIP_COMPAT_SOCKETS 0
-
-+/* Don't limit the number of sockets */
-+#define LWIP_SOCKET_OPEN_COUNT 1
-+
- /* We're using lwip_poll() */
- #define LWIP_POLL 1
-
+ /* Don't rename Sockets API functions */
+ #define LWIP_COMPAT_SOCKETS 0
+
++/* Don't limit the number of sockets */
++#define LWIP_SOCKET_OPEN_COUNT 1
++
+ /* We're using lwip_poll() */
+ #define LWIP_POLL 1
+
diff --git a/debian/patches/poll b/debian/patches/poll
index c060cf3..198e258 100644
--- a/debian/patches/poll
+++ b/debian/patches/poll
@@ -2,7 +2,7 @@ Already upstream
--- a/src/api/sockets.c
+++ b/src/api/sockets.c
fd_set *writeset;
/** unimplemented: exceptset passed to select */
fd_set *exceptset;
@@ -15,7 +15,7 @@ Already upstream
/** don't signal the same semaphore twice: set to 1 when signalled */
int sem_signalled;
/** semaphore to wake up a task waiting for select */
return lwip_sendmsg(s, &msg, 0);
}
@@ -67,7 +67,7 @@ Already upstream
/**
* Go through the readset and writeset lists and see which socket of the sockets
* set in the sets has events. On return, readset, writeset and exceptset have
select_cb.readset = readset;
select_cb.writeset = writeset;
select_cb.exceptset = exceptset;
@@ -78,7 +78,7 @@ Already upstream
select_cb.sem_signalled = 0;
#if LWIP_NETCONN_SEM_PER_THREAD
select_cb.sem = LWIP_NETCONN_THREAD_SEM_GET();
}
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
@@ -100,7 +100,7 @@ Already upstream
/* Increase select_waiting for each socket we are interested in */
maxfdp2 = maxfdp1;
SYS_ARCH_UNPROTECT(lev);
}
}
@@ -123,7 +123,7 @@ Already upstream
#if LWIP_NETCONN_SEM_PER_THREAD
if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) {
return nready;
}
@@ -304,7 +304,7 @@ Already upstream
+ LWIP_ASSERT("timeout > 0", timeout > 0);
+ msectimeout = timeout;
+ }
-+ waitres = sys_arch_sem_wait_intr(SELECT_SEM_PTR(select_cb.sem), msectimeout);
++ waitres = sys_arch_sem_wait(SELECT_SEM_PTR(select_cb.sem), msectimeout);
+#if LWIP_NETCONN_SEM_PER_THREAD
+ waited = 1;
+#endif
@@ -332,12 +332,12 @@ Already upstream
+
+ if (waitres == SYS_ARCH_TIMEOUT) {
+ /* Timeout */
-+ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
++ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: timeout expired\n"));
+ goto return_success;
+ }
+ }
+
-+ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
++ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: nready=%d\n", nready));
+ set_errno(0);
+ return nready;
@@ -377,7 +377,7 @@ Already upstream
/**
* Callback registered in the netconn layer for each socket-netconn.
* Processes recvevent (data available) and wakes up tasks waiting for select.
if (scb->sem_signalled == 0) {
/* semaphore not signalled yet */
int do_signal = 0;
@@ -419,7 +419,7 @@ Already upstream
if (do_signal) {
--- a/src/include/lwip/opt.h
+++ b/src/include/lwip/opt.h
#endif
/**
@@ -439,49 +439,49 @@ Already upstream
* names (read, write & close). (only used if you use sockets.c)
--- a/src/include/lwip/lwip_sockets.h
+++ b/src/include/lwip/lwip_sockets.h
- #error "external FD_SETSIZE too small for number of sockets"
- #endif /* FD_SET */
-
-+#if LWIP_POLL == 2
-+#define POLLIN 0x01
-+#define POLLOUT 0x02
-+#define POLLERR 0x04
-+#define POLLNVAL 0x08
-+/* No support for POLLPRI, POLLHUP, POLLMSG, POLLRDBAND, POLLWRBAND. */
-+typedef int nfds_t;
-+struct pollfd
-+{
-+ int fd;
-+ short events;
-+ short revents;
-+};
-+#endif
-+
- /** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
- * by your system, set this to 0 and include <sys/time.h> in cc.h */
- #ifndef LWIP_TIMEVAL_PRIVATE
- #define lwip_sendto sendto
- #define lwip_socket socket
- #define lwip_select select
-+#if LWIP_POLL
-+#define lwip_poll poll
-+#endif
- #define lwip_ioctlsocket ioctl
-
- #if LWIP_POSIX_SOCKETS_IO_NAMES
- #define socket(domain,type,protocol) lwip_socket(domain,type,protocol)
- #define select(maxfdp1,readset,writeset,exceptset,timeout) lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
-+#if LWIP_POLL
-+#define poll(fds,nfds,timeout) lwip_poll(fds,nfds,timeout)
-+#endif
- #define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp)
-
+ #error "external FD_SETSIZE too small for number of sockets"
+ #endif /* FD_SET */
+
++#if LWIP_POLL == 2
++#define POLLIN 0x01
++#define POLLOUT 0x02
++#define POLLERR 0x04
++#define POLLNVAL 0x08
++/* No support for POLLPRI, POLLHUP, POLLMSG, POLLRDBAND, POLLWRBAND. */
++typedef int nfds_t;
++struct pollfd
++{
++ int fd;
++ short events;
++ short revents;
++};
++#endif
++
+ /** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
+ * by your system, set this to 0 and include <sys/time.h> in cc.h */
+ #ifndef LWIP_TIMEVAL_PRIVATE
+ #define lwip_sendto sendto
+ #define lwip_socket socket
+ #define lwip_select select
++#if LWIP_POLL
++#define lwip_poll poll
++#endif
+ #define lwip_ioctlsocket ioctl
+
+ #if LWIP_POSIX_SOCKETS_IO_NAMES
+ #define socket(domain,type,protocol) lwip_socket(domain,type,protocol)
+ #define select(maxfdp1,readset,writeset,exceptset,timeout) lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
++#if LWIP_POLL
++#define poll(fds,nfds,timeout) lwip_poll(fds,nfds,timeout)
++#endif
+ #define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp)
+
--- a/src/include/lwip/sockets.h
+++ b/src/include/lwip/sockets.h
@@ -75,6 +75,9 @@
@@ -497,24 +497,24 @@ Already upstream
--- a/port/include/lwipopts.h
+++ b/port/include/lwipopts.h
@@ -26,6 +26,9 @@
- /* Don't rename Sockets API functions */
- #define LWIP_COMPAT_SOCKETS 0
-
-+/* We're using lwip_poll() */
-+#define LWIP_POLL 1
-+
- /* Use Glibc's sockets headers */
- #define LWIP_STD_SOCKETS 1
- #define LWIP_INCLUDE_STD_SOCKETS "posix/socket.h"
+ /* Don't rename Sockets API functions */
+ #define LWIP_COMPAT_SOCKETS 0
+
++/* We're using lwip_poll() */
++#define LWIP_POLL 1
++
+ /* Use Glibc's sockets headers */
+ #define LWIP_STD_SOCKETS 1
+ #define LWIP_INCLUDE_STD_SOCKETS "posix/socket.h"
--- a/port/include/arch/cc.h
+++ b/port/include/arch/cc.h
- #include <netinet/tcp.h>
- #include <netinet/udp.h>
-
-+/* We use poll() instead of select()*/
-+#include <poll.h>
-+
- /* Use our own htons() and pals */
- #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
-
+ /* Use our own ioctls */
+ #include <sys/ioctl.h>
+
++/* We use poll() instead of select()*/
++#include <poll.h>
++
+ /* Use our own htons() and pals */
+ #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
+
diff --git a/debian/patches/port b/debian/patches/port
index c6c9d82..b0ab392 100644
--- a/debian/patches/port
+++ b/debian/patches/port
@@ -3,1022 +3,941 @@ Not intended to be upstream
--- /dev/null
+++ b/port/include/arch/cc.h
@@ -0,0 +1,68 @@
-+/*
-+ Copyright (C) 2017 Free Software Foundation, Inc.
-+ Written by Joan Lledó.
-+
-+ This file is part of the GNU Hurd.
-+
-+ The GNU Hurd is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ The GNU Hurd is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#ifndef LWIP_ARCH_CC_H
-+#define LWIP_ARCH_CC_H
-+
-+#include <stdlib.h> /* rand() */
-+#include <stdio.h> /* printf() */
-+
-+/* Use Glibc's fcntl() macros */
-+#include <fcntl.h>
-+
-+/* Use Glibc's <errno.h> */
-+#include <errno.h>
-+#define LWIP_ERR_T int
-+
-+/* System provides its own struct timeval */
-+#define LWIP_TIMEVAL_PRIVATE 0
-+#include <sys/time.h>
-+
-+/* We need INT_MAX */
-+#include <limits.h>
-+
-+/* Use our own ioctls */
-+#include <sys/ioctl.h>
-+
-+/* Use our own htons() and pals */
-+#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
-+
-+/* printf() codes */
-+#define S16_F "d"
-+#define U16_F "u"
-+#define X16_F "x"
-+
-+#define S32_F "d"
-+#define U32_F "u"
-+#define X32_F "x"
-+
-+#ifdef LWIP_DEBUG
-+#define LWIP_PLATFORM_DIAG(x) do { printf x; fflush(NULL);} while(0)
-+#endif
-+
-+/* Redefine LWIP_ERROR to not abort the process if the assertion failed */
-+#define LWIP_ERROR(message, expression, handler) \
-+ do { \
-+ if (!(expression)) { \
-+ printf("Assertion \"%s\" failed at line %d in %s\n", \
-+ message, __LINE__, __FILE__); fflush(NULL); \
-+ handler;} \
-+ } while(0)
-+
-+#endif /* LWIP_ARCH_CC_H */
++/*
++ Copyright (C) 2017 Free Software Foundation, Inc.
++ Written by Joan Lledó.
++
++ This file is part of the GNU Hurd.
++
++ The GNU Hurd is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public License as
++ published by the Free Software Foundation; either version 2, or (at
++ your option) any later version.
++
++ The GNU Hurd is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
++
++#ifndef LWIP_ARCH_CC_H
++#define LWIP_ARCH_CC_H
++
++#include <stdlib.h> /* rand() */
++#include <stdio.h> /* printf() */
++
++/* Use Glibc's fcntl() macros */
++#include <fcntl.h>
++
++/* Use Glibc's <errno.h> */
++#include <errno.h>
++#define LWIP_ERR_T int
++
++/* System provides its own struct timeval */
++#define LWIP_TIMEVAL_PRIVATE 0
++#include <sys/time.h>
++
++/* We need INT_MAX */
++#include <limits.h>
++
++/* Use our own ioctls */
++#include <sys/ioctl.h>
++
++/* Use our own htons() and pals */
++#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
++
++/* printf() codes */
++#define S16_F "d"
++#define U16_F "u"
++#define X16_F "x"
++
++#define S32_F "d"
++#define U32_F "u"
++#define X32_F "x"
++
++#ifdef LWIP_DEBUG
++#define LWIP_PLATFORM_DIAG(x) do { printf x; fflush(NULL);} while(0)
++#endif
++
++/* Redefine LWIP_ERROR to not abort the process if the assertion failed */
++#define LWIP_ERROR(message, expression, handler) \
++ do { \
++ if (!(expression)) { \
++ printf("Assertion \"%s\" failed at line %d in %s\n", \
++ message, __LINE__, __FILE__); fflush(NULL); \
++ handler;} \
++ } while(0)
++
++#endif /* LWIP_ARCH_CC_H */
--- /dev/null
+++ b/port/include/arch/sys_arch.h
-+/*
-+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without modification,
-+ *
-+ * 1. Redistributions of source code must retain the above copyright notice,
-+ * this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ *
-+ * This file is part of the lwIP TCP/IP stack.
-+ *
-+ *
-+ */
-+#ifndef LWIP_ARCH_SYS_ARCH_H
-+#define LWIP_ARCH_SYS_ARCH_H
-+
-+#define SYS_MBOX_NULL NULL
-+#define SYS_SEM_NULL NULL
-+
-+/* Return code for an interrupted timed wait */
-+#define SYS_ARCH_INTR 0xfffffffeUL
-+
-+typedef u32_t sys_prot_t;
-+
-+struct sys_sem;
-+typedef struct sys_sem * sys_sem_t;
-+#define sys_sem_valid(sem) (*(sem) != NULL)
-+#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL; }}while(0)
-+
-+struct sys_mutex;
-+typedef struct sys_mutex * sys_mutex_t;
-+#define sys_mutex_valid(mutex) sys_sem_valid(mutex)
-+#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
-+
-+struct sys_mbox;
-+typedef struct sys_mbox * sys_mbox_t;
-+#define sys_mbox_valid(mbox) sys_sem_valid(mbox)
-+#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
-+
-+struct sys_thread;
-+typedef struct sys_thread * sys_thread_t;
-+
-+u32_t sys_arch_sem_wait_intr(sys_sem_t *sem, u32_t timeout);
-+
-+#endif /* LWIP_ARCH_SYS_ARCH_H */
-+
++/*
++ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without modification,
++ *
++ * 1. Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * 3. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
++ * OF SUCH DAMAGE.
++ *
++ * This file is part of the lwIP TCP/IP stack.
++ *
++ *
++ */
++#ifndef LWIP_ARCH_SYS_ARCH_H
++#define LWIP_ARCH_SYS_ARCH_H
++
++#define SYS_MBOX_NULL NULL
++#define SYS_SEM_NULL NULL
++
++/* Return code for an interrupted timed wait */
++#define SYS_ARCH_INTR 0xfffffffeUL
++
++typedef u32_t sys_prot_t;
++
++struct sys_sem;
++typedef struct sys_sem * sys_sem_t;
++#define sys_sem_valid(sem) (*(sem) != NULL)
++#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL; }}while(0)
++
++struct sys_mutex;
++typedef struct sys_mutex * sys_mutex_t;
++#define sys_mutex_valid(mutex) sys_sem_valid(mutex)
++#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
++
++struct sys_mbox;
++typedef struct sys_mbox * sys_mbox_t;
++#define sys_mbox_valid(mbox) sys_sem_valid(mbox)
++#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
++
++struct sys_thread;
++typedef struct sys_thread * sys_thread_t;
++
++#endif /* LWIP_ARCH_SYS_ARCH_H */
++
--- /dev/null
+++ b/port/include/lwipopts.h
@@ -0,0 +1,131 @@
-+/*
-+ Copyright (C) 2017 Free Software Foundation, Inc.
-+ Written by Joan Lledó.
-+
-+ This file is part of the GNU Hurd.
-+
-+ The GNU Hurd is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ The GNU Hurd is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#ifndef HURD_LWIP_LWIPOPTS_H
-+#define HURD_LWIP_LWIPOPTS_H
-+
-+/* An OS is present */
-+#define NO_SYS 0
-+
-+/* Don't rename Sockets API functions */
-+#define LWIP_COMPAT_SOCKETS 0
-+
-+/* Use Glibc malloc()/free() */
-+#define MEM_LIBC_MALLOC 1
-+#define MEMP_MEM_MALLOC 1
-+#define MEM_USE_POOLS 0
-+#define MEM_ALIGNMENT 4
-+
-+/* Only send complete packets to the device */
-+#define LWIP_NETIF_TX_SINGLE_PBUF 1
-+
-+/* Randomize local ports */
-+#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
-+
-+/* Glibc sends more than one packet in a row during an ARP resolution */
-+#define ARP_QUEUEING 1
-+#define ARP_QUEUE_LEN 10
-+
-+/* Netif API is needed to add or remove interfaces on run time */
-+#define LWIP_NETIF_API 1
-+
-+/* IPv4 stuff */
-+#define IP_FORWARD 1
-+
-+/* SLAAC support and other IPv6 stuff */
-+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
-+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
-+#define LWIP_IPV6_AUTOCONFIG 1
-+#define LWIP_IPV6_FORWARD 1
-+#define MEMP_NUM_MLD6_GROUP 16
-+#define LWIP_IPV6_NUM_ADDRESSES 6
-+
-+/* TCP tuning */
-+#define TCP_MSS 1460
-+#define TCP_WND 0xFFFF
-+#define TCP_SND_BUF TCP_WND
-+
-+/* Throughput settings */
-+#define LWIP_CHECKSUM_ON_COPY 1
-+
-+/* Disable stats */
-+#define LWIP_STATS 0
-+#define LWIP_STATS_DISPLAY 0
-+
-+/* Enable all socket operations */
-+#define LWIP_TCP_KEEPALIVE 1
-+#define LWIP_SO_SNDTIMEO 1
-+#define LWIP_SO_RCVTIMEO 1
-+#define LWIP_SO_RCVBUF 1
-+#define LWIP_SO_LINGER 1
-+#define SO_REUSE 1
-+#define LWIP_MULTICAST_TX_OPTIONS 1
-+
-+/* Enable modules */
-+#define LWIP_ARP 1
-+#define LWIP_ETHERNET 1
-+#define LWIP_IPV4 1
-+#define LWIP_ICMP 1
-+#define LWIP_IGMP 1
-+#define LWIP_RAW 1
-+#define LWIP_UDP 1
-+#define LWIP_UDPLITE 1
-+#define LWIP_TCP 1
-+#define LWIP_IPV6 1
-+#define LWIP_ICMP6 1
-+#define LWIP_IPV6_MLD 1
-+#define LWIP_NETIF_LOOPBACK 1
-+
-+/* Debug mode */
-+#ifdef LWIP_DEBUG
-+#define ETHARP_DEBUG LWIP_DBG_OFF
-+#define NETIF_DEBUG LWIP_DBG_OFF
-+#define PBUF_DEBUG LWIP_DBG_OFF
-+#define API_LIB_DEBUG LWIP_DBG_OFF
-+#define API_MSG_DEBUG LWIP_DBG_OFF
-+#define SOCKETS_DEBUG LWIP_DBG_OFF
-+#define ICMP_DEBUG LWIP_DBG_OFF
-+#define IGMP_DEBUG LWIP_DBG_OFF
-+#define INET_DEBUG LWIP_DBG_OFF
-+#define IP_DEBUG LWIP_DBG_OFF
-+#define IP_REASS_DEBUG LWIP_DBG_OFF
-+#define RAW_DEBUG LWIP_DBG_OFF
-+#define MEM_DEBUG LWIP_DBG_OFF
-+#define MEMP_DEBUG LWIP_DBG_OFF
-+#define SYS_DEBUG LWIP_DBG_OFF
-+#define TIMERS_DEBUG LWIP_DBG_OFF
-+#define TCP_DEBUG LWIP_DBG_OFF
-+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
-+#define TCP_FR_DEBUG LWIP_DBG_OFF
-+#define TCP_RTO_DEBUG LWIP_DBG_OFF
-+#define TCP_CWND_DEBUG LWIP_DBG_OFF
-+#define TCP_WND_DEBUG LWIP_DBG_OFF
-+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
-+#define TCP_RST_DEBUG LWIP_DBG_OFF
-+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
-+#define UDP_DEBUG LWIP_DBG_OFF
-+#define TCPIP_DEBUG LWIP_DBG_OFF
-+#define SLIP_DEBUG LWIP_DBG_OFF
-+#define DHCP_DEBUG LWIP_DBG_OFF
-+#define AUTOIP_DEBUG LWIP_DBG_OFF
-+#define DNS_DEBUG LWIP_DBG_OFF
-+#define IP6_DEBUG LWIP_DBG_OFF
-+#endif
-+
-+#endif
++/*
++ Copyright (C) 2017 Free Software Foundation, Inc.
++ Written by Joan Lledó.
++
++ This file is part of the GNU Hurd.
++
++ The GNU Hurd is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public License as
++ published by the Free Software Foundation; either version 2, or (at
++ your option) any later version.
++
++ The GNU Hurd is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
++
++#ifndef HURD_LWIP_LWIPOPTS_H
++#define HURD_LWIP_LWIPOPTS_H
++
++/* An OS is present */
++#define NO_SYS 0
++
++/* Don't rename Sockets API functions */
++#define LWIP_COMPAT_SOCKETS 0
++
++/* Use Glibc malloc()/free() */
++#define MEM_LIBC_MALLOC 1
++#define MEMP_MEM_MALLOC 1
++#define MEM_USE_POOLS 0
++#define MEM_ALIGNMENT 4
++
++/* Only send complete packets to the device */
++#define LWIP_NETIF_TX_SINGLE_PBUF 1
++
++/* Randomize local ports */
++#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
++
++/* Glibc sends more than one packet in a row during an ARP resolution */
++#define ARP_QUEUEING 1
++#define ARP_QUEUE_LEN 10
++
++/* Netif API is needed to add or remove interfaces on run time */
++#define LWIP_NETIF_API 1
++
++/* IPv4 stuff */
++#define IP_FORWARD 1
++
++/* SLAAC support and other IPv6 stuff */
++#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
++#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
++#define LWIP_IPV6_AUTOCONFIG 1
++#define LWIP_IPV6_FORWARD 1
++#define MEMP_NUM_MLD6_GROUP 16
++#define LWIP_IPV6_NUM_ADDRESSES 6
++
++/* TCP tuning */
++#define TCP_MSS 1460
++#define TCP_WND 0xFFFF
++#define TCP_SND_BUF TCP_WND
++
++/* Throughput settings */
++#define LWIP_CHECKSUM_ON_COPY 1
++
++/* Disable stats */
++#define LWIP_STATS 0
++#define LWIP_STATS_DISPLAY 0
++
++/* Enable all socket operations */
++#define LWIP_TCP_KEEPALIVE 1
++#define LWIP_SO_SNDTIMEO 1
++#define LWIP_SO_RCVTIMEO 1
++#define LWIP_SO_RCVBUF 1
++#define LWIP_SO_LINGER 1
++#define SO_REUSE 1
++#define LWIP_MULTICAST_TX_OPTIONS 1
++
++/* Enable modules */
++#define LWIP_ARP 1
++#define LWIP_ETHERNET 1
++#define LWIP_IPV4 1
++#define LWIP_ICMP 1
++#define LWIP_IGMP 1
++#define LWIP_RAW 1
++#define LWIP_UDP 1
++#define LWIP_UDPLITE 1
++#define LWIP_TCP 1
++#define LWIP_IPV6 1
++#define LWIP_ICMP6 1
++#define LWIP_IPV6_MLD 1
++#define LWIP_NETIF_LOOPBACK 1
++
++/* Debug mode */
++#ifdef LWIP_DEBUG
++#define ETHARP_DEBUG LWIP_DBG_OFF
++#define NETIF_DEBUG LWIP_DBG_OFF
++#define PBUF_DEBUG LWIP_DBG_OFF
++#define API_LIB_DEBUG LWIP_DBG_OFF
++#define API_MSG_DEBUG LWIP_DBG_OFF
++#define SOCKETS_DEBUG LWIP_DBG_OFF
++#define ICMP_DEBUG LWIP_DBG_OFF
++#define IGMP_DEBUG LWIP_DBG_OFF
++#define INET_DEBUG LWIP_DBG_OFF
++#define IP_DEBUG LWIP_DBG_OFF
++#define IP_REASS_DEBUG LWIP_DBG_OFF
++#define RAW_DEBUG LWIP_DBG_OFF
++#define MEM_DEBUG LWIP_DBG_OFF
++#define MEMP_DEBUG LWIP_DBG_OFF
++#define SYS_DEBUG LWIP_DBG_OFF
++#define TIMERS_DEBUG LWIP_DBG_OFF
++#define TCP_DEBUG LWIP_DBG_OFF
++#define TCP_INPUT_DEBUG LWIP_DBG_OFF
++#define TCP_FR_DEBUG LWIP_DBG_OFF
++#define TCP_RTO_DEBUG LWIP_DBG_OFF
++#define TCP_CWND_DEBUG LWIP_DBG_OFF
++#define TCP_WND_DEBUG LWIP_DBG_OFF
++#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
++#define TCP_RST_DEBUG LWIP_DBG_OFF
++#define TCP_QLEN_DEBUG LWIP_DBG_OFF
++#define UDP_DEBUG LWIP_DBG_OFF
++#define TCPIP_DEBUG LWIP_DBG_OFF
++#define SLIP_DEBUG LWIP_DBG_OFF
++#define DHCP_DEBUG LWIP_DBG_OFF
++#define AUTOIP_DEBUG LWIP_DBG_OFF
++#define DNS_DEBUG LWIP_DBG_OFF
++#define IP6_DEBUG LWIP_DBG_OFF
++#endif
++
++#endif
--- /dev/null
+++ b/port/sys_arch.c
-+/*
-+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without modification,
-+ *
-+ * 1. Redistributions of source code must retain the above copyright notice,
-+ * this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ *
-+ * This file is part of the lwIP TCP/IP stack.
-+ *
-+ *
-+ */
-+
-+/*
-+ * Wed Apr 17 16:05:29 EDT 2002 (James Roth)
-+ *
-+ * - Fixed an unlikely sys_thread_new() race condition.
-+ *
-+ * - Made current_thread() work with threads which where
-+ * not created with sys_thread_new(). This includes
-+ * the main thread and threads made with pthread_create().
-+ *
-+ * - Catch overflows where more than SYS_MBOX_SIZE messages
-+ * are waiting to be read. The sys_mbox_post() routine
-+ * will block until there is more room instead of just
-+ * leaking messages.
-+ */
-+#include "lwip/debug.h"
-+
-+#include <string.h>
-+#include <sys/time.h>
-+#include <sys/types.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <pthread.h>
-+
-+#include "lwip/def.h"
-+
-+#ifdef LWIP_UNIX_MACH
-+#include <mach/mach.h>
-+#include <mach/mach_time.h>
-+#endif
-+
-+#include "lwip/sys.h"
-+#include "lwip/opt.h"
-+#include "lwip/stats.h"
-+
-+static void
-+get_monotonic_time(struct timespec *ts)
-+{
-+#ifdef LWIP_UNIX_MACH
-+ /* darwin impl (no CLOCK_MONOTONIC) */
-+ uint64_t t = mach_absolute_time();
-+ mach_timebase_info_data_t timebase_info = {0, 0};
-+ mach_timebase_info(&timebase_info);
-+ uint64_t nano = (t * timebase_info.numer) / (timebase_info.denom);
-+ uint64_t sec = nano/1000000000L;
-+ nano -= sec * 1000000000L;
-+ ts->tv_sec = sec;
-+ ts->tv_nsec = nano;
-+#else
-+ clock_gettime(CLOCK_MONOTONIC, ts);
-+#endif
-+}
-+
-+#if !NO_SYS
-+
-+static struct sys_thread *threads = NULL;
-+static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
-+
-+struct sys_mbox_msg {
-+ struct sys_mbox_msg *next;
-+ void *msg;
-+};
-+
-+#define SYS_MBOX_SIZE 128
-+
-+struct sys_mbox {
-+ int first, last;
-+ void *msgs[SYS_MBOX_SIZE];
-+ struct sys_sem *not_empty;
-+ struct sys_sem *not_full;
-+ struct sys_sem *mutex;
-+ int wait_send;
-+};
-+
-+struct sys_sem {
-+ unsigned int c;
-+ pthread_condattr_t condattr;
-+ pthread_cond_t cond;
-+ pthread_mutex_t mutex;
-+};
-+
-+struct sys_mutex {
-+ pthread_mutex_t mutex;
-+};
-+
-+struct sys_thread {
-+ struct sys_thread *next;
-+ pthread_t pthread;
-+};
-+
-+#if SYS_LIGHTWEIGHT_PROT
-+static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
-+static pthread_t lwprot_thread = (pthread_t)0xDEAD;
-+static int lwprot_count = 0;
-+#endif /* SYS_LIGHTWEIGHT_PROT */
-+
-+static struct sys_sem *sys_sem_new_internal(u8_t count);
-+static void sys_sem_free_internal(struct sys_sem *sem);
-+
-+static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
-+ u32_t timeout);
-+
-+static u32_t cond_wait_intr(pthread_cond_t * cond, pthread_mutex_t * mutex,
-+ u32_t timeout);
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* Threads */
-+static struct sys_thread *
-+introduce_thread(pthread_t id)
-+{
-+ struct sys_thread *thread;
-+
-+ thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
-+
-+ if (thread != NULL) {
-+ pthread_mutex_lock(&threads_mutex);
-+ thread->next = threads;
-+ thread->pthread = id;
-+ threads = thread;
-+ pthread_mutex_unlock(&threads_mutex);
-+ }
-+
-+ return thread;
-+}
-+
-+sys_thread_t
-+sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
-+{
-+ int code;
-+ pthread_t tmp;
-+ struct sys_thread *st = NULL;
-+ LWIP_UNUSED_ARG(name);
-+ LWIP_UNUSED_ARG(stacksize);
-+ LWIP_UNUSED_ARG(prio);
-+
-+ code = pthread_create(&tmp,
-+ NULL,
-+ (void *(*)(void *))
-+ function,
-+ arg);
-+
-+ if (0 == code) {
-+ st = introduce_thread(tmp);
-+ }
-+
-+ if (NULL == st) {
-+ LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%lx",
-+ code, (unsigned long)st));
-+ abort();
-+ }
-+ return st;
-+}
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* Mailbox */
-+err_t
-+sys_mbox_new(struct sys_mbox **mb, int size)
-+{
-+ struct sys_mbox *mbox;
-+ LWIP_UNUSED_ARG(size);
-+
-+ mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
-+ if (mbox == NULL) {
-+ return ERR_MEM;
-+ }
-+ mbox->first = mbox->last = 0;
-+ mbox->not_empty = sys_sem_new_internal(0);
-+ mbox->not_full = sys_sem_new_internal(0);
-+ mbox->mutex = sys_sem_new_internal(1);
-+ mbox->wait_send = 0;
-+
-+ SYS_STATS_INC_USED(mbox);
-+ *mb = mbox;
-+ return ERR_OK;
-+}
-+
-+void
-+sys_mbox_free(struct sys_mbox **mb)
-+{
-+ if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
-+ struct sys_mbox *mbox = *mb;
-+ SYS_STATS_DEC(mbox.used);
-+ sys_arch_sem_wait(&mbox->mutex, 0);
-+
-+ sys_sem_free_internal(mbox->not_empty);
-+ sys_sem_free_internal(mbox->not_full);
-+ sys_sem_free_internal(mbox->mutex);
-+ mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
-+ /* LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
-+ free(mbox);
-+ }
-+}
-+
-+err_t
-+sys_mbox_trypost(struct sys_mbox **mb, void *msg)
-+{
-+ u8_t first;
-+ struct sys_mbox *mbox;
-+ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
-+ mbox = *mb;
-+
-+ sys_arch_sem_wait(&mbox->mutex, 0);
-+
-+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
-+ (void *)mbox, (void *)msg));
-+
-+ if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
-+ sys_sem_signal(&mbox->mutex);
-+ return ERR_MEM;
-+ }
-+
-+ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
-+
-+ if (mbox->last == mbox->first) {
-+ first = 1;
-+ } else {
-+ first = 0;
-+ }
-+
-+ mbox->last++;
-+
-+ if (first) {
-+ sys_sem_signal(&mbox->not_empty);
-+ }
-+
-+ sys_sem_signal(&mbox->mutex);
-+
-+ return ERR_OK;
-+}
-+
-+void
-+sys_mbox_post(struct sys_mbox **mb, void *msg)
-+{
-+ u8_t first;
-+ struct sys_mbox *mbox;
-+ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
-+ mbox = *mb;
-+
-+ sys_arch_sem_wait(&mbox->mutex, 0);
-+
-+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, (void *)msg));
-+
-+ while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
-+ mbox->wait_send++;
-+ sys_sem_signal(&mbox->mutex);
-+ sys_arch_sem_wait(&mbox->not_full, 0);
-+ sys_arch_sem_wait(&mbox->mutex, 0);
-+ mbox->wait_send--;
-+ }
-+
-+ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
-+
-+ if (mbox->last == mbox->first) {
-+ first = 1;
-+ } else {
-+ first = 0;
-+ }
-+
-+ mbox->last++;
-+
-+ if (first) {
-+ sys_sem_signal(&mbox->not_empty);
-+ }
-+
-+ sys_sem_signal(&mbox->mutex);
-+}
-+
-+u32_t
-+sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
-+{
-+ struct sys_mbox *mbox;
-+ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
-+ mbox = *mb;
-+
-+ sys_arch_sem_wait(&mbox->mutex, 0);
-+
-+ if (mbox->first == mbox->last) {
-+ sys_sem_signal(&mbox->mutex);
-+ return SYS_MBOX_EMPTY;
-+ }
-+
-+ if (msg != NULL) {
-+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void *)mbox, *msg));
-+ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
-+ }
-+ else{
-+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void *)mbox));
-+ }
-+
-+ mbox->first++;
-+
-+ if (mbox->wait_send) {
-+ sys_sem_signal(&mbox->not_full);
-+ }
-+
-+ sys_sem_signal(&mbox->mutex);
-+
-+ return 0;
-+}
-+
-+u32_t
-+sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
-+{
-+ u32_t time_needed = 0;
-+ struct sys_mbox *mbox;
-+ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
-+ mbox = *mb;
-+
-+ /* The mutex lock is quick so we don't bother with the timeout
-+ stuff here. */
-+ sys_arch_sem_wait(&mbox->mutex, 0);
-+
-+ while (mbox->first == mbox->last) {
-+ sys_sem_signal(&mbox->mutex);
-+
-+ /* We block while waiting for a mail to arrive in the mailbox. We
-+ must be prepared to timeout. */
-+ if (timeout != 0) {
-+ time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
-+
-+ if (time_needed == SYS_ARCH_TIMEOUT) {
-+ return SYS_ARCH_TIMEOUT;
-+ }
-+ } else {
-+ sys_arch_sem_wait(&mbox->not_empty, 0);
-+ }
-+
-+ sys_arch_sem_wait(&mbox->mutex, 0);
-+ }
-+
-+ if (msg != NULL) {
-+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mbox, *msg));
-+ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
-+ }
-+ else{
-+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mbox));
-+ }
-+
-+ mbox->first++;
-+
-+ if (mbox->wait_send) {
-+ sys_sem_signal(&mbox->not_full);
-+ }
-+
-+ sys_sem_signal(&mbox->mutex);
-+
-+ return time_needed;
-+}
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* Semaphore */
-+static struct sys_sem *
-+sys_sem_new_internal(u8_t count)
-+{
-+ struct sys_sem *sem;
-+
-+ sem = (struct sys_sem *)malloc(sizeof(struct sys_sem));
-+ if (sem != NULL) {
-+ sem->c = count;
-+ pthread_condattr_init(&(sem->condattr));
-+#if !(defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21))
-+ pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC);
-+#endif
-+ pthread_cond_init(&(sem->cond), &(sem->condattr));
-+ pthread_mutex_init(&(sem->mutex), NULL);
-+ }
-+ return sem;
-+}
-+
-+err_t
-+sys_sem_new(struct sys_sem **sem, u8_t count)
-+{
-+ SYS_STATS_INC_USED(sem);
-+ *sem = sys_sem_new_internal(count);
-+ if (*sem == NULL) {
-+ return ERR_MEM;
-+ }
-+ return ERR_OK;
-+}
-+
-+static u32_t
-+cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
-+{
-+ struct timespec rtime1, rtime2, ts;
-+ int ret;
-+
-+ if (timeout == 0) {
-+ pthread_cond_wait(cond, mutex);
-+ return 0;
-+ }
-+
-+ /* Get a timestamp and add the timeout value. */
-+ get_monotonic_time(&rtime1);
-+#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21)
-+ ts.tv_sec = timeout / 1000L;
-+ ts.tv_nsec = (timeout % 1000L) * 1000000L;
-+ ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
-+#else
-+ ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
-+ ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
-+ if (ts.tv_nsec >= 1000000000L) {
-+ ts.tv_sec++;
-+ ts.tv_nsec -= 1000000000L;
-+ }
-+
-+ ret = pthread_cond_timedwait(cond, mutex, &ts);
-+#endif
-+ if (ret == ETIMEDOUT) {
-+ return SYS_ARCH_TIMEOUT;
-+ }
-+
-+ /* Calculate for how long we waited for the cond. */
-+ get_monotonic_time(&rtime2);
-+ ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
-+ ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
-+ if (ts.tv_nsec < 0) {
-+ ts.tv_sec--;
-+ ts.tv_nsec += 1000000000L;
-+ }
-+ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
-+}
-+
-+u32_t
-+sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
-+{
-+ u32_t time_needed = 0;
-+ struct sys_sem *sem;
-+ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
-+ sem = *s;
-+
-+ pthread_mutex_lock(&(sem->mutex));
-+ while (sem->c <= 0) {
-+ if (timeout > 0) {
-+ time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
-+
-+ if (time_needed == SYS_ARCH_TIMEOUT) {
-+ pthread_mutex_unlock(&(sem->mutex));
-+ return SYS_ARCH_TIMEOUT;
-+ }
-+ /* pthread_mutex_unlock(&(sem->mutex));
-+ return time_needed; */
-+ } else {
-+ cond_wait(&(sem->cond), &(sem->mutex), 0);
-+ }
-+ }
-+ sem->c--;
-+ pthread_mutex_unlock(&(sem->mutex));
-+ return (u32_t)time_needed;
-+}
-+
-+/*
-+ * Like cond_wait(), but it calls Hurd's non portable
-+ * functions to receive cancellation requests
-+ */
-+static u32_t
-+cond_wait_intr(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
-+{
-+ struct timespec rtime1, rtime2, ts;
-+ int ret;
-+
-+#ifdef __GNU__
-+ #define pthread_cond_wait pthread_hurd_cond_wait_np
-+ #define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
-+#endif
-+
-+ if (timeout == 0) {
-+ ret = pthread_cond_wait(cond, mutex);
-+ return ret;
-+ }
-+
-+ /* Get a timestamp and add the timeout value. */
-+ get_monotonic_time(&rtime1);
-+#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21)
-+ ts.tv_sec = timeout / 1000L;
-+ ts.tv_nsec = (timeout % 1000L) * 1000000L;
-+ ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
-+#else
-+ ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
-+ ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
-+ if (ts.tv_nsec >= 1000000000L) {
-+ ts.tv_sec++;
-+ ts.tv_nsec -= 1000000000L;
-+ }
-+
-+ ret = pthread_cond_timedwait(cond, mutex, &ts);
-+#endif
-+ if (ret == ETIMEDOUT) {
-+ return SYS_ARCH_TIMEOUT;
-+ } else if (ret == EINTR) {
-+ return SYS_ARCH_INTR;
-+ }
-+
-+ /* Calculate for how long we waited for the cond. */
-+ get_monotonic_time(&rtime2);
-+ ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
-+ ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
-+ if (ts.tv_nsec < 0) {
-+ ts.tv_sec--;
-+ ts.tv_nsec += 1000000000L;
-+ }
-+ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
-+}
-+
-+/*
-+ * Like sys_arch_sem_wait(), but it handles thread cancellations.
-+ */
-+u32_t
-+sys_arch_sem_wait_intr(struct sys_sem **s, u32_t timeout)
-+{
-+ u32_t time_needed = 0;
-+ struct sys_sem *sem;
-+ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
-+ sem = *s;
-+
-+ pthread_mutex_lock(&(sem->mutex));
-+ while (sem->c <= 0) {
-+ if (timeout > 0) {
-+ time_needed = cond_wait_intr(&(sem->cond), &(sem->mutex), timeout);
-+
-+ if (time_needed == SYS_ARCH_TIMEOUT) {
-+ pthread_mutex_unlock(&(sem->mutex));
-+ return SYS_ARCH_TIMEOUT;
-+ } else if(time_needed == SYS_ARCH_INTR) {
-+ /* This means we were interrupted, so don't wait again */
-+ sem->c++;
-+
-+ if (sem->c > 1) {
-+ sem->c = 1;
-+ }
-+ }
-+ } else {
-+ if(cond_wait_intr(&(sem->cond), &(sem->mutex), 0)) {
-+ /* This means we were interrupted, so don't wait again */
-+ sem->c++;
-+
-+ if (sem->c > 1) {
-+ sem->c = 1;
-+ }
-+ }
-+ }
-+ }
-+ sem->c--;
-+ pthread_mutex_unlock(&(sem->mutex));
-+ return (u32_t)time_needed;
-+}
-+
-+void
-+sys_sem_signal(struct sys_sem **s)
-+{
-+ struct sys_sem *sem;
-+ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
-+ sem = *s;
-+
-+ pthread_mutex_lock(&(sem->mutex));
-+ sem->c++;
-+
-+ if (sem->c > 1) {
-+ sem->c = 1;
-+ }
-+
-+ pthread_cond_broadcast(&(sem->cond));
-+ pthread_mutex_unlock(&(sem->mutex));
-+}
-+
-+static void
-+sys_sem_free_internal(struct sys_sem *sem)
-+{
-+ pthread_cond_destroy(&(sem->cond));
-+ pthread_condattr_destroy(&(sem->condattr));
-+ pthread_mutex_destroy(&(sem->mutex));
-+ free(sem);
-+}
-+
-+void
-+sys_sem_free(struct sys_sem **sem)
-+{
-+ if ((sem != NULL) && (*sem != SYS_SEM_NULL)) {
-+ SYS_STATS_DEC(sem.used);
-+ sys_sem_free_internal(*sem);
-+ }
-+}
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* Mutex */
-+/** Create a new mutex
-+err_t
-+sys_mutex_new(struct sys_mutex **mutex)
-+{
-+ struct sys_mutex *mtx;
-+
-+ mtx = (struct sys_mutex *)malloc(sizeof(struct sys_mutex));
-+ if (mtx != NULL) {
-+ pthread_mutex_init(&(mtx->mutex), NULL);
-+ *mutex = mtx;
-+ return ERR_OK;
-+ }
-+ else {
-+ return ERR_MEM;
-+ }
-+}
-+
-+/** Lock a mutex
-+void
-+sys_mutex_lock(struct sys_mutex **mutex)
-+{
-+ pthread_mutex_lock(&((*mutex)->mutex));
-+}
-+
-+/** Unlock a mutex
-+void
-+sys_mutex_unlock(struct sys_mutex **mutex)
-+{
-+ pthread_mutex_unlock(&((*mutex)->mutex));
-+}
-+
-+/** Delete a mutex
-+void
-+sys_mutex_free(struct sys_mutex **mutex)
-+{
-+ pthread_mutex_destroy(&((*mutex)->mutex));
-+ free(*mutex);
-+}
-+
-+#endif /* !NO_SYS */
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* Time */
-+u32_t
-+sys_now(void)
-+{
-+ struct timespec ts;
-+
-+ get_monotonic_time(&ts);
-+ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
-+}
-+
-+u32_t
-+sys_jiffies(void)
-+{
-+ struct timespec ts;
-+
-+ get_monotonic_time(&ts);
-+ return (u32_t)(ts.tv_sec * 1000000000L + ts.tv_nsec);
-+}
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* Init */
-+
-+void
-+sys_init(void)
-+{
-+}
-+
-+/*-----------------------------------------------------------------------------------*/
-+/* Critical section */
-+#if SYS_LIGHTWEIGHT_PROT
-+/** sys_prot_t sys_arch_protect(void)
-+
-+This optional function does a "fast" critical region protection and returns
-+the previous protection level. This function is only called during very short
-+critical regions. An embedded system which supports ISR-based drivers might
-+want to implement this function by disabling interrupts. Task-based systems
-+might want to implement this by using a mutex or disabling tasking. This
-+function should support recursive calls from the same task or interrupt. In
-+other words, sys_arch_protect() could be called while already protected. In
-+that case the return value indicates that it is already protected.
-+
-+sys_arch_protect() is only required if your port is supporting an operating
-+system.
-+*/
-+sys_prot_t
-+sys_arch_protect(void)
-+{
-+ /* Note that for the UNIX port, we are using a lightweight mutex, and our
-+ * own counter (which is locked by the mutex). The return code is not actually
-+ * used. */
-+ if (lwprot_thread != pthread_self())
-+ {
-+ /* We are locking the mutex where it has not been locked before *
-+ * or is being locked by another thread */
-+ pthread_mutex_lock(&lwprot_mutex);
-+ lwprot_thread = pthread_self();
-+ lwprot_count = 1;
-+ }
-+ else
-+ /* It is already locked by THIS thread */
-+ lwprot_count++;
-+ return 0;
-+}
-+
-+/** void sys_arch_unprotect(sys_prot_t pval)
-+
-+This optional function does a "fast" set of critical region protection to the
-+value specified by pval. See the documentation for sys_arch_protect() for
-+more information. This function is only required if your port is supporting
-+an operating system.
-+*/
-+void
-+sys_arch_unprotect(sys_prot_t pval)
-+{
-+ LWIP_UNUSED_ARG(pval);
-+ if (lwprot_thread == pthread_self())
-+ {
-+ if (--lwprot_count == 0)
-+ {
-+ lwprot_thread = (pthread_t) 0xDEAD;
-+ pthread_mutex_unlock(&lwprot_mutex);
-+ }
-+ }
-+}
-+#endif /* SYS_LIGHTWEIGHT_PROT */
++/*
++ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without modification,
++ *
++ * 1. Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * 3. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
++ * OF SUCH DAMAGE.
++ *
++ * This file is part of the lwIP TCP/IP stack.
++ *
++ *
++ */
++
++/*
++ * Wed Apr 17 16:05:29 EDT 2002 (James Roth)
++ *
++ * - Fixed an unlikely sys_thread_new() race condition.
++ *
++ * - Made current_thread() work with threads which where
++ * not created with sys_thread_new(). This includes
++ * the main thread and threads made with pthread_create().
++ *
++ * - Catch overflows where more than SYS_MBOX_SIZE messages
++ * are waiting to be read. The sys_mbox_post() routine
++ * will block until there is more room instead of just
++ * leaking messages.
++ */
++#include "lwip/debug.h"
++
++#include <string.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <pthread.h>
++
++#include "lwip/def.h"
++
++#ifdef LWIP_UNIX_MACH
++#include <mach/mach.h>
++#include <mach/mach_time.h>
++#endif
++
++#include "lwip/sys.h"
++#include "lwip/opt.h"
++#include "lwip/stats.h"
++
++static void
++get_monotonic_time(struct timespec *ts)
++{
++#ifdef LWIP_UNIX_MACH
++ /* darwin impl (no CLOCK_MONOTONIC) */
++ uint64_t t = mach_absolute_time();
++ mach_timebase_info_data_t timebase_info = {0, 0};
++ mach_timebase_info(&timebase_info);
++ uint64_t nano = (t * timebase_info.numer) / (timebase_info.denom);
++ uint64_t sec = nano/1000000000L;
++ nano -= sec * 1000000000L;
++ ts->tv_sec = sec;
++ ts->tv_nsec = nano;
++#else
++ clock_gettime(CLOCK_MONOTONIC, ts);
++#endif
++}
++
++#if !NO_SYS
++
++static struct sys_thread *threads = NULL;
++static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
++
++struct sys_mbox_msg {
++ struct sys_mbox_msg *next;
++ void *msg;
++};
++
++#define SYS_MBOX_SIZE 128
++
++struct sys_mbox {
++ int first, last;
++ void *msgs[SYS_MBOX_SIZE];
++ struct sys_sem *not_empty;
++ struct sys_sem *not_full;
++ struct sys_sem *mutex;
++ int wait_send;
++};
++
++struct sys_sem {
++ unsigned int c;
++ pthread_condattr_t condattr;
++ pthread_cond_t cond;
++ pthread_mutex_t mutex;
++};
++
++struct sys_mutex {
++ pthread_mutex_t mutex;
++};
++
++struct sys_thread {
++ struct sys_thread *next;
++ pthread_t pthread;
++};
++
++#if SYS_LIGHTWEIGHT_PROT
++static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
++static pthread_t lwprot_thread = (pthread_t)0xDEAD;
++static int lwprot_count = 0;
++#endif /* SYS_LIGHTWEIGHT_PROT */
++
++static struct sys_sem *sys_sem_new_internal(u8_t count);
++static void sys_sem_free_internal(struct sys_sem *sem);
++
++static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
++ u32_t timeout);
++
++/*-----------------------------------------------------------------------------------*/
++/* Threads */
++static struct sys_thread *
++introduce_thread(pthread_t id)
++{
++ struct sys_thread *thread;
++
++ thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
++
++ if (thread != NULL) {
++ pthread_mutex_lock(&threads_mutex);
++ thread->next = threads;
++ thread->pthread = id;
++ threads = thread;
++ pthread_mutex_unlock(&threads_mutex);
++ }
++
++ return thread;
++}
++
++sys_thread_t
++sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
++{
++ int code;
++ pthread_t tmp;
++ struct sys_thread *st = NULL;
++ LWIP_UNUSED_ARG(name);
++ LWIP_UNUSED_ARG(stacksize);
++ LWIP_UNUSED_ARG(prio);
++
++ code = pthread_create(&tmp,
++ NULL,
++ (void *(*)(void *))
++ function,
++ arg);
++
++ if (0 == code) {
++ st = introduce_thread(tmp);
++ }
++
++ if (NULL == st) {
++ LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%lx",
++ code, (unsigned long)st));
++ abort();
++ }
++ return st;
++}
++
++/*-----------------------------------------------------------------------------------*/
++/* Mailbox */
++err_t
++sys_mbox_new(struct sys_mbox **mb, int size)
++{
++ struct sys_mbox *mbox;
++ LWIP_UNUSED_ARG(size);
++
++ mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
++ if (mbox == NULL) {
++ return ERR_MEM;
++ }
++ mbox->first = mbox->last = 0;
++ mbox->not_empty = sys_sem_new_internal(0);
++ mbox->not_full = sys_sem_new_internal(0);
++ mbox->mutex = sys_sem_new_internal(1);
++ mbox->wait_send = 0;
++
++ SYS_STATS_INC_USED(mbox);
++ *mb = mbox;
++ return ERR_OK;
++}
++
++void
++sys_mbox_free(struct sys_mbox **mb)
++{
++ if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
++ struct sys_mbox *mbox = *mb;
++ SYS_STATS_DEC(mbox.used);
++ sys_arch_sem_wait(&mbox->mutex, 0);
++
++ sys_sem_free_internal(mbox->not_empty);
++ sys_sem_free_internal(mbox->not_full);
++ sys_sem_free_internal(mbox->mutex);
++ mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
++ /* LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
++ free(mbox);
++ }
++}
++
++err_t
++sys_mbox_trypost(struct sys_mbox **mb, void *msg)
++{
++ u8_t first;
++ struct sys_mbox *mbox;
++ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
++ mbox = *mb;
++
++ sys_arch_sem_wait(&mbox->mutex, 0);
++
++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
++ (void *)mbox, (void *)msg));
++
++ if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
++ sys_sem_signal(&mbox->mutex);
++ return ERR_MEM;
++ }
++
++ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
++
++ if (mbox->last == mbox->first) {
++ first = 1;
++ } else {
++ first = 0;
++ }
++
++ mbox->last++;
++
++ if (first) {
++ sys_sem_signal(&mbox->not_empty);
++ }
++
++ sys_sem_signal(&mbox->mutex);
++
++ return ERR_OK;
++}
++
++void
++sys_mbox_post(struct sys_mbox **mb, void *msg)
++{
++ u8_t first;
++ struct sys_mbox *mbox;
++ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
++ mbox = *mb;
++
++ sys_arch_sem_wait(&mbox->mutex, 0);
++
++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, (void *)msg));
++
++ while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
++ mbox->wait_send++;
++ sys_sem_signal(&mbox->mutex);
++ sys_arch_sem_wait(&mbox->not_full, 0);
++ sys_arch_sem_wait(&mbox->mutex, 0);
++ mbox->wait_send--;
++ }
++
++ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
++
++ if (mbox->last == mbox->first) {
++ first = 1;
++ } else {
++ first = 0;
++ }
++
++ mbox->last++;
++
++ if (first) {
++ sys_sem_signal(&mbox->not_empty);
++ }
++
++ sys_sem_signal(&mbox->mutex);
++}
++
++u32_t
++sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
++{
++ struct sys_mbox *mbox;
++ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
++ mbox = *mb;
++
++ sys_arch_sem_wait(&mbox->mutex, 0);
++
++ if (mbox->first == mbox->last) {
++ sys_sem_signal(&mbox->mutex);
++ return SYS_MBOX_EMPTY;
++ }
++
++ if (msg != NULL) {
++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void *)mbox, *msg));
++ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
++ }
++ else{
++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void *)mbox));
++ }
++
++ mbox->first++;
++
++ if (mbox->wait_send) {
++ sys_sem_signal(&mbox->not_full);
++ }
++
++ sys_sem_signal(&mbox->mutex);
++
++ return 0;
++}
++
++u32_t
++sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
++{
++ u32_t time_needed = 0;
++ struct sys_mbox *mbox;
++ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
++ mbox = *mb;
++
++ /* The mutex lock is quick so we don't bother with the timeout
++ stuff here. */
++ sys_arch_sem_wait(&mbox->mutex, 0);
++
++ while (mbox->first == mbox->last) {
++ sys_sem_signal(&mbox->mutex);
++
++ /* We block while waiting for a mail to arrive in the mailbox. We
++ must be prepared to timeout. */
++ if (timeout != 0) {
++ time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
++
++ if (time_needed == SYS_ARCH_TIMEOUT) {
++ return SYS_ARCH_TIMEOUT;
++ }
++ } else {
++ sys_arch_sem_wait(&mbox->not_empty, 0);
++ }
++
++ sys_arch_sem_wait(&mbox->mutex, 0);
++ }
++
++ if (msg != NULL) {
++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mbox, *msg));
++ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
++ }
++ else{
++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mbox));
++ }
++
++ mbox->first++;
++
++ if (mbox->wait_send) {
++ sys_sem_signal(&mbox->not_full);
++ }
++
++ sys_sem_signal(&mbox->mutex);
++
++ return time_needed;
++}
++
++/*-----------------------------------------------------------------------------------*/
++/* Semaphore */
++static struct sys_sem *
++sys_sem_new_internal(u8_t count)
++{
++ struct sys_sem *sem;
++
++ sem = (struct sys_sem *)malloc(sizeof(struct sys_sem));
++ if (sem != NULL) {
++ sem->c = count;
++ pthread_condattr_init(&(sem->condattr));
++#if !(defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21))
++ pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC);
++#endif
++ pthread_cond_init(&(sem->cond), &(sem->condattr));
++ pthread_mutex_init(&(sem->mutex), NULL);
++ }
++ return sem;
++}
++
++err_t
++sys_sem_new(struct sys_sem **sem, u8_t count)
++{
++ SYS_STATS_INC_USED(sem);
++ *sem = sys_sem_new_internal(count);
++ if (*sem == NULL) {
++ return ERR_MEM;
++ }
++ return ERR_OK;
++}
++
++/*
++ * Like cond_wait(), but it calls Hurd's non portable
++ * functions to receive cancellation requests
++ */
++static u32_t
++cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
++{
++ struct timespec rtime1, rtime2, ts;
++ int ret;
++
++#ifdef __GNU__
++ #define pthread_cond_wait pthread_hurd_cond_wait_np
++ #define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
++#endif
++
++ if (timeout == 0) {
++ ret = pthread_cond_wait(cond, mutex);
++ return ret;
++ }
++
++ /* Get a timestamp and add the timeout value. */
++ get_monotonic_time(&rtime1);
++#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21)
++ ts.tv_sec = timeout / 1000L;
++ ts.tv_nsec = (timeout % 1000L) * 1000000L;
++ ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
++#else
++ ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
++ ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
++ if (ts.tv_nsec >= 1000000000L) {
++ ts.tv_sec++;
++ ts.tv_nsec -= 1000000000L;
++ }
++
++ ret = pthread_cond_timedwait(cond, mutex, &ts);
++#endif
++ if (ret == ETIMEDOUT) {
++ return SYS_ARCH_TIMEOUT;
++ } else if (ret == EINTR) {
++ return SYS_ARCH_INTR;
++ }
++
++ /* Calculate for how long we waited for the cond. */
++ get_monotonic_time(&rtime2);
++ ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
++ ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
++ if (ts.tv_nsec < 0) {
++ ts.tv_sec--;
++ ts.tv_nsec += 1000000000L;
++ }
++ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
++}
++
++/*
++ * Like sys_arch_sem_wait(), but it handles thread cancellations.
++ */
++u32_t
++sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
++{
++ u32_t time_needed = 0;
++ struct sys_sem *sem;
++ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
++ sem = *s;
++
++ pthread_mutex_lock(&(sem->mutex));
++ while (sem->c <= 0) {
++ if (timeout > 0) {
++ time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
++
++ if (time_needed == SYS_ARCH_TIMEOUT) {
++ pthread_mutex_unlock(&(sem->mutex));
++ return SYS_ARCH_TIMEOUT;
++ } else if(time_needed == SYS_ARCH_INTR) {
++ /* This means we were interrupted */
++ pthread_mutex_unlock(&(sem->mutex));
++ return SYS_ARCH_INTR;
++ }
++ } else {
++ if(cond_wait(&(sem->cond), &(sem->mutex), 0)) {
++ /* This means we were interrupted */
++ pthread_mutex_unlock(&(sem->mutex));
++ return SYS_ARCH_INTR;
++ }
++ }
++ }
++ sem->c--;
++ pthread_mutex_unlock(&(sem->mutex));
++ return (u32_t)time_needed;
++}
++
++void
++sys_sem_signal(struct sys_sem **s)
++{
++ struct sys_sem *sem;
++ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
++ sem = *s;
++
++ pthread_mutex_lock(&(sem->mutex));
++ sem->c++;
++
++ if (sem->c > 1) {
++ sem->c = 1;
++ }
++
++ pthread_cond_broadcast(&(sem->cond));
++ pthread_mutex_unlock(&(sem->mutex));
++}
++
++static void
++sys_sem_free_internal(struct sys_sem *sem)
++{
++ pthread_cond_destroy(&(sem->cond));
++ pthread_condattr_destroy(&(sem->condattr));
++ pthread_mutex_destroy(&(sem->mutex));
++ free(sem);
++}
++
++void
++sys_sem_free(struct sys_sem **sem)
++{
++ if ((sem != NULL) && (*sem != SYS_SEM_NULL)) {
++ SYS_STATS_DEC(sem.used);
++ sys_sem_free_internal(*sem);
++ }
++}
++
++/*-----------------------------------------------------------------------------------*/
++/* Mutex */
++/** Create a new mutex
++err_t
++sys_mutex_new(struct sys_mutex **mutex)
++{
++ struct sys_mutex *mtx;
++
++ mtx = (struct sys_mutex *)malloc(sizeof(struct sys_mutex));
++ if (mtx != NULL) {
++ pthread_mutex_init(&(mtx->mutex), NULL);
++ *mutex = mtx;
++ return ERR_OK;
++ }
++ else {
++ return ERR_MEM;
++ }
++}
++
++/** Lock a mutex
++void
++sys_mutex_lock(struct sys_mutex **mutex)
++{
++ pthread_mutex_lock(&((*mutex)->mutex));
++}
++
++/** Unlock a mutex
++void
++sys_mutex_unlock(struct sys_mutex **mutex)
++{
++ pthread_mutex_unlock(&((*mutex)->mutex));
++}
++
++/** Delete a mutex
++void
++sys_mutex_free(struct sys_mutex **mutex)
++{
++ pthread_mutex_destroy(&((*mutex)->mutex));
++ free(*mutex);
++}
++
++#endif /* !NO_SYS */
++
++/*-----------------------------------------------------------------------------------*/
++/* Time */
++u32_t
++sys_now(void)
++{
++ struct timespec ts;
++
++ get_monotonic_time(&ts);
++ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
++}
++
++u32_t
++sys_jiffies(void)
++{
++ struct timespec ts;
++
++ get_monotonic_time(&ts);
++ return (u32_t)(ts.tv_sec * 1000000000L + ts.tv_nsec);
++}
++
++/*-----------------------------------------------------------------------------------*/
++/* Init */
++
++void
++sys_init(void)
++{
++}
++
++/*-----------------------------------------------------------------------------------*/
++/* Critical section */
++#if SYS_LIGHTWEIGHT_PROT
++/** sys_prot_t sys_arch_protect(void)
++
++This optional function does a "fast" critical region protection and returns
++the previous protection level. This function is only called during very short
++critical regions. An embedded system which supports ISR-based drivers might
++want to implement this function by disabling interrupts. Task-based systems
++might want to implement this by using a mutex or disabling tasking. This
++function should support recursive calls from the same task or interrupt. In
++other words, sys_arch_protect() could be called while already protected. In
++that case the return value indicates that it is already protected.
++
++sys_arch_protect() is only required if your port is supporting an operating
++system.
++*/
++sys_prot_t
++sys_arch_protect(void)
++{
++ /* Note that for the UNIX port, we are using a lightweight mutex, and our
++ * own counter (which is locked by the mutex). The return code is not actually
++ * used. */
++ if (lwprot_thread != pthread_self())
++ {
++ /* We are locking the mutex where it has not been locked before *
++ * or is being locked by another thread */
++ pthread_mutex_lock(&lwprot_mutex);
++ lwprot_thread = pthread_self();
++ lwprot_count = 1;
++ }
++ else
++ /* It is already locked by THIS thread */
++ lwprot_count++;
++ return 0;
++}
++
++/** void sys_arch_unprotect(sys_prot_t pval)
++
++This optional function does a "fast" set of critical region protection to the
++value specified by pval. See the documentation for sys_arch_protect() for
++more information. This function is only required if your port is supporting
++an operating system.
++*/
++void
++sys_arch_unprotect(sys_prot_t pval)
++{
++ LWIP_UNUSED_ARG(pval);
++ if (lwprot_thread == pthread_self())
++ {
++ if (--lwprot_count == 0)
++ {
++ lwprot_thread = (pthread_t) 0xDEAD;
++ pthread_mutex_unlock(&lwprot_mutex);
++ }
++ }
++}
++#endif /* SYS_LIGHTWEIGHT_PROT */
diff --git a/debian/patches/posix b/debian/patches/posix
index 1818c4d..e92f542 100644
--- a/debian/patches/posix
+++ b/debian/patches/posix
@@ -18,117 +18,117 @@ Won't get to upstream
--- /dev/null
+++ b/port/include/posix/inet.h
@@ -0,0 +1,63 @@
-+/*
-+ Copyright (C) 2018 Free Software Foundation, Inc.
-+ Written by Joan Lledó.
-+
-+ This file is part of the GNU Hurd.
-+
-+ The GNU Hurd is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ The GNU Hurd is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#ifndef HURD_LWIP_POSIX_INET_H
-+#define HURD_LWIP_POSIX_INET_H
-+
-+#include <arpa/inet.h>
-+#include <netinet/in.h>
-+#include <netinet/tcp.h>
-+#include <netinet/udp.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define SIN_ZERO_LEN sizeof (struct sockaddr) - \
-+ __SOCKADDR_COMMON_SIZE - \
-+ sizeof (in_port_t) - \
-+ sizeof (struct in_addr)
-+
-+#if LWIP_IPV4
-+
-+#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
-+#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
-+/* ATTENTION: the next define only works because both s_addr and ip4_addr_t are an u32_t effectively! */
-+#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr) ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
-+
-+#endif /* LWIP_IPV4 */
-+
-+#if LWIP_IPV6
-+#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \
-+ (target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \
-+ (target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \
-+ (target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];}
-+#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \
-+ (target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \
-+ (target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \
-+ (target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3];}
-+/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */
-+#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
-+#endif /* LWIP_IPV6 */
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* HURD_LWIP_POSIX_INET_H */
++/*
++ Copyright (C) 2018 Free Software Foundation, Inc.
++ Written by Joan Lledó.
++
++ This file is part of the GNU Hurd.
++
++ The GNU Hurd is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public License as
++ published by the Free Software Foundation; either version 2, or (at
++ your option) any later version.
++
++ The GNU Hurd is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
++
++#ifndef HURD_LWIP_POSIX_INET_H
++#define HURD_LWIP_POSIX_INET_H
++
++#include <arpa/inet.h>
++#include <netinet/in.h>
++#include <netinet/tcp.h>
++#include <netinet/udp.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#define SIN_ZERO_LEN sizeof (struct sockaddr) - \
++ __SOCKADDR_COMMON_SIZE - \
++ sizeof (in_port_t) - \
++ sizeof (struct in_addr)
++
++#if LWIP_IPV4
++
++#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
++#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
++/* ATTENTION: the next define only works because both s_addr and ip4_addr_t are an u32_t effectively! */
++#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr) ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
++
++#endif /* LWIP_IPV4 */
++
++#if LWIP_IPV6
++#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \
++ (target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \
++ (target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \
++ (target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];}
++#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \
++ (target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \
++ (target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \
++ (target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3];}
++/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */
++#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
++#endif /* LWIP_IPV6 */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* HURD_LWIP_POSIX_INET_H */
--- /dev/null
+++ b/port/include/posix/socket.h
@@ -0,0 +1,45 @@
-+/*
-+ Copyright (C) 2018 Free Software Foundation, Inc.
-+ Written by Joan Lledó.
-+
-+ This file is part of the GNU Hurd.
-+
-+ The GNU Hurd is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ The GNU Hurd is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
-+
-+#ifndef HURD_LWIP_POSIX_SOCKET_H
-+#define HURD_LWIP_POSIX_SOCKET_H
-+
-+#include <sys/socket.h>
-+#include <poll.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* Unsuported indetifiers */
-+#ifndef SO_NO_CHECK
-+#define SO_NO_CHECK 0x0
-+#endif
-+#ifndef MSG_MORE
-+#define MSG_MORE 0x0
-+#endif
-+#ifndef TCP_KEEPALIVE
-+#define TCP_KEEPALIVE 0x0
-+#endif
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* HURD_LWIP_POSIX_SOCKET_H */
++/*
++ Copyright (C) 2018 Free Software Foundation, Inc.
++ Written by Joan Lledó.
++
++ This file is part of the GNU Hurd.
++
++ The GNU Hurd is free software; you can redistribute it and/or
++ modify it under the terms of the GNU General Public License as
++ published by the Free Software Foundation; either version 2, or (at
++ your option) any later version.
++
++ The GNU Hurd is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
++
++#ifndef HURD_LWIP_POSIX_SOCKET_H
++#define HURD_LWIP_POSIX_SOCKET_H
++
++#include <sys/socket.h>
++#include <poll.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* Unsuported indetifiers */
++#ifndef SO_NO_CHECK
++#define SO_NO_CHECK 0x0
++#endif
++#ifndef MSG_MORE
++#define MSG_MORE 0x0
++#endif
++#ifndef TCP_KEEPALIVE
++#define TCP_KEEPALIVE 0x0
++#endif
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* HURD_LWIP_POSIX_SOCKET_H */
--- a/src/include/lwip/inet.h
+++ b/src/include/lwip/inet.h
@@ -41,132 +41,11 @@
@@ -270,7 +270,7 @@ Won't get to upstream
#endif /* LWIP_HDR_INET_H */
--- a/src/include/lwip/ip.h
+++ b/src/include/lwip/ip.h
/*
* Option flags per-socket. These are the same like SO_XXX in sockets.h
*/
@@ -290,742 +290,742 @@ Won't get to upstream
--- /dev/null
+++ b/src/include/lwip/lwip_inet.h
@@ -0,0 +1,164 @@
-+/*
-+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without modification,
-+ *
-+ * 1. Redistributions of source code must retain the above copyright notice,
-+ * this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ *
-+ * This file is part of the lwIP TCP/IP stack.
-+ *
-+ *
-+ */
-+#ifndef LWIP_HDR_PRIV_INET_H
-+#define LWIP_HDR_PRIV_INET_H
-+
-+#include "lwip/opt.h"
-+#include "lwip/def.h"
-+#include "lwip/ip_addr.h"
-+#include "lwip/ip6_addr.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
-+ to prevent this code from redefining it. */
-+#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
-+typedef u32_t in_addr_t;
-+#endif
-+
-+struct in_addr {
-+ in_addr_t s_addr;
-+};
-+
-+struct in6_addr {
-+ union {
-+ u32_t u32_addr[4];
-+ u8_t u8_addr[16];
-+ } un;
-+#define s6_addr un.u8_addr
-+};
-+
-+/** 255.255.255.255 */
-+#define INADDR_NONE IPADDR_NONE
-+/** 127.0.0.1 */
-+#define INADDR_LOOPBACK IPADDR_LOOPBACK
-+/** 0.0.0.0 */
-+#define INADDR_ANY IPADDR_ANY
-+/** 255.255.255.255 */
-+#define INADDR_BROADCAST IPADDR_BROADCAST
-+
-+/** This macro can be used to initialize a variable of type struct in6_addr
-+ to the IPv6 wildcard address. */
-+#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
-+/** This macro can be used to initialize a variable of type struct in6_addr
-+ to the IPv6 loopback address. */
-+#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
-+/** This variable is initialized by the system to contain the wildcard IPv6 address. */
-+extern const struct in6_addr in6addr_any;
-+
-+/* Definitions of the bits in an (IPv4) Internet address integer.
-+
-+ On subnets, host and network parts are found according to
-+ the subnet mask, not these masks. */
-+#define IN_CLASSA(a) IP_CLASSA(a)
-+#define IN_CLASSA_NET IP_CLASSA_NET
-+#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT
-+#define IN_CLASSA_HOST IP_CLASSA_HOST
-+#define IN_CLASSA_MAX IP_CLASSA_MAX
-+
-+#define IN_CLASSB(b) IP_CLASSB(b)
-+#define IN_CLASSB_NET IP_CLASSB_NET
-+#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT
-+#define IN_CLASSB_HOST IP_CLASSB_HOST
-+#define IN_CLASSB_MAX IP_CLASSB_MAX
-+
-+#define IN_CLASSC(c) IP_CLASSC(c)
-+#define IN_CLASSC_NET IP_CLASSC_NET
-+#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT
-+#define IN_CLASSC_HOST IP_CLASSC_HOST
-+#define IN_CLASSC_MAX IP_CLASSC_MAX
-+
-+#define IN_CLASSD(d) IP_CLASSD(d)
-+#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */
-+#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */
-+#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */
-+#define IN_CLASSD_MAX IP_CLASSD_MAX
-+
-+#define IN_MULTICAST(a) IP_MULTICAST(a)
-+
-+#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a)
-+#define IN_BADCLASS(a) IP_BADCLASS(a)
-+
-+#define IN_LOOPBACKNET IP_LOOPBACKNET
-+
-+
-+#ifndef INET_ADDRSTRLEN
-+#define INET_ADDRSTRLEN IP4ADDR_STRLEN_MAX
-+#endif
-+#if LWIP_IPV6
-+#ifndef INET6_ADDRSTRLEN
-+#define INET6_ADDRSTRLEN IP6ADDR_STRLEN_MAX
-+#endif
-+#endif
-+
-+#if LWIP_IPV4
-+
-+#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
-+#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
-+/* ATTENTION: the next define only works because both s_addr and ip4_addr_t are an u32_t effectively! */
-+#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr) ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
-+
-+/* directly map this to the lwip internal functions */
-+#define inet_addr(cp) ipaddr_addr(cp)
-+#define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)
-+#define inet_ntoa(addr) ip4addr_ntoa((const ip4_addr_t*)&(addr))
-+#define inet_ntoa_r(addr, buf, buflen) ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
-+
-+#endif /* LWIP_IPV4 */
-+
-+#if LWIP_IPV6
-+#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \
-+ (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \
-+ (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \
-+ (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];}
-+#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
-+ (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
-+ (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
-+ (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];}
-+/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */
-+#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
-+
-+/* directly map this to the lwip internal functions */
-+#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr)
-+#define inet6_ntoa(addr) ip6addr_ntoa((const ip6_addr_t*)&(addr))
-+#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const ip6_addr_t*)&(addr), buf, buflen)
-+
-+#endif /* LWIP_IPV6 */
-+
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* LWIP_HDR_PRIV_INET_H */
++/*
++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without modification,
++ *
++ * 1. Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * 3. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
++ * OF SUCH DAMAGE.
++ *
++ * This file is part of the lwIP TCP/IP stack.
++ *
++ *
++ */
++#ifndef LWIP_HDR_PRIV_INET_H
++#define LWIP_HDR_PRIV_INET_H
++
++#include "lwip/opt.h"
++#include "lwip/def.h"
++#include "lwip/ip_addr.h"
++#include "lwip/ip6_addr.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
++ to prevent this code from redefining it. */
++#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
++typedef u32_t in_addr_t;
++#endif
++
++struct in_addr {
++ in_addr_t s_addr;
++};
++
++struct in6_addr {
++ union {
++ u32_t u32_addr[4];
++ u8_t u8_addr[16];
++ } un;
++#define s6_addr un.u8_addr
++};
++
++/** 255.255.255.255 */
++#define INADDR_NONE IPADDR_NONE
++/** 127.0.0.1 */
++#define INADDR_LOOPBACK IPADDR_LOOPBACK
++/** 0.0.0.0 */
++#define INADDR_ANY IPADDR_ANY
++/** 255.255.255.255 */
++#define INADDR_BROADCAST IPADDR_BROADCAST
++
++/** This macro can be used to initialize a variable of type struct in6_addr
++ to the IPv6 wildcard address. */
++#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
++/** This macro can be used to initialize a variable of type struct in6_addr
++ to the IPv6 loopback address. */
++#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
++/** This variable is initialized by the system to contain the wildcard IPv6 address. */
++extern const struct in6_addr in6addr_any;
++
++/* Definitions of the bits in an (IPv4) Internet address integer.
++
++ On subnets, host and network parts are found according to
++ the subnet mask, not these masks. */
++#define IN_CLASSA(a) IP_CLASSA(a)
++#define IN_CLASSA_NET IP_CLASSA_NET
++#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT
++#define IN_CLASSA_HOST IP_CLASSA_HOST
++#define IN_CLASSA_MAX IP_CLASSA_MAX
++
++#define IN_CLASSB(b) IP_CLASSB(b)
++#define IN_CLASSB_NET IP_CLASSB_NET
++#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT
++#define IN_CLASSB_HOST IP_CLASSB_HOST
++#define IN_CLASSB_MAX IP_CLASSB_MAX
++
++#define IN_CLASSC(c) IP_CLASSC(c)
++#define IN_CLASSC_NET IP_CLASSC_NET
++#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT
++#define IN_CLASSC_HOST IP_CLASSC_HOST
++#define IN_CLASSC_MAX IP_CLASSC_MAX
++
++#define IN_CLASSD(d) IP_CLASSD(d)
++#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */
++#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */
++#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */
++#define IN_CLASSD_MAX IP_CLASSD_MAX
++
++#define IN_MULTICAST(a) IP_MULTICAST(a)
++
++#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a)
++#define IN_BADCLASS(a) IP_BADCLASS(a)
++
++#define IN_LOOPBACKNET IP_LOOPBACKNET
++
++
++#ifndef INET_ADDRSTRLEN
++#define INET_ADDRSTRLEN IP4ADDR_STRLEN_MAX
++#endif
++#if LWIP_IPV6
++#ifndef INET6_ADDRSTRLEN
++#define INET6_ADDRSTRLEN IP6ADDR_STRLEN_MAX
++#endif
++#endif
++
++#if LWIP_IPV4
++
++#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
++#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
++/* ATTENTION: the next define only works because both s_addr and ip4_addr_t are an u32_t effectively! */
++#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr) ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
++
++/* directly map this to the lwip internal functions */
++#define inet_addr(cp) ipaddr_addr(cp)
++#define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)
++#define inet_ntoa(addr) ip4addr_ntoa((const ip4_addr_t*)&(addr))
++#define inet_ntoa_r(addr, buf, buflen) ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
++
++#endif /* LWIP_IPV4 */
++
++#if LWIP_IPV6
++#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \
++ (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \
++ (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \
++ (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];}
++#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
++ (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
++ (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
++ (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];}
++/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */
++#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
++
++/* directly map this to the lwip internal functions */
++#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr)
++#define inet6_ntoa(addr) ip6addr_ntoa((const ip6_addr_t*)&(addr))
++#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const ip6_addr_t*)&(addr), buf, buflen)
++
++#endif /* LWIP_IPV6 */
++
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* LWIP_HDR_PRIV_INET_H */
--- /dev/null
+++ b/src/include/lwip/lwip_sockets.h
@@ -0,0 +1,569 @@
-+/**
-+ * Socket API (to be used from non-TCPIP threads)
-+ */
-+
-+/*
-+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without modification,
-+ *
-+ * 1. Redistributions of source code must retain the above copyright notice,
-+ * this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ * 3. The name of the author may not be used to endorse or promote products
-+ * derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ *
-+ * This file is part of the lwIP TCP/IP stack.
-+ *
-+ *
-+ */
-+
-+
-+#ifndef LWIP_HDR_PRIV_SOCKETS_H
-+#define LWIP_HDR_PRIV_SOCKETS_H
-+
-+#include "lwip/opt.h"
-+
-+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
-+
-+#include "lwip/ip_addr.h"
-+#include "lwip/err.h"
-+#include "lwip/inet.h"
-+#include "lwip/errno.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define _HAVE_SA_LEN 1
-+
-+/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
-+ to prevent this code from redefining it. */
-+#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
-+typedef u8_t sa_family_t;
-+#endif
-+/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
-+ to prevent this code from redefining it. */
-+#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
-+typedef u16_t in_port_t;
-+#endif
-+
-+#if LWIP_IPV4
-+/* members are in network byte order */
-+struct sockaddr_in {
-+ u8_t sin_len;
-+ sa_family_t sin_family;
-+ in_port_t sin_port;
-+ struct in_addr sin_addr;
-+#define SIN_ZERO_LEN 8
-+ char sin_zero[SIN_ZERO_LEN];
-+};
-+#endif /* LWIP_IPV4 */
-+
-+#if LWIP_IPV6
-+struct sockaddr_in6 {
-+ u8_t sin6_len; /* length of this structure */
-+ sa_family_t sin6_family; /* AF_INET6 */
-+ in_port_t sin6_port; /* Transport layer port # */
-+ u32_t sin6_flowinfo; /* IPv6 flow information */
-+ struct in6_addr sin6_addr; /* IPv6 address */
-+ u32_t sin6_scope_id; /* Set of interfaces for scope */
-+};
-+#endif /* LWIP_IPV6 */
-+
-+struct sockaddr {
-+ u8_t sa_len;
-+ sa_family_t sa_family;
-+ char sa_data[14];
-+};
-+
-+struct sockaddr_storage {
-+ u8_t s2_len;
-+ sa_family_t ss_family;
-+ char s2_data1[2];
-+ u32_t s2_data2[3];
-+#if LWIP_IPV6
-+ u32_t s2_data3[3];
-+#endif /* LWIP_IPV6 */
-+};
-+
-+/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
-+ to prevent this code from redefining it. */
-+#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
-+typedef u32_t socklen_t;
-+#endif
-+
-+struct lwip_sock;
-+
-+#if !LWIP_TCPIP_CORE_LOCKING
-+/** Maximum optlen used by setsockopt/getsockopt */
-+#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16
-+
-+/** This struct is used to pass data to the set/getsockopt_internal
-+ * functions running in tcpip_thread context (only a void* is allowed) */
-+struct lwip_setgetsockopt_data {
-+ /** socket index for which to change options */
-+ int s;
-+ /** level of the option to process */
-+ int level;
-+ /** name of the option to process */
-+ int optname;
-+ /** set: value to set the option to
-+ * get: value of the option is stored here */
-+#if LWIP_MPU_COMPATIBLE
-+ u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN];
-+#else
-+ union {
-+ void *p;
-+ const void *pc;
-+ } optval;
-+#endif
-+ /** size of *optval */
-+ socklen_t optlen;
-+ /** if an error occurs, it is temporarily stored here */
-+ err_t err;
-+ /** semaphore to wake up the calling task */
-+ void* completed_sem;
-+};
-+#endif /* !LWIP_TCPIP_CORE_LOCKING */
-+
-+#if !defined(iovec)
-+struct iovec {
-+ void *iov_base;
-+ size_t iov_len;
-+};
-+#endif
-+
-+struct msghdr {
-+ void *msg_name;
-+ socklen_t msg_namelen;
-+ struct iovec *msg_iov;
-+ int msg_iovlen;
-+ void *msg_control;
-+ socklen_t msg_controllen;
-+ int msg_flags;
-+};
-+
-+/* Socket protocol types (TCP/UDP/RAW) */
-+#define SOCK_STREAM 1
-+#define SOCK_DGRAM 2
-+#define SOCK_RAW 3
-+
-+/*
-+ * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
-+ */
-+#define SO_REUSEADDR 0x0004 /* Allow local address reuse */
-+#define SO_KEEPALIVE 0x0008 /* keep connections alive */
-+#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
-+
-+
-+/*
-+ * Additional options, not kept in so_options.
-+ */
-+#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */
-+#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
-+#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */
-+#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
-+#define SO_LINGER 0x0080 /* linger on close if data present */
-+#define SO_DONTLINGER ((int)(~SO_LINGER))
-+#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */
-+#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */
-+#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
-+#define SO_RCVBUF 0x1002 /* receive buffer size */
-+#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
-+#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */
-+#define SO_SNDTIMEO 0x1005 /* send timeout */
-+#define SO_RCVTIMEO 0x1006 /* receive timeout */
-+#define SO_ERROR 0x1007 /* get error status and clear */
-+#define SO_TYPE 0x1008 /* get socket type */
-+#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
-+#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
-+
-+
-+/*
-+ * Structure used for manipulating linger option.
-+ */
-+struct linger {
-+ int l_onoff; /* option on/off */
-+ int l_linger; /* linger time in seconds */
-+};
-+
-+/*
-+ * Level number for (get/set)sockopt() to apply to socket itself.
-+ */
-+#define SOL_SOCKET 0xfff /* options for socket level */
-+
-+
-+#define AF_UNSPEC 0
-+#define AF_INET 2
-+#if LWIP_IPV6
-+#define AF_INET6 10
-+#else /* LWIP_IPV6 */
-+#define AF_INET6 AF_UNSPEC
-+#endif /* LWIP_IPV6 */
-+#define PF_INET AF_INET
-+#define PF_INET6 AF_INET6
-+#define PF_UNSPEC AF_UNSPEC
-+
-+#define IPPROTO_IP 0
-+#define IPPROTO_ICMP 1
-+#define IPPROTO_TCP 6
-+#define IPPROTO_UDP 17
-+#if LWIP_IPV6
-+#define IPPROTO_IPV6 41
-+#define IPPROTO_ICMPV6 58
-+#endif /* LWIP_IPV6 */
-+#define IPPROTO_UDPLITE 136
-+#define IPPROTO_RAW 255
-+
-+/* Flags we can use with send and recv. */
-+#define MSG_PEEK 0x01 /* Peeks at an incoming message */
-+#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
-+#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
-+#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
-+#define MSG_MORE 0x10 /* Sender will send more */
-+
-+
-+/*
-+ * Options for level IPPROTO_IP
-+ */
-+#define IP_TOS 1
-+#define IP_TTL 2
-+
-+#if LWIP_TCP
-+/*
-+ * Options for level IPPROTO_TCP
-+ */
-+#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
-+#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
-+#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
-+#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */
-+#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_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */
-+#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
-+ */
-+#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
-+#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
-+#endif /* LWIP_UDP && LWIP_UDPLITE*/
-+
-+
-+#if LWIP_MULTICAST_TX_OPTIONS
-+/*
-+ * Options and types for UDP multicast traffic handling
-+ */
-+#define IP_MULTICAST_TTL 5
-+#define IP_MULTICAST_IF 6
-+#define IP_MULTICAST_LOOP 7
-+#endif /* LWIP_MULTICAST_TX_OPTIONS */
-+
-+#if LWIP_IGMP
-+/*
-+ * Options and types related to multicast membership
-+ */
-+#define IP_ADD_MEMBERSHIP 3
-+#define IP_DROP_MEMBERSHIP 4
-+
-+typedef struct ip_mreq {
-+ struct in_addr imr_multiaddr; /* IP multicast address of group */
-+ struct in_addr imr_interface; /* local IP address of interface */
-+} ip_mreq;
-+#endif /* LWIP_IGMP */
-+
-+/*
-+ * The Type of Service provides an indication of the abstract
-+ * parameters of the quality of service desired. These parameters are
-+ * to be used to guide the selection of the actual service parameters
-+ * when transmitting a datagram through a particular network. Several
-+ * networks offer service precedence, which somehow treats high
-+ * precedence traffic as more important than other traffic (generally
-+ * by accepting only traffic above a certain precedence at time of high
-+ * load). The major choice is a three way tradeoff between low-delay,
-+ * high-reliability, and high-throughput.
-+ * The use of the Delay, Throughput, and Reliability indications may
-+ * increase the cost (in some sense) of the service. In many networks
-+ * better performance for one of these parameters is coupled with worse
-+ * performance on another. Except for very unusual cases at most two
-+ * of these three indications should be set.
-+ */
-+#define IPTOS_TOS_MASK 0x1E
-+#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
-+#define IPTOS_LOWDELAY 0x10
-+#define IPTOS_THROUGHPUT 0x08
-+#define IPTOS_RELIABILITY 0x04
-+#define IPTOS_LOWCOST 0x02
-+#define IPTOS_MINCOST IPTOS_LOWCOST
-+
-+/*
-+ * The Network Control precedence designation is intended to be used
-+ * within a network only. The actual use and control of that
-+ * designation is up to each network. The Internetwork Control
-+ * designation is intended for use by gateway control originators only.
-+ * If the actual use of these precedence designations is of concern to
-+ * a particular network, it is the responsibility of that network to
-+ * control the access to, and use of, those precedence designations.
-+ */
-+#define IPTOS_PREC_MASK 0xe0
-+#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
-+#define IPTOS_PREC_NETCONTROL 0xe0
-+#define IPTOS_PREC_INTERNETCONTROL 0xc0
-+#define IPTOS_PREC_CRITIC_ECP 0xa0
-+#define IPTOS_PREC_FLASHOVERRIDE 0x80
-+#define IPTOS_PREC_FLASH 0x60
-+#define IPTOS_PREC_IMMEDIATE 0x40
-+#define IPTOS_PREC_PRIORITY 0x20
-+#define IPTOS_PREC_ROUTINE 0x00
-+
-+
-+/*
-+ * Commands for ioctlsocket(), taken from the BSD file fcntl.h.
-+ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
-+ *
-+ * Ioctl's have the command encoded in the lower word,
-+ * and the size of any in or out parameters in the upper
-+ * word. The high 2 bits of the upper word are used
-+ * to encode the in/out status of the parameter; for now
-+ * we restrict parameters to at most 128 bytes.
-+ */
-+#if !defined(FIONREAD) || !defined(FIONBIO)
-+#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */
-+#define IOC_VOID 0x20000000UL /* no parameters */
-+#define IOC_OUT 0x40000000UL /* copy out parameters */
-+#define IOC_IN 0x80000000UL /* copy in parameters */
-+#define IOC_INOUT (IOC_IN|IOC_OUT)
-+ /* 0x20000000 distinguishes new &
-+ old ioctl's */
-+#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
-+
-+#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
-+
-+#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
-+#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
-+
-+#ifndef FIONREAD
-+#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
-+#endif
-+#ifndef FIONBIO
-+#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
-+#endif
-+
-+/* Socket I/O Controls: unimplemented */
-+#ifndef SIOCSHIWAT
-+#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */
-+#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */
-+#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */
-+#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */
-+#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */
-+#endif
-+
-+/* commands for fnctl */
-+#ifndef F_GETFL
-+#define F_GETFL 3
-+#endif
-+#ifndef F_SETFL
-+#define F_SETFL 4
-+#endif
-+
-+/* File status flags and file access modes for fnctl,
-+ these are bits in an int. */
-+#ifndef O_NONBLOCK
-+#define O_NONBLOCK 1 /* nonblocking I/O */
-+#endif
-+#ifndef O_NDELAY
-+#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */
-+#endif
-+
-+#ifndef SHUT_RD
-+ #define SHUT_RD 0
-+ #define SHUT_WR 1
-+ #define SHUT_RDWR 2
-+#endif
-+
-+/* FD_SET used for lwip_select */
-+#ifndef FD_SET
-+#undef FD_SETSIZE
-+/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
-+#define FD_SETSIZE MEMP_NUM_NETCONN
-+#define FDSETSAFESET(n, code) do { \
-+ if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \
-+ code; }} while(0)
-+#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
-+ (code) : 0)
-+#define FD_SET(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |= (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
-+#define FD_CLR(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
-+#define FD_ISSET(n,p) FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
-+#define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
-+
-+typedef struct fd_set
-+{
-+ unsigned char fd_bits [(FD_SETSIZE+7)/8];
-+} fd_set;
-+
-+#elif LWIP_SOCKET_OFFSET
-+#error LWIP_SOCKET_OFFSET does not work with external FD_SET!
-+#elif FD_SETSIZE < MEMP_NUM_NETCONN
-+#error "external FD_SETSIZE too small for number of sockets"
-+#endif /* FD_SET */
-+
-+/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
-+ * by your system, set this to 0 and include <sys/time.h> in cc.h */
-+#ifndef LWIP_TIMEVAL_PRIVATE
-+#define LWIP_TIMEVAL_PRIVATE 1
-+#endif
-+
-+#if LWIP_TIMEVAL_PRIVATE
-+struct timeval {
-+ long tv_sec; /* seconds */
-+ long tv_usec; /* and microseconds */
-+};
-+#endif /* LWIP_TIMEVAL_PRIVATE */
-+
-+#define lwip_socket_init() /* Compatibility define, no init needed. */
-+void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */
-+void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */
-+
-+#if LWIP_COMPAT_SOCKETS == 2
-+/* This helps code parsers/code completion by not having the COMPAT functions as defines */
-+#define lwip_accept accept
-+#define lwip_bind bind
-+#define lwip_shutdown shutdown
-+#define lwip_getpeername getpeername
-+#define lwip_getsockname getsockname
-+#define lwip_setsockopt setsockopt
-+#define lwip_getsockopt getsockopt
-+#define lwip_close closesocket
-+#define lwip_connect connect
-+#define lwip_listen listen
-+#define lwip_recv recv
-+#define lwip_recvfrom recvfrom
-+#define lwip_send send
-+#define lwip_sendmsg sendmsg
-+#define lwip_sendto sendto
-+#define lwip_socket socket
-+#define lwip_select select
-+#define lwip_ioctlsocket ioctl
-+
-+#if LWIP_POSIX_SOCKETS_IO_NAMES
-+#define lwip_read read
-+#define lwip_write write
-+#define lwip_writev writev
-+#undef lwip_close
-+#define lwip_close close
-+#define closesocket(s) close(s)
-+#define lwip_fcntl fcntl
-+#define lwip_ioctl ioctl
-+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
-+#endif /* LWIP_COMPAT_SOCKETS == 2 */
-+
-+#if LWIP_COMPAT_SOCKETS
-+#if LWIP_COMPAT_SOCKETS != 2
-+#define accept(s,addr,addrlen) lwip_accept(s,addr,addrlen)
-+#define bind(s,name,namelen) lwip_bind(s,name,namelen)
-+#define shutdown(s,how) lwip_shutdown(s,how)
-+#define getpeername(s,name,namelen) lwip_getpeername(s,name,namelen)
-+#define getsockname(s,name,namelen) lwip_getsockname(s,name,namelen)
-+#define setsockopt(s,level,optname,opval,optlen) lwip_setsockopt(s,level,optname,opval,optlen)
-+#define getsockopt(s,level,optname,opval,optlen) lwip_getsockopt(s,level,optname,opval,optlen)
-+#define closesocket(s) lwip_close(s)
-+#define connect(s,name,namelen) lwip_connect(s,name,namelen)
-+#define listen(s,backlog) lwip_listen(s,backlog)
-+#define recv(s,mem,len,flags) lwip_recv(s,mem,len,flags)
-+#define recvfrom(s,mem,len,flags,from,fromlen) lwip_recvfrom(s,mem,len,flags,from,fromlen)
-+#define send(s,dataptr,size,flags) lwip_send(s,dataptr,size,flags)
-+#define sendmsg(s,message,flags) lwip_sendmsg(s,message,flags)
-+#define sendto(s,dataptr,size,flags,to,tolen) lwip_sendto(s,dataptr,size,flags,to,tolen)
-+#define socket(domain,type,protocol) lwip_socket(domain,type,protocol)
-+#define select(maxfdp1,readset,writeset,exceptset,timeout) lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
-+#define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp)
-+
-+#if LWIP_POSIX_SOCKETS_IO_NAMES
-+#define read(s,mem,len) lwip_read(s,mem,len)
-+#define write(s,dataptr,len) lwip_write(s,dataptr,len)
-+#define writev(s,iov,iovcnt) lwip_writev(s,iov,iovcnt)
-+#define close(s) lwip_close(s)
-+#define fcntl(s,cmd,val) lwip_fcntl(s,cmd,val)
-+#define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp)
-+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
-+#endif /* LWIP_COMPAT_SOCKETS != 2 */
-+
-+#if LWIP_IPV4 && LWIP_IPV6
-+#define inet_ntop(af,src,dst,size) \
-+ (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) \
-+ : (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL))
-+#define inet_pton(af,src,dst) \
-+ (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
-+ : (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
-+#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
-+#define inet_ntop(af,src,dst,size) \
-+ (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL)
-+#define inet_pton(af,src,dst) \
-+ (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
-+#else /* LWIP_IPV4 && LWIP_IPV6 */
-+#define inet_ntop(af,src,dst,size) \
-+ (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) : NULL)
-+#define inet_pton(af,src,dst) \
-+ (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0)
-+#endif /* LWIP_IPV4 && LWIP_IPV6 */
-+
-+#endif /* LWIP_COMPAT_SOCKETS */
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* LWIP_SOCKET */
-+
-+#endif /* LWIP_HDR_PRIV_SOCKETS_H */
++/**
++ * Socket API (to be used from non-TCPIP threads)
++ */
++
++/*
++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without modification,
++ *
++ * 1. Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * 3. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
++ * OF SUCH DAMAGE.
++ *
++ * This file is part of the lwIP TCP/IP stack.
++ *
++ *
++ */
++
++
++#ifndef LWIP_HDR_PRIV_SOCKETS_H
++#define LWIP_HDR_PRIV_SOCKETS_H
++
++#include "lwip/opt.h"
++
++#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
++
++#include "lwip/ip_addr.h"
++#include "lwip/err.h"
++#include "lwip/inet.h"
++#include "lwip/errno.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#define _HAVE_SA_LEN 1
++
++/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
++ to prevent this code from redefining it. */
++#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
++typedef u8_t sa_family_t;
++#endif
++/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
++ to prevent this code from redefining it. */
++#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
++typedef u16_t in_port_t;
++#endif
++
++#if LWIP_IPV4
++/* members are in network byte order */
++struct sockaddr_in {
++ u8_t sin_len;
++ sa_family_t sin_family;
++ in_port_t sin_port;
++ struct in_addr sin_addr;
++#define SIN_ZERO_LEN 8
++ char sin_zero[SIN_ZERO_LEN];
++};
++#endif /* LWIP_IPV4 */
++
++#if LWIP_IPV6
++struct sockaddr_in6 {
++ u8_t sin6_len; /* length of this structure */
++ sa_family_t sin6_family; /* AF_INET6 */
++ in_port_t sin6_port; /* Transport layer port # */
++ u32_t sin6_flowinfo; /* IPv6 flow information */
++ struct in6_addr sin6_addr; /* IPv6 address */
++ u32_t sin6_scope_id; /* Set of interfaces for scope */
++};
++#endif /* LWIP_IPV6 */
++
++struct sockaddr {
++ u8_t sa_len;
++ sa_family_t sa_family;
++ char sa_data[14];
++};
++
++struct sockaddr_storage {
++ u8_t s2_len;
++ sa_family_t ss_family;
++ char s2_data1[2];
++ u32_t s2_data2[3];
++#if LWIP_IPV6
++ u32_t s2_data3[3];
++#endif /* LWIP_IPV6 */
++};
++
++/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
++ to prevent this code from redefining it. */
++#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
++typedef u32_t socklen_t;
++#endif
++
++struct lwip_sock;
++
++#if !LWIP_TCPIP_CORE_LOCKING
++/** Maximum optlen used by setsockopt/getsockopt */
++#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16
++
++/** This struct is used to pass data to the set/getsockopt_internal
++ * functions running in tcpip_thread context (only a void* is allowed) */
++struct lwip_setgetsockopt_data {
++ /** socket index for which to change options */
++ int s;
++ /** level of the option to process */
++ int level;
++ /** name of the option to process */
++ int optname;
++ /** set: value to set the option to
++ * get: value of the option is stored here */
++#if LWIP_MPU_COMPATIBLE
++ u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN];
++#else
++ union {
++ void *p;
++ const void *pc;
++ } optval;
++#endif
++ /** size of *optval */
++ socklen_t optlen;
++ /** if an error occurs, it is temporarily stored here */
++ err_t err;
++ /** semaphore to wake up the calling task */
++ void* completed_sem;
++};
++#endif /* !LWIP_TCPIP_CORE_LOCKING */
++
++#if !defined(iovec)
++struct iovec {
++ void *iov_base;
++ size_t iov_len;
++};
++#endif
++
++struct msghdr {
++ void *msg_name;
++ socklen_t msg_namelen;
++ struct iovec *msg_iov;
++ int msg_iovlen;
++ void *msg_control;
++ socklen_t msg_controllen;
++ int msg_flags;
++};
++
++/* Socket protocol types (TCP/UDP/RAW) */
++#define SOCK_STREAM 1
++#define SOCK_DGRAM 2
++#define SOCK_RAW 3
++
++/*
++ * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c)
++ */
++#define SO_REUSEADDR 0x0004 /* Allow local address reuse */
++#define SO_KEEPALIVE 0x0008 /* keep connections alive */
++#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
++
++
++/*
++ * Additional options, not kept in so_options.
++ */
++#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */
++#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
++#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */
++#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
++#define SO_LINGER 0x0080 /* linger on close if data present */
++#define SO_DONTLINGER ((int)(~SO_LINGER))
++#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */
++#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */
++#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
++#define SO_RCVBUF 0x1002 /* receive buffer size */
++#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
++#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */
++#define SO_SNDTIMEO 0x1005 /* send timeout */
++#define SO_RCVTIMEO 0x1006 /* receive timeout */
++#define SO_ERROR 0x1007 /* get error status and clear */
++#define SO_TYPE 0x1008 /* get socket type */
++#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
++#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
++
++
++/*
++ * Structure used for manipulating linger option.
++ */
++struct linger {
++ int l_onoff; /* option on/off */
++ int l_linger; /* linger time in seconds */
++};
++
++/*
++ * Level number for (get/set)sockopt() to apply to socket itself.
++ */
++#define SOL_SOCKET 0xfff /* options for socket level */
++
++
++#define AF_UNSPEC 0
++#define AF_INET 2
++#if LWIP_IPV6
++#define AF_INET6 10
++#else /* LWIP_IPV6 */
++#define AF_INET6 AF_UNSPEC
++#endif /* LWIP_IPV6 */
++#define PF_INET AF_INET
++#define PF_INET6 AF_INET6
++#define PF_UNSPEC AF_UNSPEC
++
++#define IPPROTO_IP 0
++#define IPPROTO_ICMP 1
++#define IPPROTO_TCP 6
++#define IPPROTO_UDP 17
++#if LWIP_IPV6
++#define IPPROTO_IPV6 41
++#define IPPROTO_ICMPV6 58
++#endif /* LWIP_IPV6 */
++#define IPPROTO_UDPLITE 136
++#define IPPROTO_RAW 255
++
++/* Flags we can use with send and recv. */
++#define MSG_PEEK 0x01 /* Peeks at an incoming message */
++#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
++#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
++#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
++#define MSG_MORE 0x10 /* Sender will send more */
++
++
++/*
++ * Options for level IPPROTO_IP
++ */
++#define IP_TOS 1
++#define IP_TTL 2
++
++#if LWIP_TCP
++/*
++ * Options for level IPPROTO_TCP
++ */
++#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
++#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
++#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
++#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */
++#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_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */
++#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
++ */
++#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
++#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
++#endif /* LWIP_UDP && LWIP_UDPLITE*/
++
++
++#if LWIP_MULTICAST_TX_OPTIONS
++/*
++ * Options and types for UDP multicast traffic handling
++ */
++#define IP_MULTICAST_TTL 5
++#define IP_MULTICAST_IF 6
++#define IP_MULTICAST_LOOP 7
++#endif /* LWIP_MULTICAST_TX_OPTIONS */
++
++#if LWIP_IGMP
++/*
++ * Options and types related to multicast membership
++ */
++#define IP_ADD_MEMBERSHIP 3
++#define IP_DROP_MEMBERSHIP 4
++
++typedef struct ip_mreq {
++ struct in_addr imr_multiaddr; /* IP multicast address of group */
++ struct in_addr imr_interface; /* local IP address of interface */
++} ip_mreq;
++#endif /* LWIP_IGMP */
++
++/*
++ * The Type of Service provides an indication of the abstract
++ * parameters of the quality of service desired. These parameters are
++ * to be used to guide the selection of the actual service parameters
++ * when transmitting a datagram through a particular network. Several
++ * networks offer service precedence, which somehow treats high
++ * precedence traffic as more important than other traffic (generally
++ * by accepting only traffic above a certain precedence at time of high
++ * load). The major choice is a three way tradeoff between low-delay,
++ * high-reliability, and high-throughput.
++ * The use of the Delay, Throughput, and Reliability indications may
++ * increase the cost (in some sense) of the service. In many networks
++ * better performance for one of these parameters is coupled with worse
++ * performance on another. Except for very unusual cases at most two
++ * of these three indications should be set.
++ */
++#define IPTOS_TOS_MASK 0x1E
++#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
++#define IPTOS_LOWDELAY 0x10
++#define IPTOS_THROUGHPUT 0x08
++#define IPTOS_RELIABILITY 0x04
++#define IPTOS_LOWCOST 0x02
++#define IPTOS_MINCOST IPTOS_LOWCOST
++
++/*
++ * The Network Control precedence designation is intended to be used
++ * within a network only. The actual use and control of that
++ * designation is up to each network. The Internetwork Control
++ * designation is intended for use by gateway control originators only.
++ * If the actual use of these precedence designations is of concern to
++ * a particular network, it is the responsibility of that network to
++ * control the access to, and use of, those precedence designations.
++ */
++#define IPTOS_PREC_MASK 0xe0
++#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
++#define IPTOS_PREC_NETCONTROL 0xe0
++#define IPTOS_PREC_INTERNETCONTROL 0xc0
++#define IPTOS_PREC_CRITIC_ECP 0xa0
++#define IPTOS_PREC_FLASHOVERRIDE 0x80
++#define IPTOS_PREC_FLASH 0x60
++#define IPTOS_PREC_IMMEDIATE 0x40
++#define IPTOS_PREC_PRIORITY 0x20
++#define IPTOS_PREC_ROUTINE 0x00
++
++
++/*
++ * Commands for ioctlsocket(), taken from the BSD file fcntl.h.
++ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
++ *
++ * Ioctl's have the command encoded in the lower word,
++ * and the size of any in or out parameters in the upper
++ * word. The high 2 bits of the upper word are used
++ * to encode the in/out status of the parameter; for now
++ * we restrict parameters to at most 128 bytes.
++ */
++#if !defined(FIONREAD) || !defined(FIONBIO)
++#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */
++#define IOC_VOID 0x20000000UL /* no parameters */
++#define IOC_OUT 0x40000000UL /* copy out parameters */
++#define IOC_IN 0x80000000UL /* copy in parameters */
++#define IOC_INOUT (IOC_IN|IOC_OUT)
++ /* 0x20000000 distinguishes new &
++ old ioctl's */
++#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
++
++#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
++
++#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
++#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
++
++#ifndef FIONREAD
++#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
++#endif
++#ifndef FIONBIO
++#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */
++#endif
++
++/* Socket I/O Controls: unimplemented */
++#ifndef SIOCSHIWAT
++#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */
++#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */
++#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */
++#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */
++#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */
++#endif
++
++/* commands for fnctl */
++#ifndef F_GETFL
++#define F_GETFL 3
++#endif
++#ifndef F_SETFL
++#define F_SETFL 4
++#endif
++
++/* File status flags and file access modes for fnctl,
++ these are bits in an int. */
++#ifndef O_NONBLOCK
++#define O_NONBLOCK 1 /* nonblocking I/O */
++#endif
++#ifndef O_NDELAY
++#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */
++#endif
++
++#ifndef SHUT_RD
++ #define SHUT_RD 0
++ #define SHUT_WR 1
++ #define SHUT_RDWR 2
++#endif
++
++/* FD_SET used for lwip_select */
++#ifndef FD_SET
++#undef FD_SETSIZE
++/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
++#define FD_SETSIZE MEMP_NUM_NETCONN
++#define FDSETSAFESET(n, code) do { \
++ if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \
++ code; }} while(0)
++#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
++ (code) : 0)
++#define FD_SET(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |= (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
++#define FD_CLR(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
++#define FD_ISSET(n,p) FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
++#define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
++
++typedef struct fd_set
++{
++ unsigned char fd_bits [(FD_SETSIZE+7)/8];
++} fd_set;
++
++#elif LWIP_SOCKET_OFFSET
++#error LWIP_SOCKET_OFFSET does not work with external FD_SET!
++#elif FD_SETSIZE < MEMP_NUM_NETCONN
++#error "external FD_SETSIZE too small for number of sockets"
++#endif /* FD_SET */
++
++/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
++ * by your system, set this to 0 and include <sys/time.h> in cc.h */
++#ifndef LWIP_TIMEVAL_PRIVATE
++#define LWIP_TIMEVAL_PRIVATE 1
++#endif
++
++#if LWIP_TIMEVAL_PRIVATE
++struct timeval {
++ long tv_sec; /* seconds */
++ long tv_usec; /* and microseconds */
++};
++#endif /* LWIP_TIMEVAL_PRIVATE */
++
++#define lwip_socket_init() /* Compatibility define, no init needed. */
++void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */
++void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */
++
++#if LWIP_COMPAT_SOCKETS == 2
++/* This helps code parsers/code completion by not having the COMPAT functions as defines */
++#define lwip_accept accept
++#define lwip_bind bind
++#define lwip_shutdown shutdown
++#define lwip_getpeername getpeername
++#define lwip_getsockname getsockname
++#define lwip_setsockopt setsockopt
++#define lwip_getsockopt getsockopt
++#define lwip_close closesocket
++#define lwip_connect connect
++#define lwip_listen listen
++#define lwip_recv recv
++#define lwip_recvfrom recvfrom
++#define lwip_send send
++#define lwip_sendmsg sendmsg
++#define lwip_sendto sendto
++#define lwip_socket socket
++#define lwip_select select
++#define lwip_ioctlsocket ioctl
++
++#if LWIP_POSIX_SOCKETS_IO_NAMES
++#define lwip_read read
++#define lwip_write write
++#define lwip_writev writev
++#undef lwip_close
++#define lwip_close close
++#define closesocket(s) close(s)
++#define lwip_fcntl fcntl
++#define lwip_ioctl ioctl
++#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
++#endif /* LWIP_COMPAT_SOCKETS == 2 */
++
++#if LWIP_COMPAT_SOCKETS
++#if LWIP_COMPAT_SOCKETS != 2
++#define accept(s,addr,addrlen) lwip_accept(s,addr,addrlen)
++#define bind(s,name,namelen) lwip_bind(s,name,namelen)
++#define shutdown(s,how) lwip_shutdown(s,how)
++#define getpeername(s,name,namelen) lwip_getpeername(s,name,namelen)
++#define getsockname(s,name,namelen) lwip_getsockname(s,name,namelen)
++#define setsockopt(s,level,optname,opval,optlen) lwip_setsockopt(s,level,optname,opval,optlen)
++#define getsockopt(s,level,optname,opval,optlen) lwip_getsockopt(s,level,optname,opval,optlen)
++#define closesocket(s) lwip_close(s)
++#define connect(s,name,namelen) lwip_connect(s,name,namelen)
++#define listen(s,backlog) lwip_listen(s,backlog)
++#define recv(s,mem,len,flags) lwip_recv(s,mem,len,flags)
++#define recvfrom(s,mem,len,flags,from,fromlen) lwip_recvfrom(s,mem,len,flags,from,fromlen)
++#define send(s,dataptr,size,flags) lwip_send(s,dataptr,size,flags)
++#define sendmsg(s,message,flags) lwip_sendmsg(s,message,flags)
++#define sendto(s,dataptr,size,flags,to,tolen) lwip_sendto(s,dataptr,size,flags,to,tolen)
++#define socket(domain,type,protocol) lwip_socket(domain,type,protocol)
++#define select(maxfdp1,readset,writeset,exceptset,timeout) lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
++#define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp)
++
++#if LWIP_POSIX_SOCKETS_IO_NAMES
++#define read(s,mem,len) lwip_read(s,mem,len)
++#define write(s,dataptr,len) lwip_write(s,dataptr,len)
++#define writev(s,iov,iovcnt) lwip_writev(s,iov,iovcnt)
++#define close(s) lwip_close(s)
++#define fcntl(s,cmd,val) lwip_fcntl(s,cmd,val)
++#define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp)
++#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
++#endif /* LWIP_COMPAT_SOCKETS != 2 */
++
++#if LWIP_IPV4 && LWIP_IPV6
++#define inet_ntop(af,src,dst,size) \
++ (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) \
++ : (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL))
++#define inet_pton(af,src,dst) \
++ (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
++ : (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
++#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
++#define inet_ntop(af,src,dst,size) \
++ (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL)
++#define inet_pton(af,src,dst) \
++ (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
++#else /* LWIP_IPV4 && LWIP_IPV6 */
++#define inet_ntop(af,src,dst,size) \
++ (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) : NULL)
++#define inet_pton(af,src,dst) \
++ (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0)
++#endif /* LWIP_IPV4 && LWIP_IPV6 */
++
++#endif /* LWIP_COMPAT_SOCKETS */
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* LWIP_SOCKET */
++
++#endif /* LWIP_HDR_PRIV_SOCKETS_H */
--- a/src/include/lwip/opt.h
+++ b/src/include/lwip/opt.h
@@ -1760,6 +1760,15 @@
@@ -1497,7 +1497,7 @@ Won't get to upstream
int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
int lwip_shutdown(int s, int how);
int lwip_ioctl(int s, long cmd, void *argp);
int lwip_fcntl(int s, int cmd, int val);
@@ -1596,35 +1596,20 @@ Won't get to upstream
--- a/port/include/lwipopts.h
+++ b/port/include/lwipopts.h
@@ -26,6 +26,11 @@
- /* Don't rename Sockets API functions */
- #define LWIP_COMPAT_SOCKETS 0
-
-+/* Use Glibc's sockets headers */
-+#define LWIP_STD_SOCKETS 1
-+#define LWIP_INCLUDE_STD_SOCKETS "posix/socket.h"
-+#define LWIP_INCLUDE_STD_INET "posix/inet.h"
-+
- /* Use Glibc malloc()/free() */
- #define MEM_LIBC_MALLOC 1
- #define MEMP_MEM_MALLOC 1
---- a/port/include/arch/cc.h
-+++ b/port/include/arch/cc.h
- /* Use our own ioctls */
- #include <sys/ioctl.h>
-
-+/* Use our own <sys/socket.h> */
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <netinet/tcp.h>
-+#include <netinet/udp.h>
-+
- /* Use our own htons() and pals */
- #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
-
+ /* Don't rename Sockets API functions */
+ #define LWIP_COMPAT_SOCKETS 0
+
++/* Use Glibc's sockets headers */
++#define LWIP_STD_SOCKETS 1
++#define LWIP_INCLUDE_STD_SOCKETS "posix/socket.h"
++#define LWIP_INCLUDE_STD_INET "posix/inet.h"
++
+ /* Use Glibc malloc()/free() */
+ #define MEM_LIBC_MALLOC 1
+ #define MEMP_MEM_MALLOC 1
--- a/src/api/netdb.c
+++ b/src/api/netdb.c
/* set up sockaddr */
inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr));
sa6->sin6_family = AF_INET6;
@@ -1634,7 +1619,7 @@ Won't get to upstream
sa6->sin6_port = lwip_htons((u16_t)port_nr);
ai->ai_family = AF_INET6;
#endif /* LWIP_IPV6 */
/* set up sockaddr */
inet_addr_from_ip4addr(&sa4->sin_addr, ip_2_ip4(&addr));
sa4->sin_family = AF_INET;
@@ -1676,7 +1661,7 @@ Won't get to upstream
(sin6)->sin6_family = AF_INET6; \
(sin6)->sin6_port = lwip_htons((port)); \
(sin6)->sin6_flowinfo = 0; \
LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL);
IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port);
@@ -1688,7 +1673,7 @@ Won't get to upstream
MEMCPY(addr, &tempaddr, *addrlen);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
if (from && fromlen)
#endif /* SOCKETS_DEBUG */
{
@@ -1700,7 +1685,7 @@ Won't get to upstream
MEMCPY(from, &saddr, *fromlen);
}
}
ip_addr_debug_print_val(SOCKETS_DEBUG, naddr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port));
--
2.11.0