Managed Routes now supported, with automatic add/remove
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,6 +21,7 @@ zt3
|
||||
zt4
|
||||
zt5
|
||||
zt6
|
||||
objs
|
||||
|
||||
*.bob
|
||||
*.alice
|
||||
|
||||
48
Jenkinsfile
vendored
48
Jenkinsfile
vendored
@@ -16,7 +16,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib, no stack') {
|
||||
sh 'make static_lib NO_STACK=1; make tests'
|
||||
sh 'make clean; make static_lib NO_STACK=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -30,7 +30,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib, no stack, ipv4') {
|
||||
sh 'make static_lib NO_STACK=1 LIBZT_IPV4=1; make tests'
|
||||
sh 'make clean; make static_lib NO_STACK=1 LIBZT_IPV4=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -44,7 +44,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib, no stack, ipv6') {
|
||||
sh 'make static_lib NO_STACK=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make static_lib NO_STACK=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -58,7 +58,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib, no stack, ipv4, ipv6') {
|
||||
sh 'make static_lib NO_STACK=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make static_lib NO_STACK=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -74,7 +74,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib, picoTCP') {
|
||||
sh 'make static_lib STACK_PICO=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_PICO=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -88,7 +88,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib, picoTCP, ipv4') {
|
||||
sh 'make static_lib STACK_PICO=1 LIBZT_IPV4=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_PICO=1 LIBZT_IPV4=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -102,7 +102,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib, picoTCP, ipv6') {
|
||||
sh 'make static_lib STACK_PICO=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_PICO=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -116,7 +116,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib, picoTCP, ipv4, ipv6') {
|
||||
sh 'make static_lib STACK_PICO=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_PICO=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -133,7 +133,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib lwIP') {
|
||||
sh 'make static_lib STACK_LWIP=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_LWIP=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -148,7 +148,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib lwIP, ipv4') {
|
||||
sh 'make static_lib STACK_LWIP=1 LIBZT_IPV4=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_LWIP=1 LIBZT_IPV4=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -163,7 +163,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib lwIP, ipv6') {
|
||||
sh 'make static_lib STACK_LWIP=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_LWIP=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -178,7 +178,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('linux static lib lwIP, ipv4, ipv6') {
|
||||
sh 'make static_lib STACK_LWIP=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make clean; make static_lib STACK_LWIP=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -214,7 +214,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, no stack') {
|
||||
sh 'make static_lib NO_STACK=1; make tests'
|
||||
sh 'make clean; make static_lib NO_STACK=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -228,7 +228,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, no stack, ipv4') {
|
||||
sh 'make static_lib NO_STACK=1 LIBZT_IPV4=1; make tests'
|
||||
sh 'make clean; make static_lib NO_STACK=1 LIBZT_IPV4=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -242,7 +242,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, no stack, ipv6') {
|
||||
sh 'make static_lib NO_STACK=1 LIBZT_IPV6=1'; make tests
|
||||
sh 'make clean; make static_lib NO_STACK=1 LIBZT_IPV6=1'; make tests
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -256,7 +256,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, no stack, ipv4, ipv6') {
|
||||
sh 'make static_lib NO_STACK=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make static_lib NO_STACK=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -271,7 +271,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, picoTCP') {
|
||||
sh 'make static_lib STACK_PICO=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_PICO=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -285,7 +285,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, picoTCP, ipv4') {
|
||||
sh 'make static_lib STACK_PICO=1 LIBZT_IPV4=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_PICO=1 LIBZT_IPV4=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -299,7 +299,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, picoTCP, ipv6') {
|
||||
sh 'make static_lib STACK_PICO=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_PICO=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -313,7 +313,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, picoTCP, ipv4, ipv6') {
|
||||
sh 'make static_lib STACK_PICO=1 LIBZT_IPV4=1 LIBZT_IPV6=1'; make tests
|
||||
sh 'make clean; make static_lib STACK_PICO=1 LIBZT_IPV4=1 LIBZT_IPV6=1'; make tests
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -330,7 +330,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, lwIP') {
|
||||
sh 'make static_lib STACK_LWIP=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_LWIP=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -344,7 +344,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, lwIP, ipv4') {
|
||||
sh 'make static_lib STACK_LWIP=1 LIBZT_IPV4=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_LWIP=1 LIBZT_IPV4=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -358,7 +358,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, lwIP, ipv6') {
|
||||
sh 'make static_lib STACK_LWIP=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_LWIP=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
@@ -372,7 +372,7 @@ parallel 'centos7': {
|
||||
checkout scm
|
||||
sh 'git submodule update --init'
|
||||
stage('macOS static lib, lwIP, ipv4, ipv6') {
|
||||
sh 'make static_lib STACK_LWIP=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
sh 'make clean; make static_lib STACK_LWIP=1 LIBZT_IPV4=1 LIBZT_IPV6=1; make tests'
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
|
||||
@@ -1159,7 +1159,7 @@ static int pico_ipv4_frame_sock_push(struct pico_protocol *self, struct pico_fra
|
||||
}
|
||||
|
||||
|
||||
int MOCKABLE pico_ipv4_route_add(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link)
|
||||
extern int MOCKABLE pico_ipv4_route_add(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link)
|
||||
{
|
||||
struct pico_ipv4_route test, *new;
|
||||
test.dest.addr = address.addr;
|
||||
|
||||
@@ -94,6 +94,10 @@ extern "C" {
|
||||
#endif
|
||||
int pico_ipv4_link_add(struct pico_device *dev, struct pico_ip4 address, struct pico_ip4 netmask);
|
||||
int pico_string_to_ipv4(const char *ipstr, uint32_t *ip);
|
||||
int pico_ipv4_route_add(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link);
|
||||
int pico_ipv4_route_del(struct pico_ip4 address, struct pico_ip4 netmask, int metric);
|
||||
struct pico_ip4 pico_ipv4_route_get_gateway(struct pico_ip4 *addr);
|
||||
void pico_ipv4_route_set_bcast_link(struct pico_ipv4_link *link);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -108,10 +112,6 @@ struct pico_ipv4_link *pico_ipv4_link_by_dev_next(struct pico_device *dev, struc
|
||||
struct pico_device *pico_ipv4_link_find(struct pico_ip4 *address);
|
||||
struct pico_ip4 *pico_ipv4_source_find(const struct pico_ip4 *dst);
|
||||
struct pico_device *pico_ipv4_source_dev_find(const struct pico_ip4 *dst);
|
||||
int pico_ipv4_route_add(struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link);
|
||||
int pico_ipv4_route_del(struct pico_ip4 address, struct pico_ip4 netmask, int metric);
|
||||
struct pico_ip4 pico_ipv4_route_get_gateway(struct pico_ip4 *addr);
|
||||
void pico_ipv4_route_set_bcast_link(struct pico_ipv4_link *link);
|
||||
void pico_ipv4_unreachable(struct pico_frame *f, int err);
|
||||
|
||||
int pico_ipv4_mcast_join(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group, uint8_t reference_count, uint8_t filter_mode, struct pico_tree *MCASTFilter);
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
#include <net/if.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include "ZeroTierOne.h"
|
||||
|
||||
// See test/selftest.cpp for examples
|
||||
|
||||
/****************************************************************************/
|
||||
/* For SOCK_RAW support, it will initially be modeled after linux's API, so */
|
||||
@@ -463,6 +468,11 @@ int zts_write(ZT_WRITE_SIG);
|
||||
*/
|
||||
int zts_shutdown(ZT_SHUTDOWN_SIG);
|
||||
|
||||
/*
|
||||
* Returns a vector of network routes { target, via, metric, etc... }
|
||||
*/
|
||||
std::vector<ZT_VirtualNetworkRoute> *zts_get_network_routes(char *nwid);
|
||||
|
||||
/****************************************************************************/
|
||||
/* SDK Socket API Helper functions/objects --- DONT CALL THESE DIRECTLY */
|
||||
/****************************************************************************/
|
||||
@@ -515,6 +525,10 @@ ZeroTier::SocketTap *getTapByNWID(uint64_t nwid);
|
||||
ZeroTier::SocketTap *getTapByAddr(ZeroTier::InetAddress &addr);
|
||||
ZeroTier::SocketTap *getTapByName(char *ifname);
|
||||
ZeroTier::SocketTap *getTapByIndex(int index);
|
||||
|
||||
/*
|
||||
* Destroys all virtual tap devices
|
||||
*/
|
||||
void dismantleTaps();
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,14 +45,12 @@
|
||||
#include "lwip/debug.h"
|
||||
|
||||
// IP Protocol version
|
||||
// It seems using ipv6/ipv4 in the same stack is problematic, for this reason we
|
||||
// compile for only one or the other using the SDK_IPV4=1/SDK_IPV6=1 flags for now
|
||||
#if defined(SDK_IPV6)
|
||||
#if defined(LIBZT_IPV6)
|
||||
#define LWIP_IPV6 1
|
||||
#define LWIP_IPV4 0
|
||||
|
||||
#endif
|
||||
#if defined(SDK_IPV4)
|
||||
#if defined(LIBZT_IPV4)
|
||||
#define LWIP_IPV4 1
|
||||
#define LWIP_IPV6 0
|
||||
#endif
|
||||
|
||||
@@ -36,7 +36,6 @@ LWIPARCH=$(CONTRIBDIR)/ports/unix
|
||||
#default assumes it's a dir named lwip at the same level as the contrib module
|
||||
LWIPDIR=ext/lwip/src
|
||||
|
||||
|
||||
CCDEP=clang++
|
||||
|
||||
# Automagically pick clang or gcc, with preference for clang
|
||||
@@ -79,14 +78,14 @@ CORE4FILES=$(LWIPDIR)/core/ipv4/autoip.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4.c \
|
||||
$(LWIPDIR)/core/ipv4/ip4_addr.c
|
||||
|
||||
CORE6FILES=$(LWIPDIR)/core/ipv6/dhcp6.c \
|
||||
$(LWIPDIR)/core/ipv6/ethip6.c \
|
||||
CORE6FILES=$(LWIPDIR)/core/ipv6/ethip6.c \
|
||||
$(LWIPDIR)/core/ipv6/icmp6.c \
|
||||
$(LWIPDIR)/core/ipv6/inet6.c \
|
||||
$(LWIPDIR)/core/ipv6/ip6.c \
|
||||
$(LWIPDIR)/core/ipv6/ip6_addr.c \
|
||||
$(LWIPDIR)/core/ipv6/ip6_frag.c \
|
||||
$(LWIPDIR)/core/ipv6/mld6.c \
|
||||
$(LWIPDIR)/core/ipv6/dhcp6.c \
|
||||
$(LWIPDIR)/core/ipv6/nd6.c
|
||||
|
||||
# APIFILES: The files which implement the sequential and socket APIs.
|
||||
@@ -113,7 +112,7 @@ SIXLOWPAN=$(LWIPDIR)/netif/lowpan6.c \
|
||||
ARCHFILES=$(wildcard $(LWIPARCH)/*.c $(LWIPARCH)tapif.c $(LWIPARCH)/netif/list.c $(LWIPARCH)/netif/tcpdump.c)
|
||||
|
||||
# LWIPFILES: All the above.
|
||||
LWIPFILES=$(COREFILES) $(CORE4FILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES)
|
||||
LWIPFILES=$(COREFILES) $(APIFILES) $(NETIFFILES) $(ARCHFILES)
|
||||
|
||||
ifeq ($(IPV4),1)
|
||||
LWIPFILES+=$(CORE4FILES)
|
||||
@@ -127,28 +126,21 @@ endif
|
||||
LWIPFILESW=$(wildcard $(LWIPFILES))
|
||||
LWIPOBJS=$(notdir $(LWIPFILESW:.c=.o))
|
||||
|
||||
LWIPLIB=liblwip.so
|
||||
|
||||
%.o:
|
||||
$(CXX) $(CFLAGS) -Isrc/stack_drivers/lwip -c $(<:.o=.c)
|
||||
$(CXX) $(CFLAGS) -c $(<:.o=.c) -o obj/$@
|
||||
|
||||
all: $(LWIPLIB)
|
||||
all:
|
||||
.PHONY: all
|
||||
|
||||
clean:
|
||||
rm -f *.o $(LWIPLIB4) $(LWIPLIB6) *.s .depend* *.core core
|
||||
rm -f *.o *.s .depend* *.core core
|
||||
|
||||
depend dep: .depend
|
||||
|
||||
include .depend
|
||||
|
||||
$(LWIPLIB): $(LWIPOBJS)
|
||||
mkdir -p build
|
||||
$(CXX) -Isrc/stack_drivers/lwip -g -nostartfiles -shared -o build/$@ $^
|
||||
|
||||
liblwip.a: $(LWIPOBJS)
|
||||
echo $(LWIPOBJS)
|
||||
libtool -static -o $@ $^
|
||||
#libtool -static -o $@ $^
|
||||
|
||||
.depend: $(LWIPFILES)
|
||||
$(CCDEP) $(CFLAGS) -MM $^ > .depend || rm -f .depend
|
||||
@@ -121,12 +121,15 @@ ifeq ($(STACK_PICO),1)
|
||||
ifeq ($(LIBZT_IPV4)$(LIBZT_IPV6),1)
|
||||
ifeq ($(LIBZT_IPV4),1)
|
||||
CXXFLAGS+=-DLIBZT_IPV4
|
||||
STACK_FLAGS+=-IPV4=1 -IPv4=1
|
||||
endif
|
||||
ifeq ($(LIBZT_IPV6),1)
|
||||
CXXFLAGS+=-DLIBZT_IPV6
|
||||
STACK_FLAGS+=-IPV6=1 -IPv6=1
|
||||
endif
|
||||
else
|
||||
CXXFLAGS+=-DLIBZT_IPV4 -DLIBZT_IPV6
|
||||
STACK_FLAGS+=-IPV6=1 -IPv6=1 -IPV6=1 -IPv6=1
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -135,12 +138,15 @@ ifeq ($(STACK_LWIP),1)
|
||||
ifeq ($(LIBZT_IPV4)$(LIBZT_IPV6),1)
|
||||
ifeq ($(LIBZT_IPV4),1)
|
||||
CXXFLAGS+=-DLIBZT_IPV4
|
||||
STACK_FLAGS+=IPV4=1 IPv4=1
|
||||
endif
|
||||
ifeq ($(LIBZT_IPV6),1)
|
||||
CXXFLAGS+=-DLIBZT_IPV6
|
||||
STACK_FLAGS+=IPV6=1 IPv6=1
|
||||
endif
|
||||
else
|
||||
CXXFLAGS+=-DLIBZT_IPV4
|
||||
STACK_FLAGS+=IPV4=1 IPv4=1
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -154,29 +160,14 @@ STACK_DIR:=ext/picotcp
|
||||
STACK_LIB:=$(STACK_DIR)/build/lib/$(STACK_LIB)
|
||||
STACK_DRIVER_FILES:=src/picoTCP.cpp
|
||||
STACK_DRIVER_OBJS+=picoTCP.o
|
||||
STACK_OBJS+= ext/picotcp/build/lib/pico_device.o \
|
||||
ext/picotcp/build/lib/pico_frame.o \
|
||||
ext/picotcp/build/lib/pico_md5.o \
|
||||
ext/picotcp/build/lib/pico_protocol.o \
|
||||
ext/picotcp/build/lib/pico_socket_multicast.o \
|
||||
ext/picotcp/build/lib/pico_socket.o \
|
||||
ext/picotcp/build/lib/pico_stack.o \
|
||||
ext/picotcp/build/lib/pico_tree.o \
|
||||
ext/picotcp/build/modules/*.o
|
||||
INCLUDES+=-Iext/picotcp/include -Iext/picotcp/build/include
|
||||
endif
|
||||
|
||||
ifeq ($(STACK_LWIP),1)
|
||||
STACK_FLAGS+=-DLWIP_PREFIX_BYTEORDER_FUNCS
|
||||
STACK_DRIVER_FLAGS+=-DLWIP_PREFIX_BYTEORDER_FUNCS
|
||||
CXXFLAGS+=-DSTACK_LWIP
|
||||
STACK_DRIVER_FILES:=src/lwIP.cpp
|
||||
STACK_DRIVER_OBJS+=lwIP.o
|
||||
STACK_OBJS+= init.o def.o dns.o inet_chksum.o ip.o mem.o \
|
||||
memp.o netif.o pbuf.o raw.o stats.o sys.o tcp.o \
|
||||
tcp_in.o tcp_out.o timeouts.o udp.o autoip.o \
|
||||
dhcp.o etharp.o icmp.o igmp.o ip4_frag.o ip4.o \
|
||||
ip4_addr.o api_lib.o api_msg.o err.o netbuf.o \
|
||||
netdb.o netifapi.o sockets.o tcpip.o ethernet.o
|
||||
LWIPARCH=$(CONTRIBDIR)/ports/unix
|
||||
LWIPDIR=ext/lwip/src
|
||||
INCLUDES+=-Iext/lwip/src/include/lwip \
|
||||
@@ -193,6 +184,14 @@ endif
|
||||
|
||||
all:
|
||||
|
||||
%.o : %.cpp
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CXX) $(CXXFLAGS) -c $^ -o obj/$(@F)
|
||||
|
||||
%.o : %.c
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CC) $(CFLAGS) -c $^ -o obj/$(@F)
|
||||
|
||||
##############################################################################
|
||||
## User-Space Stack ##
|
||||
##############################################################################
|
||||
@@ -201,7 +200,7 @@ picotcp:
|
||||
cd $(STACK_DIR); make lib ARCH=shared IPV4=1 IPV6=1
|
||||
|
||||
lwip:
|
||||
-make -f make-liblwip.mk liblwip.a IPV4=1 IPV6=1
|
||||
-make -f make-liblwip.mk liblwip.a $(STACK_FLAGS)
|
||||
|
||||
##############################################################################
|
||||
## Static Libraries ##
|
||||
@@ -209,22 +208,27 @@ lwip:
|
||||
|
||||
ifeq ($(STACK_PICO),1)
|
||||
static_lib: picotcp $(ZTO_OBJS)
|
||||
@mkdir -p $(BUILD)
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CXX) $(CXXFLAGS) $(LIBZT_FILES) $(STACK_DRIVER_FILES) -c
|
||||
ar rcs -o $(STATIC_LIB) $(ZTO_OBJS) $(STACK_DRIVER_OBJS) $(STACK_OBJS) $(LIBZT_OBJS) $(STACK_LIB)
|
||||
mv *.o obj
|
||||
mv ext/picotcp/build/lib/*.o obj
|
||||
mv ext/picotcp/build/modules/*.o obj
|
||||
ar rcs -o $(STATIC_LIB) obj/*.o $(STACK_LIB)
|
||||
endif
|
||||
ifeq ($(STACK_LWIP),1)
|
||||
static_lib: lwip $(ZTO_OBJS)
|
||||
@mkdir -p $(BUILD)
|
||||
$(CXX) $(CXXFLAGS) $(STACK_FLAGS) $(STACK_INCLUDES) $(LIBZT_FILES) $(STACK_DRIVER_FILES) -c
|
||||
ar rcs -o $(STATIC_LIB) $(ZTO_OBJS) $(STACK_DRIVER_OBJS) $(STACK_OBJS) $(LIBZT_OBJS) $(STACK_LIB)
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CXX) $(CXXFLAGS) $(STACK_DRIVER_FLAGS) $(STACK_INCLUDES) $(LIBZT_FILES) $(STACK_DRIVER_FILES) -c
|
||||
mv *.o obj
|
||||
ar rcs -o $(STATIC_LIB) obj/*.o $(STACK_LIB)
|
||||
endif
|
||||
# for layer-2 only (this will omit all userspace network stack code)
|
||||
ifeq ($(NO_STACK),1)
|
||||
static_lib: $(ZTO_OBJS)
|
||||
@mkdir -p $(BUILD)
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CXX) $(CXXFLAGS) $(LIBZT_FILES) -c
|
||||
ar rcs -o $(STATIC_LIB) $(ZTO_OBJS) $(LIBZT_OBJS)
|
||||
mv *.o obj
|
||||
ar rcs -o $(STATIC_LIB) obj/*.o
|
||||
endif
|
||||
|
||||
##############################################################################
|
||||
|
||||
49
make-mac.mk
49
make-mac.mk
@@ -119,12 +119,15 @@ ifeq ($(STACK_PICO),1)
|
||||
ifeq ($(LIBZT_IPV4)$(LIBZT_IPV6),1)
|
||||
ifeq ($(LIBZT_IPV4),1)
|
||||
CXXFLAGS+=-DLIBZT_IPV4
|
||||
STACK_FLAGS+=-IPV4=1 -IPv4=1
|
||||
endif
|
||||
ifeq ($(LIBZT_IPV6),1)
|
||||
CXXFLAGS+=-DLIBZT_IPV6
|
||||
STACK_FLAGS+=-IPV6=1 -IPv6=1
|
||||
endif
|
||||
else
|
||||
CXXFLAGS+=-DLIBZT_IPV4 -DLIBZT_IPV6
|
||||
STACK_FLAGS+=-IPV6=1 -IPv6=1 -IPV6=1 -IPv6=1
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -133,12 +136,15 @@ ifeq ($(STACK_LWIP),1)
|
||||
ifeq ($(LIBZT_IPV4)$(LIBZT_IPV6),1)
|
||||
ifeq ($(LIBZT_IPV4),1)
|
||||
CXXFLAGS+=-DLIBZT_IPV4
|
||||
STACK_FLAGS+=IPV4=1 IPv4=1
|
||||
endif
|
||||
ifeq ($(LIBZT_IPV6),1)
|
||||
CXXFLAGS+=-DLIBZT_IPV6
|
||||
STACK_FLAGS+=IPV6=1 IPv6=1
|
||||
endif
|
||||
else
|
||||
CXXFLAGS+=-DLIBZT_IPV4
|
||||
STACK_FLAGS+=IPV4=1 IPv4=1
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -152,27 +158,14 @@ STACK_DIR:=ext/picotcp
|
||||
STACK_LIB:=$(STACK_DIR)/build/lib/$(STACK_LIB)
|
||||
STACK_DRIVER_FILES:=src/picoTCP.cpp
|
||||
STACK_DRIVER_OBJS+=picoTCP.o
|
||||
STACK_OBJS+= ext/picotcp/build/lib/pico_device.o \
|
||||
ext/picotcp/build/lib/pico_frame.o \
|
||||
ext/picotcp/build/lib/pico_md5.o \
|
||||
ext/picotcp/build/lib/pico_protocol.o \
|
||||
ext/picotcp/build/lib/pico_socket_multicast.o \
|
||||
ext/picotcp/build/lib/pico_socket.o \
|
||||
ext/picotcp/build/lib/pico_stack.o \
|
||||
ext/picotcp/build/lib/pico_tree.o
|
||||
INCLUDES+=-Iext/picotcp/include -Iext/picotcp/build/include
|
||||
endif
|
||||
|
||||
ifeq ($(STACK_LWIP),1)
|
||||
STACK_DRIVER_FLAGS+=-DLWIP_PREFIX_BYTEORDER_FUNCS
|
||||
CXXFLAGS+=-DSTACK_LWIP
|
||||
STACK_DRIVER_FILES:=src/lwIP.cpp
|
||||
STACK_DRIVER_OBJS+=lwIP.o
|
||||
STACK_OBJS+= init.o def.o dns.o inet_chksum.o ip.o mem.o \
|
||||
memp.o netif.o pbuf.o raw.o stats.o sys.o tcp.o \
|
||||
tcp_in.o tcp_out.o timeouts.o udp.o autoip.o \
|
||||
dhcp.o etharp.o icmp.o igmp.o ip4_frag.o ip4.o \
|
||||
ip4_addr.o api_lib.o api_msg.o err.o netbuf.o \
|
||||
netdb.o netifapi.o sockets.o tcpip.o ethernet.o
|
||||
LWIPARCH=$(CONTRIBDIR)/ports/unix
|
||||
LWIPDIR=ext/lwip/src
|
||||
INCLUDES+=-Iext/lwip/src/include/lwip \
|
||||
@@ -189,6 +182,14 @@ endif
|
||||
|
||||
all:
|
||||
|
||||
%.o : %.cpp
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CXX) $(CXXFLAGS) -c $^ -o obj/$(@F)
|
||||
|
||||
%.o : %.c
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CC) $(CFLAGS) -c $^ -o obj/$(@F)
|
||||
|
||||
##############################################################################
|
||||
## User-Space Stack ##
|
||||
##############################################################################
|
||||
@@ -203,24 +204,30 @@ lwip:
|
||||
## Static Libraries ##
|
||||
##############################################################################
|
||||
|
||||
|
||||
ifeq ($(STACK_PICO),1)
|
||||
static_lib: picotcp $(ZTO_OBJS)
|
||||
@mkdir -p $(BUILD)
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CXX) $(CXXFLAGS) $(LIBZT_FILES) $(STACK_DRIVER_FILES) -c
|
||||
libtool -static -o $(STATIC_LIB) $(ZTO_OBJS) $(STACK_DRIVER_OBJS) $(STACK_OBJS) $(LIBZT_OBJS) $(STACK_LIB)
|
||||
mv *.o obj
|
||||
mv ext/picotcp/build/lib/*.o obj
|
||||
mv ext/picotcp/build/modules/*.o obj
|
||||
libtool -static -o $(STATIC_LIB) obj/*.o $(STACK_LIB)
|
||||
endif
|
||||
ifeq ($(STACK_LWIP),1)
|
||||
static_lib: lwip $(ZTO_OBJS)
|
||||
@mkdir -p $(BUILD)
|
||||
$(CXX) $(CXXFLAGS) $(STACK_INCLUDES) $(LIBZT_FILES) $(STACK_DRIVER_FILES) -c
|
||||
libtool -static -o $(STATIC_LIB) $(ZTO_OBJS) $(STACK_DRIVER_OBJS) $(STACK_OBJS) $(LIBZT_OBJS) $(STACK_LIB)
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CXX) $(CXXFLAGS) $(STACK_DRIVER_FLAGS) $(STACK_INCLUDES) $(LIBZT_FILES) $(STACK_DRIVER_FILES) -c
|
||||
mv *.o obj
|
||||
libtool -static -o $(STATIC_LIB) obj/*.o $(STACK_LIB)
|
||||
endif
|
||||
# for layer-2 only (this will omit all userspace network stack code)
|
||||
ifeq ($(NO_STACK),1)
|
||||
static_lib: $(ZTO_OBJS)
|
||||
@mkdir -p $(BUILD)
|
||||
@mkdir -p $(BUILD) obj
|
||||
$(CXX) $(CXXFLAGS) $(LIBZT_FILES) -c
|
||||
libtool -static -o $(STATIC_LIB) $(ZTO_OBJS) $(LIBZT_OBJS)
|
||||
mv *.o obj
|
||||
libtool -static -o $(STATIC_LIB) obj/*.o
|
||||
endif
|
||||
|
||||
##############################################################################
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <netinet/ether.h>
|
||||
#endif
|
||||
|
||||
#include "OneService.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "OSUtils.hpp"
|
||||
#include "Constants.hpp"
|
||||
@@ -59,7 +60,9 @@
|
||||
|
||||
class SocketTap;
|
||||
|
||||
|
||||
extern std::vector<void*> vtaps;
|
||||
//extern ZeroTier::OneService *zt1Service;
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
@@ -277,50 +280,79 @@ namespace ZeroTier {
|
||||
Read(sock,uptr,stack_invoked);
|
||||
}
|
||||
|
||||
// Adds a route to the virtual tap
|
||||
bool SocketTap::routeAdd(const InetAddress &addr, const InetAddress &nm, const InetAddress &gw)
|
||||
{
|
||||
#if defined(STACK_PICO)
|
||||
if(picostack)
|
||||
return picostack->pico_route_add(this, addr, nm, gw, 0);
|
||||
#endif
|
||||
#if defined(STACK_LWIP)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deletes a route from the virtual tap
|
||||
bool SocketTap::routeDelete(const InetAddress &addr, const InetAddress &nm)
|
||||
{
|
||||
#if defined(STACK_PICO)
|
||||
if(picostack)
|
||||
return picostack->pico_route_del(this, addr, nm, 0);
|
||||
#endif
|
||||
#if defined(STACK_LWIP)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* SDK Socket API */
|
||||
/****************************************************************************/
|
||||
|
||||
int SocketTap::Connect(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
// Connect
|
||||
int SocketTap::Connect(Connection *conn, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
#if defined(NO_STACK)
|
||||
return -1;
|
||||
#endif
|
||||
Mutex::Lock _l(_tcpconns_m);
|
||||
#if defined(STACK_PICO)
|
||||
if(picostack)
|
||||
return picostack->pico_Connect(conn, fd, addr, addrlen);
|
||||
Mutex::Lock _l(_tcpconns_m);
|
||||
return picostack->pico_Connect(conn, addr, addrlen);
|
||||
#endif
|
||||
#if defined(STACK_LWIP)
|
||||
if(lwipstack)
|
||||
return lwipstack->lwip_Connect(conn, fd, addr, addrlen);
|
||||
return lwipstack->lwip_Connect(conn, addr, addrlen);
|
||||
#endif
|
||||
return ZT_ERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
int SocketTap::Bind(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
// Bind VirtualSocket to a network stack's interface
|
||||
int SocketTap::Bind(Connection *conn, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
#if defined(NO_STACK)
|
||||
return -1;
|
||||
#endif
|
||||
Mutex::Lock _l(_tcpconns_m);
|
||||
#if defined(STACK_PICO)
|
||||
if(picostack)
|
||||
return picostack->pico_Bind(conn, fd, addr, addrlen);
|
||||
return picostack->pico_Bind(conn, addr, addrlen);
|
||||
#endif
|
||||
#if defined(STACK_LWIP)
|
||||
if(lwipstack)
|
||||
return lwipstack->lwip_Bind(this, conn, fd, addr, addrlen);
|
||||
return lwipstack->lwip_Bind(this, conn, addr, addrlen);
|
||||
#endif
|
||||
return ZT_ERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
int SocketTap::Listen(Connection *conn, int fd, int backlog) {
|
||||
// Listen for an incoming connection
|
||||
int SocketTap::Listen(Connection *conn, int backlog) {
|
||||
#if defined(NO_STACK)
|
||||
return -1;
|
||||
#endif
|
||||
Mutex::Lock _l(_tcpconns_m);
|
||||
#if defined(STACK_PICO)
|
||||
if(picostack)
|
||||
return picostack->pico_Listen(conn, fd, backlog);
|
||||
return picostack->pico_Listen(conn, backlog);
|
||||
return ZT_ERR_GENERAL_FAILURE;
|
||||
#endif
|
||||
#if defined(STACK_LWIP)
|
||||
@@ -331,13 +363,14 @@ namespace ZeroTier {
|
||||
return ZT_ERR_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
// Accept a connection
|
||||
Connection* SocketTap::Accept(Connection *conn) {
|
||||
#if defined(NO_STACK)
|
||||
return NULL;
|
||||
#endif
|
||||
Mutex::Lock _l(_tcpconns_m);
|
||||
#if defined(STACK_PICO)
|
||||
if(picostack)
|
||||
Mutex::Lock _l(_tcpconns_m);
|
||||
return picostack->pico_Accept(conn);
|
||||
return NULL;
|
||||
#endif
|
||||
@@ -349,6 +382,7 @@ namespace ZeroTier {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Read from stack/buffers into the app's socket
|
||||
int SocketTap::Read(PhySocket *sock,void **uptr,bool stack_invoked) {
|
||||
#if defined(STACK_PICO)
|
||||
if(picostack)
|
||||
@@ -361,6 +395,7 @@ namespace ZeroTier {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Write data from app socket to the virtual wire, either raw over VL2, or via network stack
|
||||
int SocketTap::Write(Connection *conn, void *data, ssize_t len) {
|
||||
// VL2, SOCK_RAW, no network stack
|
||||
if(conn->socket_type == SOCK_RAW) {
|
||||
@@ -372,7 +407,6 @@ namespace ZeroTier {
|
||||
_handler(_arg,NULL,_nwid,src_mac,dest_mac, Utils::ntoh((uint16_t)eh->ether_type),0, ((char*)data) + sizeof(struct ether_header),len - sizeof(struct ether_header));
|
||||
return len;
|
||||
}
|
||||
|
||||
#if defined(STACK_PICO)
|
||||
if(picostack)
|
||||
return picostack->pico_Write(conn, data, len);
|
||||
@@ -384,6 +418,26 @@ namespace ZeroTier {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Send data to a specified host
|
||||
int SocketTap::SendTo(Connection *conn, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
// TODO: flags
|
||||
int err = 0;
|
||||
DEBUG_INFO();
|
||||
#if defined(STACK_PICO)
|
||||
if(picostack) {
|
||||
err = picostack->pico_Connect(conn, addr, addrlen); // implicit
|
||||
err = picostack->pico_Write(conn, (void*)buf, len);
|
||||
}
|
||||
#endif
|
||||
#if defined(STACK_LWIP)
|
||||
if(lwipstack)
|
||||
err = lwipstack->lwip_Connect(conn, addr, addrlen); // implicit
|
||||
err = lwipstack->lwip_Write(conn, (void*)buf, len);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
int SocketTap::Close(Connection *conn) {
|
||||
#if defined(STACK_PICO)
|
||||
if(!conn) {
|
||||
@@ -427,21 +481,66 @@ namespace ZeroTier {
|
||||
|
||||
void SocketTap::Housekeeping()
|
||||
{
|
||||
#if defined(STACK_PICO)
|
||||
Mutex::Lock _l(_tcpconns_m);
|
||||
std::time_t current_ts = std::time(nullptr);
|
||||
if(current_ts > last_housekeeping_ts + ZT_HOUSEKEEPING_INTERVAL) {
|
||||
// Clean up old Connection objects
|
||||
for(size_t i=0;i<_Connections.size();++i) {
|
||||
if(_Connections[i]->closure_ts != -1 && (current_ts > _Connections[i]->closure_ts + ZT_CONNECTION_DELETE_WAIT_TIME)) {
|
||||
// DEBUG_ERROR("deleting %p object, _Connections.size() = %d", _Connections[i], _Connections.size());
|
||||
delete _Connections[i];
|
||||
_Connections.erase(_Connections.begin() + i);
|
||||
}
|
||||
// update managed routes (add/del from network stacks)
|
||||
if(zt1ServiceRef) {
|
||||
std::vector<ZT_VirtualNetworkRoute> *managed_routes = ((ZeroTier::OneService *)zt1ServiceRef)->getRoutes(this->_nwid);
|
||||
ZeroTier::InetAddress target_addr;
|
||||
ZeroTier::InetAddress via_addr;
|
||||
ZeroTier::InetAddress null_addr;
|
||||
ZeroTier::InetAddress nm;
|
||||
null_addr.fromString("");
|
||||
bool found;
|
||||
char ipbuf[64], ipbuf2[64], ipbuf3[64];
|
||||
// TODO: Rework this when we have time
|
||||
// check if pushed route exists in tap (add)
|
||||
for(int i=0; i<ZT_MAX_NETWORK_ROUTES; i++) {
|
||||
found = false;
|
||||
target_addr = managed_routes->at(i).target;
|
||||
via_addr = managed_routes->at(i).via;
|
||||
nm = target_addr.netmask();
|
||||
for(int j=0; j<routes.size(); j++) {
|
||||
if(via_addr.ipsEqual(null_addr) || target_addr.ipsEqual(null_addr)) {
|
||||
found=true;
|
||||
continue;
|
||||
}
|
||||
if(routes[j].first.ipsEqual(target_addr) && routes[j].second.ipsEqual(nm)) {
|
||||
found=true;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
if(!via_addr.ipsEqual(null_addr)) {
|
||||
DEBUG_INFO("adding route <target=%s, nm=%s, via=%s>", target_addr.toString(ipbuf), nm.toString(ipbuf2), via_addr.toString(ipbuf3));
|
||||
routes.push_back(std::pair<ZeroTier::InetAddress,ZeroTier::InetAddress>(target_addr, nm));
|
||||
routeAdd(target_addr, nm, via_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
// check if route exists in tap but not in pushed routes (remove)
|
||||
for(int i=0; i<routes.size(); i++) {
|
||||
found = false;
|
||||
for(int j=0; j<ZT_MAX_NETWORK_ROUTES; j++) {
|
||||
target_addr = managed_routes->at(j).target;
|
||||
via_addr = managed_routes->at(j).via;
|
||||
nm = target_addr.netmask();
|
||||
if(routes[i].first.ipsEqual(target_addr) && routes[i].second.ipsEqual(nm)) {
|
||||
found=true;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
DEBUG_INFO("removing route to <target=%s>", routes[i].first.toString(ipbuf), routes[i].second.toString(ipbuf2));
|
||||
routes.erase(routes.begin() + i);
|
||||
routeDelete(routes[i].first, routes[i].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Clean up Connection objects
|
||||
|
||||
last_housekeeping_ts = std::time(nullptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -155,6 +155,16 @@ namespace ZeroTier {
|
||||
*/
|
||||
void phyOnUnixWritable(PhySocket *sock, void **uptr, bool lwip_invoked);
|
||||
|
||||
/*
|
||||
* Adds a route to the virtual tap
|
||||
*/
|
||||
bool routeAdd(const InetAddress &addr, const InetAddress &nm, const InetAddress &gw);
|
||||
|
||||
/*
|
||||
* Deletes a route from the virtual tap
|
||||
*/
|
||||
bool routeDelete(const InetAddress &addr, const InetAddress &nm);
|
||||
|
||||
/****************************************************************************/
|
||||
/* Vars */
|
||||
/****************************************************************************/
|
||||
@@ -183,6 +193,9 @@ namespace ZeroTier {
|
||||
netif lwipdev6;
|
||||
#endif
|
||||
|
||||
std::vector<std::pair<ZeroTier::InetAddress, ZeroTier::InetAddress>> routes;
|
||||
void *zt1ServiceRef;
|
||||
|
||||
static int devno;
|
||||
int ifindex;
|
||||
|
||||
@@ -222,17 +235,17 @@ namespace ZeroTier {
|
||||
/*
|
||||
* Connect to a remote host via the userspace stack interface associated with this SocketTap
|
||||
*/
|
||||
int Connect(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int Connect(Connection *conn, const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
/*
|
||||
* Bind to the userspace stack interface associated with this SocketTap
|
||||
*/
|
||||
int Bind(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int Bind(Connection *conn, const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
/*
|
||||
* Listen for a Connection
|
||||
*/
|
||||
int Listen(Connection *conn, int fd, int backlog);
|
||||
int Listen(Connection *conn, int backlog);
|
||||
|
||||
/*
|
||||
* Accepts an incoming Connection
|
||||
@@ -249,6 +262,11 @@ namespace ZeroTier {
|
||||
*/
|
||||
int Write(Connection *conn, void *data, ssize_t len);
|
||||
|
||||
/*
|
||||
* Send data to specified host
|
||||
*/
|
||||
int SendTo(Connection *conn, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
/*
|
||||
* Closes a Connection
|
||||
*/
|
||||
|
||||
@@ -24,4 +24,4 @@
|
||||
* of your own application.
|
||||
*/
|
||||
|
||||
// Intentionally left blank
|
||||
// Intentionally left blank
|
||||
@@ -27,6 +27,30 @@
|
||||
#ifndef UTILITIES_HPP
|
||||
#define UTILITIES_HPP
|
||||
|
||||
#if defined(STACK_LWIP) && defined(LIBZT_IPV6)
|
||||
#define IP6_ADDR2(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = ZeroTier::Utils::hton((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \
|
||||
(ipaddr)->addr[1] = ZeroTier::Utils::hton(((c & 0xffff) << 16) | (d & 0xffff)); \
|
||||
(ipaddr)->addr[2] = ZeroTier::Utils::hton(((e & 0xffff) << 16) | (f & 0xffff)); \
|
||||
(ipaddr)->addr[3] = ZeroTier::Utils::hton(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)
|
||||
|
||||
// Convert from standard IPV6 address structure to an lwIP native structure
|
||||
inline void in6_to_ip6(ip6_addr_t *ba, struct sockaddr_in6 *in6)
|
||||
{
|
||||
uint8_t *ip = &(in6->sin6_addr).s6_addr[0];
|
||||
IP6_ADDR2(ba,
|
||||
(((ip[ 0] & 0xffff) << 8) | ((ip[ 1]) & 0xffff)),
|
||||
(((ip[ 2] & 0xffff) << 8) | ((ip[ 3]) & 0xffff)),
|
||||
(((ip[ 4] & 0xffff) << 8) | ((ip[ 5]) & 0xffff)),
|
||||
(((ip[ 6] & 0xffff) << 8) | ((ip[ 7]) & 0xffff)),
|
||||
(((ip[ 8] & 0xffff) << 8) | ((ip[ 9]) & 0xffff)),
|
||||
(((ip[10] & 0xffff) << 8) | ((ip[11]) & 0xffff)),
|
||||
(((ip[12] & 0xffff) << 8) | ((ip[13]) & 0xffff)),
|
||||
(((ip[14] & 0xffff) << 8) | ((ip[15]) & 0xffff))
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(STACK_LWIP) && defined(LIBZT_IPV4)
|
||||
|
||||
#include "lwip/ip_addr.h"
|
||||
|
||||
198
src/libzt.cpp
198
src/libzt.cpp
@@ -74,9 +74,10 @@ for applications to use. See also: include/libzt.h */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static ZeroTier::OneService *zt1Service;
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
static ZeroTier::OneService *zt1Service;
|
||||
|
||||
std::string homeDir; // Platform-specific dir we *must* use internally
|
||||
std::string netDir; // Where network .conf files are to be written
|
||||
|
||||
@@ -98,7 +99,7 @@ namespace ZeroTier {
|
||||
std::map<int, std::pair<Connection*,SocketTap*>*> fdmap;
|
||||
|
||||
/*
|
||||
*
|
||||
* Virtual tap interfaces, one per virtual network
|
||||
*/
|
||||
std::vector<void*> vtaps;
|
||||
|
||||
@@ -113,7 +114,7 @@ namespace ZeroTier {
|
||||
|
||||
void zts_start(const char *path)
|
||||
{
|
||||
if(zt1Service)
|
||||
if(ZeroTier::zt1Service)
|
||||
return;
|
||||
#if defined(STACK_PICO)
|
||||
if(ZeroTier::picostack)
|
||||
@@ -142,15 +143,15 @@ void zts_simple_start(const char *path, const char *nwid)
|
||||
}
|
||||
|
||||
void zts_stop() {
|
||||
if(zt1Service) {
|
||||
zt1Service->terminate();
|
||||
if(ZeroTier::zt1Service) {
|
||||
ZeroTier::zt1Service->terminate();
|
||||
dismantleTaps();
|
||||
}
|
||||
}
|
||||
|
||||
void zts_join(const char * nwid) {
|
||||
if(zt1Service) {
|
||||
std::string confFile = zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
|
||||
if(ZeroTier::zt1Service) {
|
||||
std::string confFile = ZeroTier::zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
|
||||
if(!ZeroTier::OSUtils::mkdir(ZeroTier::netDir)) {
|
||||
DEBUG_ERROR("unable to create: %s", ZeroTier::netDir.c_str());
|
||||
handle_general_failure();
|
||||
@@ -159,7 +160,13 @@ void zts_join(const char * nwid) {
|
||||
DEBUG_ERROR("unable to write network conf file: %s", confFile.c_str());
|
||||
handle_general_failure();
|
||||
}
|
||||
zt1Service->join(nwid);
|
||||
ZeroTier::zt1Service->join(nwid);
|
||||
}
|
||||
// provide ZTO service reference to virtual taps
|
||||
// TODO: This might prove to be unreliable, but it works for now
|
||||
for(int i=0;i<ZeroTier::vtaps.size(); i++) {
|
||||
ZeroTier::SocketTap *s = (ZeroTier::SocketTap*)ZeroTier::vtaps[i];
|
||||
s->zt1ServiceRef=(void*)ZeroTier::zt1Service;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,8 +186,8 @@ void zts_join_soft(const char * filepath, const char * nwid) {
|
||||
}
|
||||
|
||||
void zts_leave(const char * nwid) {
|
||||
if(zt1Service)
|
||||
zt1Service->leave(nwid);
|
||||
if(ZeroTier::zt1Service)
|
||||
ZeroTier::zt1Service->leave(nwid);
|
||||
}
|
||||
|
||||
void zts_leave_soft(const char * filepath, const char * nwid) {
|
||||
@@ -206,9 +213,9 @@ void zts_lib_version(char *ver) {
|
||||
}
|
||||
|
||||
int zts_get_device_id(char *devID) {
|
||||
if(zt1Service) {
|
||||
if(ZeroTier::zt1Service) {
|
||||
char id[ZT_ID_LEN+1];
|
||||
sprintf(id, "%lx",zt1Service->getNode()->address());
|
||||
sprintf(id, "%lx",ZeroTier::zt1Service->getNode()->address());
|
||||
memcpy(devID, id, ZT_ID_LEN+1);
|
||||
return 0;
|
||||
}
|
||||
@@ -228,7 +235,7 @@ int zts_get_device_id(char *devID) {
|
||||
}
|
||||
|
||||
int zts_running() {
|
||||
return !zt1Service ? false : zt1Service->isRunning();
|
||||
return !ZeroTier::zt1Service ? false : ZeroTier::zt1Service->isRunning();
|
||||
}
|
||||
|
||||
int zts_has_ipv4_address(const char *nwid)
|
||||
@@ -254,7 +261,7 @@ int zts_has_address(const char *nwid)
|
||||
|
||||
void zts_get_ipv4_address(const char *nwid, char *addrstr, const int addrlen)
|
||||
{
|
||||
if(zt1Service) {
|
||||
if(ZeroTier::zt1Service) {
|
||||
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||
ZeroTier::SocketTap *tap = getTapByNWID(nwid_int);
|
||||
if(tap && tap->_ips.size()){
|
||||
@@ -276,7 +283,7 @@ void zts_get_ipv4_address(const char *nwid, char *addrstr, const int addrlen)
|
||||
|
||||
void zts_get_ipv6_address(const char *nwid, char *addrstr, const int addrlen)
|
||||
{
|
||||
if(zt1Service) {
|
||||
if(ZeroTier::zt1Service) {
|
||||
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||
ZeroTier::SocketTap *tap = getTapByNWID(nwid_int);
|
||||
if(tap && tap->_ips.size()){
|
||||
@@ -313,15 +320,15 @@ void zts_get_rfc4193_addr(char *addr, const char *nwid, const char *devID)
|
||||
}
|
||||
|
||||
unsigned long zts_get_peer_count() {
|
||||
if(zt1Service)
|
||||
return zt1Service->getNode()->peers()->peerCount;
|
||||
if(ZeroTier::zt1Service)
|
||||
return ZeroTier::zt1Service->getNode()->peers()->peerCount;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zts_get_peer_address(char *peer, const char *devID) {
|
||||
if(zt1Service) {
|
||||
ZT_PeerList *pl = zt1Service->getNode()->peers();
|
||||
if(ZeroTier::zt1Service) {
|
||||
ZT_PeerList *pl = ZeroTier::zt1Service->getNode()->peers();
|
||||
// uint64_t addr;
|
||||
for(int i=0; i<pl->peerCount; i++) {
|
||||
// ZT_Peer *p = &(pl->peers[i]);
|
||||
@@ -374,7 +381,7 @@ int zts_socket(ZT_SOCKET_SIG) {
|
||||
return -1;
|
||||
}
|
||||
int err = 0;
|
||||
if(!zt1Service) {
|
||||
if(!ZeroTier::zt1Service) {
|
||||
DEBUG_ERROR("cannot create socket, no service running. call zts_start() first.");
|
||||
errno = EMFILE; // could also be ENFILE
|
||||
return -1;
|
||||
@@ -417,7 +424,6 @@ int zts_socket(ZT_SOCKET_SIG) {
|
||||
|
||||
#if defined(STACK_LWIP)
|
||||
// TODO: check for max lwIP timers/sockets
|
||||
ZeroTier::Connection *conn = new ZeroTier::Connection();
|
||||
void *pcb;
|
||||
err = ZeroTier::lwipstack->lwip_Socket(&pcb, socket_family, socket_type, protocol);
|
||||
if(pcb) {
|
||||
@@ -493,15 +499,14 @@ Linux:
|
||||
|
||||
*/
|
||||
int zts_connect(ZT_CONNECT_SIG) {
|
||||
#if defined(STACK_PICO)
|
||||
//DEBUG_INFO("fd = %d", fd);
|
||||
DEBUG_INFO("fd = %d", fd);
|
||||
int err = 0;
|
||||
if(fd < 0) {
|
||||
errno = EBADF;
|
||||
DEBUG_ERROR("EBADF");
|
||||
return -1;
|
||||
}
|
||||
if(!zt1Service) {
|
||||
if(!ZeroTier::zt1Service) {
|
||||
DEBUG_ERROR("Service not started. Call zts_start(path) first");
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
@@ -539,9 +544,13 @@ int zts_connect(ZT_CONNECT_SIG) {
|
||||
err = -1;
|
||||
}
|
||||
else {
|
||||
#if defined(STACK_PICO)
|
||||
// pointer to tap we use in callbacks from the stack
|
||||
conn->picosock->priv = new ZeroTier::ConnectionPair(tap, conn);
|
||||
err = tap->Connect(conn, fd, addr, addrlen);
|
||||
#endif
|
||||
#if defined(STACK_LWIP)
|
||||
#endif
|
||||
err = tap->Connect(conn, addr, addrlen);
|
||||
if(err == 0) {
|
||||
tap->_Connections.push_back(conn); // Give this Connection to the tap we decided on
|
||||
conn->tap = tap;
|
||||
@@ -549,7 +558,6 @@ int zts_connect(ZT_CONNECT_SIG) {
|
||||
// Wrap the socketpair we created earlier
|
||||
// For I/O loop participation and referencing the PhySocket's parent Connection in callbacks
|
||||
conn->sock = tap->_phy.wrapSocket(conn->sdk_fd, conn);
|
||||
//DEBUG_ERROR("sock->fd = %d", tap->_phy.getDescriptor(conn->sock));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -575,7 +583,6 @@ int zts_connect(ZT_CONNECT_SIG) {
|
||||
else {
|
||||
blocking = !(f_err & O_NONBLOCK);
|
||||
}
|
||||
|
||||
// non-blocking
|
||||
if(err == 0 && !blocking) {
|
||||
DEBUG_EXTRA("EINPROGRESS, not a real error, assuming non-blocking mode");
|
||||
@@ -596,11 +603,15 @@ int zts_connect(ZT_CONNECT_SIG) {
|
||||
tap->_tcpconns_m.lock();
|
||||
for(int i=0; i<tap->_Connections.size(); i++)
|
||||
{
|
||||
#if defined(STACK_PICO)
|
||||
if(tap->_Connections[i]->state == PICO_ERR_ECONNRESET) {
|
||||
errno = ECONNRESET;
|
||||
DEBUG_ERROR("ECONNRESET");
|
||||
err = -1;
|
||||
}
|
||||
#endif
|
||||
#if defined(STACK_LWIP)
|
||||
#endif
|
||||
if(tap->_Connections[i]->state == ZT_SOCK_STATE_UNHANDLED_CONNECTED) {
|
||||
tap->_Connections[i]->state = ZT_SOCK_STATE_CONNECTED;
|
||||
errno = 0;
|
||||
@@ -615,8 +626,6 @@ int zts_connect(ZT_CONNECT_SIG) {
|
||||
}
|
||||
}
|
||||
return err;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -640,7 +649,7 @@ int zts_bind(ZT_BIND_SIG) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if(!zt1Service) {
|
||||
if(!ZeroTier::zt1Service) {
|
||||
DEBUG_ERROR("Service not started. Call zts_start(path) first");
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
@@ -677,7 +686,7 @@ int zts_bind(ZT_BIND_SIG) {
|
||||
else {
|
||||
conn->picosock->priv = new ZeroTier::ConnectionPair(tap, conn);
|
||||
tap->_Connections.push_back(conn); // Give this Connection to the tap we decided on
|
||||
err = tap->Bind(conn, fd, addr, addrlen);
|
||||
err = tap->Bind(conn, addr, addrlen);
|
||||
conn->tap = tap;
|
||||
if(err == 0) { // success
|
||||
ZeroTier::unmap.erase(fd);
|
||||
@@ -688,7 +697,7 @@ int zts_bind(ZT_BIND_SIG) {
|
||||
#if defined(STACK_LWIP)
|
||||
else {
|
||||
tap->_Connections.push_back(conn);
|
||||
err = tap->Bind(conn, fd, addr, addrlen);
|
||||
err = tap->Bind(conn, addr, addrlen);
|
||||
conn->tap = tap;
|
||||
if(err == 0) { // success
|
||||
ZeroTier::unmap.erase(fd);
|
||||
@@ -731,7 +740,7 @@ int zts_listen(ZT_LISTEN_SIG) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if(!zt1Service) {
|
||||
if(!ZeroTier::zt1Service) {
|
||||
DEBUG_ERROR("service not started. call zts_start(path) first");
|
||||
errno = EACCES;
|
||||
return -1;
|
||||
@@ -752,7 +761,7 @@ int zts_listen(ZT_LISTEN_SIG) {
|
||||
}
|
||||
if(!err) {
|
||||
backlog = backlog > 128 ? 128 : backlog; // See: /proc/sys/net/core/somaxconn
|
||||
err = tap->Listen(conn, fd, backlog);
|
||||
err = tap->Listen(conn, backlog);
|
||||
conn->state = ZT_SOCK_STATE_LISTENING;
|
||||
ZeroTier::_multiplexer_lock.unlock();
|
||||
}
|
||||
@@ -998,7 +1007,7 @@ int zts_close(ZT_CLOSE_SIG)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!zt1Service) {
|
||||
if(!ZeroTier::zt1Service) {
|
||||
DEBUG_ERROR("cannot close socket. service not started. call zts_start(path) first");
|
||||
errno = EBADF;
|
||||
err = -1;
|
||||
@@ -1221,29 +1230,64 @@ ssize_t zts_sendto(ZT_SENDTO_SIG)
|
||||
err = -1;
|
||||
}
|
||||
else {
|
||||
struct sockaddr_ll *socket_address = (struct sockaddr_ll *)addr;
|
||||
ZeroTier::SocketTap *tap = getTapByIndex(socket_address->sll_ifindex);
|
||||
if(tap)
|
||||
{
|
||||
DEBUG_INFO("found interface of ifindex=%d", tap->ifindex);
|
||||
ZeroTier::Connection *conn = ZeroTier::unmap[fd];
|
||||
if(conn) {
|
||||
DEBUG_INFO("located connection object for fd=%d", fd);
|
||||
err = tap->Write(conn, (void*)buf, len);
|
||||
ZeroTier::Connection *conn = ZeroTier::unmap[fd];
|
||||
ZeroTier::InetAddress iaddr;
|
||||
ZeroTier::SocketTap *tap;
|
||||
char ipstr[INET6_ADDRSTRLEN];
|
||||
int port;
|
||||
memset(ipstr, 0, INET6_ADDRSTRLEN);
|
||||
|
||||
if(conn->socket_type == SOCK_DGRAM) {
|
||||
if(conn->socket_family == AF_INET) {
|
||||
inet_ntop(AF_INET,
|
||||
(const void *)&((struct sockaddr_in *)addr)->sin_addr.s_addr, ipstr, INET_ADDRSTRLEN);
|
||||
iaddr.fromString(ipstr);
|
||||
port = ((struct sockaddr_in*)addr)->sin_port;
|
||||
}
|
||||
if(conn->socket_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6,
|
||||
(const void *)&((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, ipstr, INET6_ADDRSTRLEN);
|
||||
// TODO: This is a hack, determine a proper way to do this
|
||||
char addrstr[64];
|
||||
sprintf(addrstr, "%s%s", ipstr, std::string("/88").c_str());
|
||||
iaddr.fromString(addrstr);
|
||||
port = ((struct sockaddr_in6*)addr)->sin6_port;
|
||||
}
|
||||
tap = getTapByAddr(iaddr);
|
||||
if(tap) {
|
||||
tap->SendTo(conn, buf, len, flags, addr, addrlen);
|
||||
}
|
||||
else {
|
||||
DEBUG_ERROR("unable to locate connection object for fd=%d", fd);
|
||||
DEBUG_INFO("SOCK_DGRAM, tap not found");
|
||||
errno = EDESTADDRREQ; // TODO: double check this is the best errno to report
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(conn->socket_type == SOCK_RAW)
|
||||
{
|
||||
struct sockaddr_ll *socket_address = (struct sockaddr_ll *)addr;
|
||||
ZeroTier::SocketTap *tap = getTapByIndex(socket_address->sll_ifindex);
|
||||
if(tap)
|
||||
{
|
||||
DEBUG_INFO("found interface of ifindex=%d", tap->ifindex);
|
||||
if(conn) {
|
||||
DEBUG_INFO("located connection object for fd=%d", fd);
|
||||
err = tap->Write(conn, (void*)buf, len);
|
||||
}
|
||||
else {
|
||||
DEBUG_ERROR("unable to locate connection object for fd=%d", fd);
|
||||
err = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_ERROR("unable to locate tap of ifindex=%d", socket_address->sll_ifindex);
|
||||
err = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
//err = sendto(fd, buf, len, flags, addr, addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_ERROR("unable to locate tap of ifindex=%d", socket_address->sll_ifindex);
|
||||
err = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
//err = sendto(fd, buf, len, flags, addr, addrlen);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@@ -1319,7 +1363,7 @@ int zts_shutdown(ZT_SHUTDOWN_SIG)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!zt1Service) {
|
||||
if(!ZeroTier::zt1Service) {
|
||||
DEBUG_ERROR("cannot shutdown socket. service not started. call zts_start(path) first");
|
||||
errno = EBADF;
|
||||
err = -1;
|
||||
@@ -1406,7 +1450,7 @@ namespace ZeroTier {
|
||||
}
|
||||
// Shuts down ZeroTier service and SOCKS5 Proxy server
|
||||
JNIEXPORT void JNICALL Java_zerotier_ZeroTier_ztjni_1stop(JNIEnv *env, jobject thisObj) {
|
||||
if(zt1Service)
|
||||
if(ZeroTier::zt1Service)
|
||||
zts_stop();
|
||||
}
|
||||
|
||||
@@ -1652,7 +1696,7 @@ namespace ZeroTier {
|
||||
int zts_get_pico_socket(int fd, struct pico_socket **s)
|
||||
{
|
||||
int err = 0;
|
||||
if(!zt1Service) {
|
||||
if(!ZeroTier::zt1Service) {
|
||||
DEBUG_ERROR("cannot locate socket. service not started. call zts_start(path) first");
|
||||
errno = EBADF;
|
||||
err = -1;
|
||||
@@ -1700,6 +1744,7 @@ bool can_provision_new_socket()
|
||||
// TODO: Add check here (see lwipopts.h)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
int zts_nsockets()
|
||||
@@ -1723,6 +1768,12 @@ int zts_maxsockets()
|
||||
/* ZeroTier Core helper functions for libzt - DON'T CALL THESE DIRECTLY */
|
||||
/****************************************************************************/
|
||||
|
||||
std::vector<ZT_VirtualNetworkRoute> *zts_get_network_routes(char *nwid)
|
||||
{
|
||||
uint64_t nwid_int = strtoull(nwid, NULL, 16);
|
||||
return ZeroTier::zt1Service->getRoutes(nwid_int);
|
||||
}
|
||||
|
||||
ZeroTier::SocketTap *getTapByNWID(uint64_t nwid)
|
||||
{
|
||||
ZeroTier::_vtaps_lock.lock();
|
||||
@@ -1739,14 +1790,33 @@ ZeroTier::SocketTap *getTapByAddr(ZeroTier::InetAddress &addr)
|
||||
{
|
||||
ZeroTier::_vtaps_lock.lock();
|
||||
ZeroTier::SocketTap *s, *tap = nullptr;
|
||||
char ipbuf[64], ipbuf2[64], ipbuf3[64];
|
||||
for(int i=0; i<ZeroTier::vtaps.size(); i++) {
|
||||
s = (ZeroTier::SocketTap*)ZeroTier::vtaps[i];
|
||||
// check address schemes
|
||||
for(int j=0; j<s->_ips.size(); j++) {
|
||||
if(s->_ips[j].isEqualPrefix(addr)
|
||||
|| s->_ips[j].ipsEqual(addr)
|
||||
|| s->_ips[j].containsAddress(addr))
|
||||
{
|
||||
DEBUG_INFO("chose tap <addr=%s>", s->_ips[j].toString(ipbuf));
|
||||
tap = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// check managed routes
|
||||
if(!tap) {
|
||||
std::vector<ZT_VirtualNetworkRoute> *managed_routes = ZeroTier::zt1Service->getRoutes(s->_nwid);
|
||||
ZeroTier::InetAddress target, nm, via;
|
||||
for(int i=0; i<managed_routes->size(); i++){
|
||||
target = managed_routes->at(i).target;
|
||||
nm = target.netmask();
|
||||
via = managed_routes->at(i).via;
|
||||
if(target.containsAddress(addr)) {
|
||||
DEBUG_INFO("chose tap with route <target=%s, nm=%s, via=%s>", target.toString(ipbuf), nm.toString(ipbuf2), via.toString(ipbuf3));
|
||||
tap = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1797,7 +1867,7 @@ void *zts_start_service(void *thread_id) {
|
||||
DEBUG_INFO("homeDir=%s", ZeroTier::homeDir.c_str());
|
||||
// Where network .conf files will be stored
|
||||
ZeroTier::netDir = ZeroTier::homeDir + "/networks.d";
|
||||
zt1Service = (ZeroTier::OneService *)0;
|
||||
ZeroTier::zt1Service = (ZeroTier::OneService *)0;
|
||||
|
||||
// Construct path for network config and supporting service files
|
||||
if (ZeroTier::homeDir.length()) {
|
||||
@@ -1832,17 +1902,17 @@ void *zts_start_service(void *thread_id) {
|
||||
int servicePort = 9000 + (randp % 1000);
|
||||
|
||||
for(;;) {
|
||||
zt1Service = ZeroTier::OneService::newInstance(ZeroTier::homeDir.c_str(),servicePort);
|
||||
switch(zt1Service->run()) {
|
||||
ZeroTier::zt1Service = ZeroTier::OneService::newInstance(ZeroTier::homeDir.c_str(),servicePort);
|
||||
switch(ZeroTier::zt1Service->run()) {
|
||||
case ZeroTier::OneService::ONE_STILL_RUNNING:
|
||||
case ZeroTier::OneService::ONE_NORMAL_TERMINATION:
|
||||
break;
|
||||
case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR:
|
||||
DEBUG_ERROR("fatal error: %s",zt1Service->fatalErrorMessage().c_str());
|
||||
DEBUG_ERROR("fatal error: %s",ZeroTier::zt1Service->fatalErrorMessage().c_str());
|
||||
break;
|
||||
case ZeroTier::OneService::ONE_IDENTITY_COLLISION: {
|
||||
delete zt1Service;
|
||||
zt1Service = (ZeroTier::OneService *)0;
|
||||
delete ZeroTier::zt1Service;
|
||||
ZeroTier::zt1Service = (ZeroTier::OneService *)0;
|
||||
std::string oldid;
|
||||
ZeroTier::OSUtils::readFile((ZeroTier::homeDir + ZT_PATH_SEPARATOR_S
|
||||
+ "identity.secret").c_str(),oldid);
|
||||
@@ -1859,8 +1929,8 @@ void *zts_start_service(void *thread_id) {
|
||||
}
|
||||
break; // terminate loop -- normally we don't keep restarting
|
||||
}
|
||||
delete zt1Service;
|
||||
zt1Service = (ZeroTier::OneService *)0;
|
||||
delete ZeroTier::zt1Service;
|
||||
ZeroTier::zt1Service = (ZeroTier::OneService *)0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
109
src/lwIP.cpp
109
src/lwIP.cpp
@@ -36,6 +36,13 @@
|
||||
#include "netif/ethernet.h"
|
||||
#include "lwip/etharp.h"
|
||||
|
||||
#if defined(LIBZT_IPV6)
|
||||
#include "lwip/ethip6.h"
|
||||
#include "lwip/nd6.h"
|
||||
#endif
|
||||
|
||||
void nd6_tmr(void);
|
||||
|
||||
err_t tapif_init(struct netif *netif)
|
||||
{
|
||||
DEBUG_INFO();
|
||||
@@ -82,6 +89,7 @@ namespace ZeroTier
|
||||
if (std::find(tap->_ips.begin(),tap->_ips.end(),ip) == tap->_ips.end()) {
|
||||
tap->_ips.push_back(ip);
|
||||
std::sort(tap->_ips.begin(),tap->_ips.end());
|
||||
char ipbuf[64], nmbuf[64];
|
||||
#if defined(LIBZT_IPV4)
|
||||
if (ip.isV4()) {
|
||||
// Set IP
|
||||
@@ -101,13 +109,11 @@ namespace ZeroTier
|
||||
tap->lwipdev.flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
|
||||
netif_set_default(&(tap->lwipdev));
|
||||
netif_set_up(&(tap->lwipdev));
|
||||
char ipbuf[64];
|
||||
DEBUG_INFO("addr=%s, netmask=%s", ip.toString(ipbuf), ip.netmask().toString(ipbuf));
|
||||
DEBUG_INFO("addr=%s, netmask=%s", ip.toString(ipbuf), ip.netmask().toString(nmbuf));
|
||||
}
|
||||
#endif
|
||||
#if defined(LIBZT_IPV6)
|
||||
if(ip.isV6()) {
|
||||
DEBUG_INFO("local_addr=%s", ip.toString().c_str());
|
||||
static ip6_addr_t addr6;
|
||||
struct sockaddr_in6 in6;
|
||||
memcpy(in6.sin6_addr.s6_addr,ip.rawIpData(),16);
|
||||
@@ -128,8 +134,7 @@ namespace ZeroTier
|
||||
tap->lwipdev6.output_ip6 = ethip6_output;
|
||||
tap->lwipdev6.state = tap;
|
||||
tap->lwipdev6.flags = NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
|
||||
char ipbuf[64];
|
||||
DEBUG_INFO("addr=%s, netmask=%s", ip.toString(ipbuf), ip.netmask().toString(ipbuf));
|
||||
DEBUG_INFO("addr=%s, netmask=%s", ip.toString(ipbuf), ip.netmask().toString(nmbuf));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -138,13 +143,12 @@ namespace ZeroTier
|
||||
void lwIP::lwip_loop(SocketTap *tap)
|
||||
{
|
||||
DEBUG_INFO();
|
||||
uint64_t prev_tcp_time = 0, prev_status_time = 0, prev_discovery_time = 0;
|
||||
uint64_t prev_tcp_time = 0, prev_discovery_time = 0;
|
||||
while(tap->_run)
|
||||
{
|
||||
uint64_t now = OSUtils::now();
|
||||
uint64_t since_tcp = now - prev_tcp_time;
|
||||
uint64_t since_discovery = now - prev_discovery_time;
|
||||
uint64_t since_status = now - prev_status_time;
|
||||
uint64_t tcp_remaining = LWIP_TCP_TIMER_INTERVAL;
|
||||
uint64_t discovery_remaining = 5000;
|
||||
|
||||
@@ -173,6 +177,7 @@ namespace ZeroTier
|
||||
discovery_remaining = DISCOVERY_INTERVAL - since_discovery;
|
||||
}
|
||||
tap->_phy.poll((unsigned long)std::min(tcp_remaining,discovery_remaining));
|
||||
tap->Housekeeping();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +249,7 @@ namespace ZeroTier
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lwIP::lwip_Connect(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
int lwIP::lwip_Connect(Connection *conn, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
DEBUG_INFO();
|
||||
ip_addr_t ba;
|
||||
@@ -252,9 +257,8 @@ namespace ZeroTier
|
||||
int port = 0, err = 0;
|
||||
|
||||
#if defined(LIBZT_IPV4)
|
||||
struct sockaddr_in *in4;
|
||||
struct sockaddr_in *in4 = (struct sockaddr_in *)addr;
|
||||
if(addr->sa_family == AF_INET) {
|
||||
in4 = (struct sockaddr_in *)addr;
|
||||
inet_ntop(AF_INET, &(in4->sin_addr), addrstr, INET_ADDRSTRLEN);
|
||||
DEBUG_INFO("%s:%d", addrstr, lwip_ntohs(in4->sin_port));
|
||||
}
|
||||
@@ -336,9 +340,10 @@ namespace ZeroTier
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int lwIP::lwip_Bind(SocketTap *tap, Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
int lwIP::lwip_Bind(SocketTap *tap, Connection *conn, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
DEBUG_INFO();
|
||||
ip_addr_t ba;
|
||||
@@ -346,9 +351,8 @@ namespace ZeroTier
|
||||
int port = 0, err = 0;
|
||||
|
||||
#if defined(LIBZT_IPV4)
|
||||
struct sockaddr_in *in4;
|
||||
struct sockaddr_in *in4 = (struct sockaddr_in *)addr;
|
||||
if(addr->sa_family == AF_INET) {
|
||||
in4 = (struct sockaddr_in *)addr;
|
||||
inet_ntop(AF_INET, &(in4->sin_addr), addrstr, INET_ADDRSTRLEN);
|
||||
DEBUG_INFO("%s:%d", addrstr, lwip_ntohs(in4->sin_port));
|
||||
}
|
||||
@@ -422,7 +426,6 @@ namespace ZeroTier
|
||||
|
||||
Connection* lwIP::lwip_Accept(Connection *conn)
|
||||
{
|
||||
DEBUG_EXTRA("conn=%p", conn);
|
||||
if(!conn) {
|
||||
DEBUG_ERROR("invalid conn");
|
||||
handle_general_failure();
|
||||
@@ -430,9 +433,7 @@ namespace ZeroTier
|
||||
}
|
||||
// Retreive first of queued Connections from parent connection
|
||||
Connection *new_conn = NULL;
|
||||
DEBUG_INFO("locking...");
|
||||
Mutex::Lock _l(conn->tap->_tcpconns_m);
|
||||
DEBUG_INFO("locked.");
|
||||
if(conn->_AcceptedConnections.size()) {
|
||||
new_conn = conn->_AcceptedConnections.front();
|
||||
conn->_AcceptedConnections.pop();
|
||||
@@ -443,6 +444,7 @@ namespace ZeroTier
|
||||
int lwIP::lwip_Read(Connection *conn, bool lwip_invoked)
|
||||
{
|
||||
DEBUG_EXTRA("conn=%p", conn);
|
||||
int err = 0;
|
||||
if(!conn) {
|
||||
DEBUG_ERROR("no connection");
|
||||
return -1;
|
||||
@@ -458,49 +460,39 @@ namespace ZeroTier
|
||||
int n = conn->tap->_phy.streamSend(conn->sock, conn->RXbuf->get_buf(), wr);
|
||||
char str[22];
|
||||
memcpy(str, conn->RXbuf->get_buf(), 22);
|
||||
DEBUG_INFO("string = %s", str);
|
||||
DEBUG_INFO("n =%d", n);
|
||||
conn->RXbuf->consume(n);
|
||||
|
||||
//if(n == max)
|
||||
//{
|
||||
//if(conn->socket_type == SOCK_DGRAM){
|
||||
// conn->tap->_phy.setNotifyWritable(conn->sock, false);
|
||||
//}
|
||||
if(conn->socket_type == SOCK_DGRAM)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
if(conn->socket_type == SOCK_STREAM) { // Only acknolwedge receipt of TCP packets
|
||||
tcp_recved((struct tcp_pcb*)conn->pcb, n);
|
||||
DEBUG_TRANS("TCP RX %ld bytes", n);
|
||||
DEBUG_TRANS("TCP RX %d bytes", n);
|
||||
}
|
||||
//}
|
||||
}
|
||||
if(conn->RXbuf->count() == 0) {
|
||||
DEBUG_INFO("wrote everything");
|
||||
conn->tap->_phy.setNotifyWritable(conn->sock, false); // nothing else to send to the app
|
||||
}
|
||||
if(!lwip_invoked) {
|
||||
DEBUG_INFO("unlocking...");
|
||||
conn->tap->_tcpconns_m.unlock();
|
||||
conn->_rx_m.unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
int payload_sz, addr_sz_offset = sizeof(struct sockaddr_storage);
|
||||
memcpy(&payload_sz, conn->rxbuf + addr_sz_offset, sizeof(int)); // OPT:
|
||||
// extract address
|
||||
struct sockaddr_storage addr;
|
||||
memcpy(&addr, conn->rxbuf, addr_sz_offset);
|
||||
*/
|
||||
return err;
|
||||
}
|
||||
|
||||
int lwIP::lwip_Write(Connection *conn, void *data, ssize_t len)
|
||||
{
|
||||
DEBUG_EXTRA("conn=%p", (void*)&conn);
|
||||
DEBUG_EXTRA("conn=%p, len=%d", (void*)&conn, len);
|
||||
int err = 0;
|
||||
if(!conn) {
|
||||
DEBUG_ERROR("no connection");
|
||||
return -1;
|
||||
}
|
||||
if(conn->socket_type == SOCK_DGRAM)
|
||||
{
|
||||
DEBUG_ERROR("socket_type==SOCK_DGRAM");
|
||||
// TODO: Packet re-assembly hasn't yet been tested with lwIP so UDP packets are limited to MTU-sized chunks
|
||||
int udp_trans_len = std::min((ssize_t)conn->TXbuf->count(), (ssize_t)ZT_MAX_MTU);
|
||||
DEBUG_EXTRA("allocating pbuf chain of size=%d for UDP packet, txsz=%d", udp_trans_len, conn->TXbuf->count());
|
||||
@@ -526,24 +518,27 @@ namespace ZeroTier
|
||||
}
|
||||
if(conn->socket_type == SOCK_STREAM)
|
||||
{
|
||||
DEBUG_ERROR("socket_type==SOCK_STREAM");
|
||||
// How much we are currently allowed to write to the connection
|
||||
ssize_t sndbuf = ((struct tcp_pcb*)conn->pcb)->snd_buf;
|
||||
int err, sz, r;
|
||||
|
||||
int err, r;
|
||||
if(!sndbuf) {
|
||||
// PCB send buffer is full, turn off readability notifications for the
|
||||
// corresponding PhySocket until nc_sent() is called and confirms that there is
|
||||
// now space on the buffer
|
||||
DEBUG_ERROR(" LWIP stack is full, sndbuf == 0");
|
||||
DEBUG_ERROR("lwIP stack is full, sndbuf == 0");
|
||||
conn->tap->_phy.setNotifyReadable(conn->sock, false);
|
||||
return -1;
|
||||
}
|
||||
if(conn->TXbuf->count() <= 0)
|
||||
return -1; // Nothing to write
|
||||
|
||||
//if(!conn->listening)
|
||||
// tcp_output(conn->TCP_pcb);
|
||||
|
||||
int buf_w = conn->TXbuf->write((const unsigned char*)data, len);
|
||||
if (buf_w != len) {
|
||||
// because we checked ZT_TCP_TX_BUF_SZ above, this should not happen
|
||||
DEBUG_ERROR("TX wrote only %d but expected to write %d", buf_w, len);
|
||||
exit(0);
|
||||
}
|
||||
if(conn->TXbuf->count() <= 0) {
|
||||
return -1; // nothing to write
|
||||
}
|
||||
if(conn->sock) {
|
||||
r = std::min((ssize_t)conn->TXbuf->count(), sndbuf);
|
||||
// Writes data pulled from the client's socket buffer to LWIP. This merely sends the
|
||||
@@ -552,9 +547,9 @@ namespace ZeroTier
|
||||
err = tcp_write((struct tcp_pcb*)conn->pcb, conn->TXbuf->get_buf(), r, TCP_WRITE_FLAG_COPY);
|
||||
tcp_output((struct tcp_pcb*)conn->pcb);
|
||||
if(err != ERR_OK) {
|
||||
DEBUG_ERROR(" error while writing to PCB, err=%d", err);
|
||||
DEBUG_ERROR("error while writing to lwIP tcp_pcb, err=%d", err);
|
||||
if(err == -1)
|
||||
DEBUG_ERROR("out of memory");
|
||||
DEBUG_ERROR("lwIP out of memory");
|
||||
return -1;
|
||||
} else {
|
||||
conn->TXbuf->consume(r); // success
|
||||
@@ -563,6 +558,7 @@ namespace ZeroTier
|
||||
}
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int lwIP::lwip_Close(Connection *conn)
|
||||
@@ -580,7 +576,6 @@ namespace ZeroTier
|
||||
DEBUG_EXTRA("ignoring close request. invalid PCB state for this operation. sock=%p", conn->sock);
|
||||
return -1;
|
||||
}
|
||||
// DEBUG_BLANK("__tcp_close(...)");
|
||||
struct tcp_pcb* tpcb = (struct tcp_pcb*)conn->pcb;
|
||||
if(tcp_close(tpcb) == ERR_OK) {
|
||||
// Unregister callbacks for this PCB
|
||||
@@ -614,14 +609,9 @@ namespace ZeroTier
|
||||
|
||||
//Mutex::Lock _l(conn->tap->_tcpconns_m);
|
||||
//Mutex::Lock _l2(conn->_rx_m);
|
||||
|
||||
DEBUG_INFO("locking...");
|
||||
|
||||
conn->tap->_tcpconns_m.lock();
|
||||
conn->_rx_m.lock();
|
||||
|
||||
DEBUG_INFO("locked.");
|
||||
|
||||
struct pbuf* q = p;
|
||||
if(p == NULL) {
|
||||
if(((struct tcp_pcb*)conn->pcb)->state == CLOSE_WAIT) {
|
||||
@@ -725,14 +715,13 @@ namespace ZeroTier
|
||||
{
|
||||
DEBUG_ERROR("err=%d", err);
|
||||
Connection *conn = (Connection *)arg;
|
||||
Mutex::Lock _l(conn->tap->_tcpconns_m);
|
||||
|
||||
if(!conn){
|
||||
DEBUG_ERROR("conn==NULL");
|
||||
errno = -1; // FIXME: Find more appropriate value
|
||||
}
|
||||
Mutex::Lock _l(conn->tap->_tcpconns_m);
|
||||
int fd = conn->tap->_phy.getDescriptor(conn->sock);
|
||||
DEBUG_ERROR("conn=%p, pcb=%p, err=%d", conn, conn->pcb, err);
|
||||
DEBUG_ERROR("conn=%p, pcb=%p, fd=%d, err=%d", conn, conn->pcb, fd, err);
|
||||
DEBUG_ERROR("closing connection");
|
||||
conn->tap->Close(conn);
|
||||
switch(err)
|
||||
@@ -781,19 +770,19 @@ namespace ZeroTier
|
||||
// TODO: Below are errors which don't have a standard errno correlate
|
||||
|
||||
case ERR_RST:
|
||||
//l->tap->sendReturnValue(fd, -1, -1);
|
||||
// -1
|
||||
break;
|
||||
case ERR_CLSD:
|
||||
//l->tap->sendReturnValue(fd, -1, -1);
|
||||
// -1
|
||||
break;
|
||||
case ERR_CONN:
|
||||
//l->tap->sendReturnValue(fd, -1, -1);
|
||||
// -1
|
||||
break;
|
||||
case ERR_ARG:
|
||||
//l->tap->sendReturnValue(fd, -1, -1);
|
||||
// -1
|
||||
break;
|
||||
case ERR_IF:
|
||||
//l->tap->sendReturnValue(fd, -1, -1);
|
||||
// -1
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -56,6 +56,7 @@ struct netif;
|
||||
#endif
|
||||
#if defined(LIBZT_IPV6)
|
||||
#include "lwip/ip6_addr.h"
|
||||
#include "ethip6.h"
|
||||
#define LWIP_NETIF_ADD_SIG struct netif *netif, void *state, netif_init_fn init, netif_input_fn input
|
||||
#define LWIP_ETHIP6_OUTPUT_SIG struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr
|
||||
#define LWIP_ETHARP_OUTPUT_SIG struct netif *netif, struct pbuf *q, const ip6_addr_t *ipaddr
|
||||
@@ -109,9 +110,9 @@ struct netif;
|
||||
#endif
|
||||
#if defined(LIBZT_IPV6)
|
||||
extern "C" void nd6_tmr(void);
|
||||
extern "C" void netif_ip6_addr_set_state(LWIP_NETIF_IP6_ADDR_SET_STATE_SIG);
|
||||
//extern "C" void netif_ip6_addr_set_state(LWIP_NETIF_IP6_ADDR_SET_STATE_SIG);
|
||||
extern "C" void netif_create_ip6_linklocal_address(LWIP_NETIF_CREATE_IP6_LINKLOCAL_ADDRESS_SIG);
|
||||
extern "C" err_t _ethip6_output(LWIP_ETHIP6_OUTPUT_SIG);
|
||||
extern "C" err_t ethip6_output(LWIP_ETHIP6_OUTPUT_SIG);
|
||||
#endif
|
||||
|
||||
extern "C" void lwip_init();
|
||||
@@ -185,8 +186,8 @@ namespace ZeroTier {
|
||||
void lwip_rx(SocketTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len);
|
||||
|
||||
int lwip_Socket(void **pcb, int socket_family, int socket_type, int protocol);
|
||||
int lwip_Connect(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int lwip_Bind(SocketTap *tap, Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int lwip_Connect(Connection *conn, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int lwip_Bind(SocketTap *tap, Connection *conn, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int lwip_Listen(Connection *conn, int backlog);
|
||||
Connection* lwip_Accept(Connection *conn);
|
||||
int lwip_Read(Connection *conn, bool lwip_invoked);
|
||||
|
||||
135
src/picoTCP.cpp
135
src/picoTCP.cpp
@@ -48,12 +48,12 @@
|
||||
#include "Constants.hpp"
|
||||
#include "Phy.hpp"
|
||||
|
||||
|
||||
int pico_ipv4_to_string(PICO_IPV4_TO_STRING_SIG);
|
||||
extern "C" int pico_stack_init(void);
|
||||
extern "C" void pico_stack_tick(void);
|
||||
|
||||
int pico_ipv4_to_string(PICO_IPV4_TO_STRING_SIG);
|
||||
extern "C" int pico_ipv4_link_add(PICO_IPV4_LINK_ADD_SIG);
|
||||
extern "C" int pico_ipv4_route_add(PICO_IPV4_ROUTE_ADD_SIG);
|
||||
extern "C" int pico_ipv4_route_del(PICO_IPV4_ROUTE_DEL_SIG);
|
||||
extern "C" int pico_device_init(PICO_DEVICE_INIT_SIG);
|
||||
extern "C" int pico_string_to_ipv4(PICO_STRING_TO_IPV4_SIG);
|
||||
extern "C" int pico_string_to_ipv6(PICO_STRING_TO_IPV6_SIG);
|
||||
@@ -131,6 +131,39 @@ namespace ZeroTier {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// pico_ipv6_route_add
|
||||
// pico_ipv6_route_del
|
||||
|
||||
bool picoTCP::pico_route_add(SocketTap *tap, const InetAddress &addr, const InetAddress &nm, const InetAddress &gw, int metric)
|
||||
{
|
||||
struct pico_ipv4_link *link = NULL;
|
||||
struct pico_ip4 address;
|
||||
address.addr = *((uint32_t *)addr.rawIpData());
|
||||
struct pico_ip4 netmask;
|
||||
netmask.addr = *((uint32_t *)nm.rawIpData());
|
||||
struct pico_ip4 gateway;
|
||||
gateway.addr = *((uint32_t *)gw.rawIpData());
|
||||
int err = pico_ipv4_route_add(address, netmask, gateway, metric, link);
|
||||
if(err) {
|
||||
DEBUG_ERROR("err=%d, %s", err, beautify_pico_error(pico_err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
bool picoTCP::pico_route_del(SocketTap *tap, const InetAddress &addr, const InetAddress &nm, int metric)
|
||||
{
|
||||
struct pico_ip4 address;
|
||||
address.addr = *((uint32_t *)addr.rawIpData());
|
||||
struct pico_ip4 netmask;
|
||||
netmask.addr = *((uint32_t *)nm.rawIpData());
|
||||
int err = pico_ipv4_route_del(address, netmask, metric);
|
||||
if(err) {
|
||||
DEBUG_ERROR("err=%d, %s", err, beautify_pico_error(pico_err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void picoTCP::pico_loop(SocketTap *tap)
|
||||
{
|
||||
@@ -138,7 +171,7 @@ namespace ZeroTier {
|
||||
{
|
||||
tap->_phy.poll(ZT_PHY_POLL_INTERVAL);
|
||||
pico_stack_tick();
|
||||
//tap->Housekeeping();
|
||||
tap->Housekeeping();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,7 +554,7 @@ namespace ZeroTier {
|
||||
protocol_version = PICO_PROTO_IPV6;
|
||||
|
||||
if(socket_type == SOCK_DGRAM) {
|
||||
DEBUG_ERROR("SOCK_DGRAM");
|
||||
DEBUG_INFO("SOCK_DGRAM");
|
||||
psock = pico_socket_open(
|
||||
protocol_version, PICO_PROTO_UDP, &ZeroTier::picoTCP::pico_cb_socket_activity);
|
||||
if(psock) { // configure size of UDP SND/RCV buffers
|
||||
@@ -555,7 +588,7 @@ namespace ZeroTier {
|
||||
return err;
|
||||
}
|
||||
|
||||
int picoTCP::pico_Connect(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
int picoTCP::pico_Connect(Connection *conn, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
if(!conn || !conn->picosock) {
|
||||
DEBUG_ERROR("invalid conn or conn->picosock");
|
||||
@@ -582,6 +615,9 @@ namespace ZeroTier {
|
||||
pico_string_to_ipv6(ipv6_str, zaddr.addr);
|
||||
err = pico_socket_connect(conn->picosock, &zaddr, in6->sin6_port);
|
||||
}
|
||||
if(err) {
|
||||
DEBUG_ERROR("err=%d, %s", err, beautify_pico_error(pico_err));
|
||||
}
|
||||
memcpy(&(conn->peer_addr), &addr, sizeof(struct sockaddr_storage));
|
||||
|
||||
if(err == PICO_ERR_EPROTONOSUPPORT)
|
||||
@@ -593,7 +629,7 @@ namespace ZeroTier {
|
||||
return err;
|
||||
}
|
||||
|
||||
int picoTCP::pico_Bind(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
int picoTCP::pico_Bind(Connection *conn, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
//DEBUG_INFO();
|
||||
if(!conn || !conn->picosock) {
|
||||
@@ -647,7 +683,7 @@ namespace ZeroTier {
|
||||
return err;
|
||||
}
|
||||
|
||||
int picoTCP::pico_Listen(Connection *conn, int fd, int backlog)
|
||||
int picoTCP::pico_Listen(Connection *conn, int backlog)
|
||||
{
|
||||
//DEBUG_INFO();
|
||||
if(!conn || !conn->picosock) {
|
||||
@@ -776,7 +812,7 @@ namespace ZeroTier {
|
||||
{
|
||||
int err = 0;
|
||||
// TODO: Add RingBuffer overflow checks
|
||||
//DEBUG_INFO("conn=%p, len = %d", conn, len);
|
||||
DEBUG_INFO("conn=%p, len=%d", conn, len);
|
||||
Mutex::Lock _l(conn->_tx_m);
|
||||
if(len <= 0) {
|
||||
DEBUG_ERROR("invalid write length (len=%d)", len);
|
||||
@@ -793,51 +829,56 @@ namespace ZeroTier {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int original_txsz = conn->TXbuf->count();
|
||||
if(conn->socket_type == SOCK_DGRAM)
|
||||
{
|
||||
int r;
|
||||
if((r = pico_socket_write(conn->picosock, data, len)) < 0) {
|
||||
DEBUG_ERROR("unable to write to picosock=%p, r=%d", conn->picosock, r);
|
||||
err = -1;
|
||||
}
|
||||
else {
|
||||
err = r; // successful write
|
||||
}
|
||||
DEBUG_TRANS("[ UDP TX -> STACK] :: conn=%p, len=%d, err=%s", conn, r, beautify_pico_error(pico_err));
|
||||
}
|
||||
if(conn->socket_type == SOCK_STREAM)
|
||||
{
|
||||
int original_txsz = conn->TXbuf->count();
|
||||
if(original_txsz + len >= ZT_TCP_TX_BUF_SZ) {
|
||||
DEBUG_ERROR("txsz=%d, len=%d", original_txsz, len);
|
||||
DEBUG_ERROR("TX buffer is too small, try increasing ZT_TCP_TX_BUF_SZ in libzt.h");
|
||||
exit(0);
|
||||
}
|
||||
int buf_w = conn->TXbuf->write((const unsigned char*)data, len);
|
||||
if (buf_w != len) {
|
||||
// because we checked ZT_TCP_TX_BUF_SZ above, this should not happen
|
||||
DEBUG_ERROR("TX wrote only %d but expected to write %d", buf_w, len);
|
||||
exit(0);
|
||||
}
|
||||
//DEBUG_INFO("TXbuf->count() = %d", conn->TXbuf->count());
|
||||
int txsz = conn->TXbuf->count();
|
||||
|
||||
if(original_txsz + len >= ZT_TCP_TX_BUF_SZ) {
|
||||
DEBUG_ERROR("txsz = %d, len = %d", original_txsz, len);
|
||||
DEBUG_ERROR("TX buffer is too small, try increasing ZT_TCP_TX_BUF_SZ in libzt.h");
|
||||
exit(0);
|
||||
int r, max_write_len = std::min(std::min(txsz, ZT_SDK_MTU),ZT_STACK_SOCKET_WR_MAX);
|
||||
//int buf_r = conn->TXbuf->read(conn->tmptxbuf, max_write_len);
|
||||
|
||||
if((r = pico_socket_write(conn->picosock, conn->TXbuf->get_buf(), max_write_len)) < 0) {
|
||||
DEBUG_ERROR("unable to write to picosock=%p, r=%d", conn->picosock, r);
|
||||
err = -1;
|
||||
}
|
||||
else {
|
||||
err = r; // successful write
|
||||
}
|
||||
if(r>0){
|
||||
conn->TXbuf->consume(r);
|
||||
}
|
||||
DEBUG_TRANS("[ TCP TX -> STACK] :: conn=%p, len=%d", conn, r);
|
||||
}
|
||||
|
||||
int buf_w = conn->TXbuf->write((const unsigned char*)data, len);
|
||||
if (buf_w != len) {
|
||||
// because we checked ZT_TCP_TX_BUF_SZ above, this should not happen
|
||||
DEBUG_ERROR("TX wrote only %d but expected to write %d", buf_w, len);
|
||||
exit(0);
|
||||
}
|
||||
//DEBUG_INFO("TXbuf->count() = %d", conn->TXbuf->count());
|
||||
int txsz = conn->TXbuf->count();
|
||||
|
||||
//if(original_txsz > 0)
|
||||
// return; // don't write here, we already have stuff in the queue, a callback will handle it
|
||||
|
||||
int r, max_write_len = std::min(std::min(txsz, ZT_SDK_MTU),ZT_STACK_SOCKET_WR_MAX);
|
||||
//int buf_r = conn->TXbuf->read(conn->tmptxbuf, max_write_len);
|
||||
|
||||
if((r = pico_socket_write(conn->picosock, conn->TXbuf->get_buf(), max_write_len)) < 0) {
|
||||
DEBUG_ERROR("unable to write to picosock=%p, r=%d", conn->picosock, r);
|
||||
err = -1;
|
||||
}
|
||||
else {
|
||||
err = r; // successful write
|
||||
}
|
||||
if(conn->socket_type == SOCK_STREAM) {
|
||||
//DEBUG_TRANS("[ TCP TX -> STACK] :: conn = %p, len = %d", conn, r);
|
||||
}
|
||||
if(conn->socket_type == SOCK_DGRAM) {
|
||||
//DEBUG_TRANS("[ UDP TX -> STACK] :: conn = %p, len = %d", conn, r);
|
||||
}
|
||||
if(r>0)
|
||||
conn->TXbuf->consume(r);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int picoTCP::pico_Close(Connection *conn)
|
||||
{
|
||||
DEBUG_INFO("conn = %p, picosock=%p, fd = %d", conn, conn->picosock, conn->app_fd);
|
||||
DEBUG_INFO("conn=%p, picosock=%p, fd=%d", conn, conn->picosock, conn->app_fd);
|
||||
if(!conn || !conn->picosock)
|
||||
return ZT_ERR_GENERAL_FAILURE;
|
||||
int err = 0;
|
||||
|
||||
@@ -67,6 +67,10 @@
|
||||
#define PICO_SOCKET_SHUTDOWN_SIG struct pico_socket *s, int mode
|
||||
#define PICO_SOCKET_ACCEPT_SIG struct pico_socket *s, void *orig, uint16_t *port
|
||||
#define PICO_IPV6_LINK_ADD_SIG struct pico_device *dev, struct pico_ip6 address, struct pico_ip6 netmask
|
||||
#define PICO_IPV4_ROUTE_ADD_SIG struct pico_ip4 address, struct pico_ip4 netmask, struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link
|
||||
#define PICO_IPV4_ROUTE_DEL_SIG struct pico_ip4 address, struct pico_ip4 netmask, int metric
|
||||
#define PICO_IPV6_ROUTE_ADD_SIG struct pico_ip6 address, struct pico_ip6 netmask, struct pico_ip6 gateway, int metric, struct pico_ipv6_link *link
|
||||
#define PICO_IPV6_ROUTE_DEL_SIG struct pico_ip6 address, struct pico_ip6 netmask, struct pico_ip6 gateway, int metric, struct pico_ipv6_link *link
|
||||
|
||||
namespace ZeroTier
|
||||
{
|
||||
@@ -92,6 +96,16 @@ namespace ZeroTier
|
||||
*/
|
||||
bool pico_init_interface(ZeroTier::SocketTap *tap, const ZeroTier::InetAddress &ip);
|
||||
|
||||
/*
|
||||
* Adds a route to the picoTCP device
|
||||
*/
|
||||
bool pico_route_add(SocketTap *tap, const InetAddress &addr, const InetAddress &nm, const InetAddress &gw, int metric);
|
||||
|
||||
/*
|
||||
* Deletes a route from the picoTCP device
|
||||
*/
|
||||
bool pico_route_del(SocketTap *tap, const InetAddress &addr, const InetAddress &nm, int metric);
|
||||
|
||||
/*
|
||||
* Main stack loop
|
||||
*/
|
||||
@@ -130,17 +144,17 @@ namespace ZeroTier
|
||||
/*
|
||||
* Connect to remote host via userspace network stack interface - Called from SocketTap
|
||||
*/
|
||||
int pico_Connect(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int pico_Connect(Connection *conn, const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
/*
|
||||
* Bind to a userspace network stack interface - Called from SocketTap
|
||||
*/
|
||||
int pico_Bind(Connection *conn, int fd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int pico_Bind(Connection *conn, const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
/*
|
||||
* Listen for incoming connections - Called from SocketTap
|
||||
*/
|
||||
int pico_Listen(Connection *conn, int fd, int backlog);
|
||||
int pico_Listen(Connection *conn, int backlog);
|
||||
|
||||
/*
|
||||
* Accept an incoming connection - Called from SocketTap
|
||||
|
||||
@@ -57,6 +57,10 @@ int main(int argc , char *argv[])
|
||||
}
|
||||
fprintf(stderr, "Created raw socket (%d)\n", fd);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
fprintf(stderr, "SOCK_RAW not supported on mac builds yet. exiting");
|
||||
exit(0);
|
||||
#endif
|
||||
#if defined(__linux__) // The rest of this file isn't yet supported on non-linux platforms
|
||||
// get interface index to bind on
|
||||
struct ifreq if_idx;
|
||||
|
||||
@@ -345,7 +345,7 @@ void udp_client_4(UNIT_TEST_SIG_4)
|
||||
if((sockfd = zts_socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
DEBUG_ERROR("error creating ZeroTier socket");
|
||||
|
||||
w = zts_sendto(sockfd, str, strlen(str), 0, (struct sockaddr *)&addr, sizeof(addr));
|
||||
w = zts_sendto(sockfd, str, strlen(str), 0, (struct sockaddr *)addr, sizeof(addr));
|
||||
memset(rbuf, 0, sizeof(rbuf));
|
||||
int serverlen = sizeof(addr);
|
||||
r = zts_recvfrom(sockfd, rbuf, STR_SIZE, 0, (struct sockaddr *)&addr, (socklen_t *)&serverlen);
|
||||
@@ -367,10 +367,13 @@ void udp_server_4(UNIT_TEST_SIG_4)
|
||||
if((sockfd = zts_socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
DEBUG_ERROR("error creating ZeroTier socket");
|
||||
|
||||
if((err = zts_bind(sockfd, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) < 0))
|
||||
DEBUG_ERROR("error binding to interface (%d)", err);
|
||||
|
||||
int serverlen = sizeof(addr);
|
||||
r = zts_recvfrom(sockfd, rbuf, STR_SIZE, 0, (struct sockaddr *)&addr, (socklen_t *)&serverlen);
|
||||
memset(rbuf, 0, sizeof(rbuf));
|
||||
w = zts_sendto(sockfd, str, strlen(str), 0, (struct sockaddr *)&addr, sizeof(addr));
|
||||
w = zts_sendto(sockfd, str, strlen(str), 0, (struct sockaddr *)addr, sizeof(addr));
|
||||
|
||||
sleep(WAIT_FOR_TRANSMISSION_TO_COMPLETE);
|
||||
err = zts_close(sockfd);
|
||||
@@ -1159,6 +1162,23 @@ int obscure_api_test()
|
||||
return err;
|
||||
}
|
||||
|
||||
void get_network_routes(char *nwid)
|
||||
{
|
||||
// Retreive managed routes for a given ZeroTier network
|
||||
std::vector<ZT_VirtualNetworkRoute> *routes = zts_get_network_routes(nwid);
|
||||
|
||||
for(int i=0; i<routes->size(); i++) {
|
||||
struct sockaddr_in *target = (struct sockaddr_in*)&(routes->at(i).target);
|
||||
struct sockaddr_in *via = (struct sockaddr_in*)&(routes->at(i).via);
|
||||
char target_str[INET6_ADDRSTRLEN];
|
||||
memset(target_str, 0, INET6_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)target)->sin_addr.s_addr, target_str, INET_ADDRSTRLEN);
|
||||
char via_str[INET6_ADDRSTRLEN];
|
||||
memset(via_str, 0, INET6_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)via)->sin_addr.s_addr, via_str, INET_ADDRSTRLEN);
|
||||
DEBUG_INFO("<target=%s, via=%s, flags=%d>", target_str, via_str, routes->at(i).flags);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* RANDOMIZED API TEST */
|
||||
@@ -1433,6 +1453,7 @@ int main(int argc , char *argv[])
|
||||
|
||||
|
||||
// ipv4 client/server
|
||||
|
||||
ipv = 4;
|
||||
if(mode == TEST_MODE_SERVER) {
|
||||
create_addr(local_ipstr, port, ipv, (struct sockaddr *)&addr);
|
||||
@@ -1459,7 +1480,7 @@ int main(int argc , char *argv[])
|
||||
port++;
|
||||
|
||||
// UDP
|
||||
|
||||
/*
|
||||
if(mode == TEST_MODE_SERVER) {
|
||||
create_addr(local_ipstr, port, ipv, (struct sockaddr *)&addr);
|
||||
udp_server_4((struct sockaddr_in *)&addr, operation, count, delay, details, &passed); // tcp_server_4
|
||||
@@ -1483,7 +1504,7 @@ int main(int argc , char *argv[])
|
||||
}
|
||||
RECORD_RESULTS(&test_number, passed, details, &results);
|
||||
port++;
|
||||
|
||||
*/
|
||||
// ipv4 sustained transfer
|
||||
ipv = 4;
|
||||
if(mode == TEST_MODE_SERVER) {
|
||||
|
||||
Reference in New Issue
Block a user