diff --git a/src/api/sockets.c b/src/api/sockets.c index b7632489..786a294e 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -44,6 +44,8 @@ * */ +//#include + #include "lwip/opt.h" #if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 07b2f984..f10136e2 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -150,6 +150,11 @@ tcpip_thread(void *arg) msg->msg.cb.function(msg->msg.cb.ctx); break; + case TCPIP_MSG_SHUTDOWN: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: SHUTDOWN %p\n", (void *)msg)); + sys_sem_signal(msg->msg.api_call.sem); + return; + default: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); LWIP_ASSERT("tcpip_thread: invalid message", 0); @@ -158,6 +163,49 @@ tcpip_thread(void *arg) } } +err_t +tcpip_shutdown(void) +{ + //struct tcpip_msg msg; + sys_sem_t sem; + + /* If there is no tcpip mailbox, leave */ + if (mbox == SYS_MBOX_NULL) + return ERR_OK; + + /* Create semaphore for message */ + sys_sem_new(&sem, 0); + LWIP_ASSERT("tcpip_terminate: failed to create semaphore\n", + sem != SYS_SEM_NULL); + if (sem == SYS_SEM_NULL) { + return ERR_MEM; + } + + /* TODO: do we need to stop the timers? if so, how? */ + + struct tcpip_msg *msg; + LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox)); + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); + + /* Tell tcpip thread to exit, and wait */ + msg->msg.api_call.sem = &sem; + msg->type = TCPIP_MSG_SHUTDOWN; + + if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + return ERR_MEM; + } + + sys_arch_sem_wait(&sem, 0); + + /* clean up tcpip thread resources */ + + //sys_mbox_free(&mbox); + sys_sem_free(&sem); + mbox = SYS_MBOX_NULL; + return ERR_OK; +} + /** * Pass a received packet to tcpip_thread for input processing * diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index f14e3342..facd3b21 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -264,6 +264,17 @@ ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest) } } + /* Choose a ZeroTier adhoc with matching prefix. */ + if (ip6_addr_is_zt_adhoc(dest)) { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_is_zt_adhoc(netif_ip6_addr(netif, i)) && + ip6_addr_6plane_cmp(dest, netif_ip6_addr(netif, i))) { + return netif_ip_addr6(netif, i); + } + } + } + /* Last resort: see if arbitrary prefix matches. */ for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c index 0b367181..2a5b77d4 100644 --- a/src/core/ipv6/nd6.c +++ b/src/core/ipv6/nd6.c @@ -1361,8 +1361,13 @@ nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif) } /* Check to see if address prefix matches a (manually?) configured address. */ for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i))) { + int prefix_match = 0; + if (ip6_addr_is_zt_6plane(ip6addr) || ip6_addr_is_zt_adhoc(ip6addr)) { + prefix_match = ip6_addr_6plane_cmp(ip6addr, netif_ip6_addr(netif, i)); + } else { + prefix_match = ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i)); + } + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && prefix_match) { return 1; } } diff --git a/src/core/timeouts.c b/src/core/timeouts.c index 8bf209a5..cf4e556a 100644 --- a/src/core/timeouts.c +++ b/src/core/timeouts.c @@ -186,6 +186,19 @@ void sys_timeouts_init(void) timeouts_last_time = sys_now(); } +/** Remove all timeouts */ +void sys_timeouts_free(void) +{ + size_t i; + for (i = (LWIP_TCP ? 1 : 0); i < LWIP_ARRAYSIZE(lwip_cyclic_timers); i++) { + /* we have to cast via size_t to get rid of const warning + (this is OK as cyclic_timer() casts back to const* */ + sys_untimeout(cyclic_timer, LWIP_CONST_CAST(void*, &lwip_cyclic_timers[i])); + } + /* Initialise timestamp for sys_check_timeouts */ + timeouts_last_time = sys_now(); +} + /** * Create a one-shot timer (aka timeout). Timeouts are processed in the * following cases: diff --git a/src/include/lwip/errno.h b/src/include/lwip/errno.h index 641cffb0..cec43f7f 100644 --- a/src/include/lwip/errno.h +++ b/src/include/lwip/errno.h @@ -174,7 +174,11 @@ extern "C" { #define EMEDIUMTYPE 124 /* Wrong medium type */ #ifndef errno -extern int errno; +#if defined(__linux__) && !defined(__ANDROID__) + #include +#else + extern int errno; +#endif #endif #else /* LWIP_PROVIDE_ERRNO */ diff --git a/src/include/lwip/ip6_addr.h b/src/include/lwip/ip6_addr.h index ee381aeb..b879f212 100644 --- a/src/include/lwip/ip6_addr.h +++ b/src/include/lwip/ip6_addr.h @@ -133,6 +133,14 @@ typedef struct ip6_addr ip6_addr_t; #define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ ((addr1)->addr[1] == (addr2)->addr[1])) +#define ip6_addr_is_zt_6plane(addr1) (((addr1)->addr[0] & PP_HTONL(0xffffffffUL)) == PP_HTONL(0xfc937e7fUL) && \ + ((addr1)->addr[1] & PP_HTONL(0xff000000UL)) == PP_HTONL(0x72000000UL)) + +#define ip6_addr_is_zt_adhoc(addr1) (((addr1)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xfce90000UL)) + +#define ip6_addr_6plane_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ + ((addr1)->addr[1] & PP_HTONL(0xff000000UL)) == ((addr2)->addr[1] & PP_HTONL(0xff000000UL))) + #define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ ((addr1)->addr[1] == (addr2)->addr[1]) && \ ((addr1)->addr[2] == (addr2)->addr[2]) && \ diff --git a/src/include/lwip/priv/tcpip_priv.h b/src/include/lwip/priv/tcpip_priv.h index 630efb14..41fb3e60 100644 --- a/src/include/lwip/priv/tcpip_priv.h +++ b/src/include/lwip/priv/tcpip_priv.h @@ -117,7 +117,8 @@ enum tcpip_msg_type { TCPIP_MSG_UNTIMEOUT, #endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ TCPIP_MSG_CALLBACK, - TCPIP_MSG_CALLBACK_STATIC + TCPIP_MSG_CALLBACK_STATIC, + TCPIP_MSG_SHUTDOWN }; struct tcpip_msg { diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h index 2522056d..1af0c989 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h @@ -104,7 +104,7 @@ struct sockaddr_storage { /* 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) +#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) && !defined(__ANDROID__) typedef u32_t socklen_t; #endif diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h index f2f6b469..60d3578b 100644 --- a/src/include/lwip/tcpip.h +++ b/src/include/lwip/tcpip.h @@ -73,6 +73,7 @@ typedef void (*tcpip_callback_fn)(void *ctx); struct tcpip_callback_msg; void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); +err_t tcpip_shutdown(); err_t tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn); err_t tcpip_input(struct pbuf *p, struct netif *inp); diff --git a/src/include/lwip/timeouts.h b/src/include/lwip/timeouts.h index c9b93aa0..74385dd4 100644 --- a/src/include/lwip/timeouts.h +++ b/src/include/lwip/timeouts.h @@ -94,6 +94,7 @@ struct sys_timeo { }; void sys_timeouts_init(void); +void sys_timeouts_free(void); #if LWIP_DEBUG_TIMERNAMES void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name);