294 lines
7.2 KiB
C
294 lines
7.2 KiB
C
//
|
|
// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
|
|
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
|
|
//
|
|
// This software is supplied under the terms of the MIT License, a
|
|
// copy of which should be located in the distribution where this
|
|
// file was obtained (LICENSE.txt). A copy of the license may also be
|
|
// found online at https://opensource.org/licenses/MIT.
|
|
//
|
|
|
|
#include <nng/nng.h>
|
|
#include <nng/protocol/pair0/pair.h>
|
|
#include <nng/transport/zerotier/zerotier.h>
|
|
|
|
#include "convey.h"
|
|
#include "trantest.h"
|
|
#include "stubs.h"
|
|
|
|
// zerotier tests.
|
|
|
|
// This network is an open network setup exclusively for nng testing.
|
|
// Do not attach to it in production.
|
|
#define NWID "a09acf02337b057b"
|
|
#define NWID_NUM 0xa09acf02337b057bull
|
|
|
|
// This network is a closed network, which nothing can join. We use it for
|
|
// testing permission denied.
|
|
#define CLOSED_NWID "17d709436ce162a3"
|
|
|
|
#ifdef _WIN32
|
|
|
|
int
|
|
mkdir(const char *path, int mode)
|
|
{
|
|
CreateDirectory(path, NULL);
|
|
return (0);
|
|
}
|
|
#else
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#endif // WIN32
|
|
|
|
static int
|
|
check_props(nng_msg *msg)
|
|
{
|
|
nng_pipe p;
|
|
p = nng_msg_get_pipe(msg);
|
|
So(nng_pipe_id(p) > 0);
|
|
|
|
// Check local address.
|
|
Convey("Local address property works", {
|
|
nng_sockaddr la;
|
|
So(nng_pipe_getopt_sockaddr(p, NNG_OPT_LOCADDR, &la) == 0);
|
|
|
|
So(la.s_family == NNG_AF_ZT);
|
|
So(la.s_zt.sa_port == (trantest_port - 1));
|
|
So(la.s_zt.sa_nwid == NWID_NUM);
|
|
So(la.s_zt.sa_nodeid != 0);
|
|
});
|
|
|
|
Convey("Remote address property works", {
|
|
// Check remote address.
|
|
uint64_t mynode;
|
|
nng_sockaddr ra;
|
|
|
|
So(nng_pipe_getopt_sockaddr(p, NNG_OPT_REMADDR, &ra) == 0);
|
|
So(ra.s_family == NNG_AF_ZT);
|
|
So(ra.s_zt.sa_port != 0);
|
|
So(ra.s_zt.sa_nwid == NWID_NUM);
|
|
|
|
So(nng_pipe_getopt_uint64(p, NNG_OPT_ZT_NODE, &mynode) == 0);
|
|
So(mynode != 0);
|
|
So(ra.s_zt.sa_nodeid == mynode);
|
|
});
|
|
|
|
Convey("NWID property works", {
|
|
uint64_t nwid = 0;
|
|
|
|
So(nng_pipe_getopt_uint64(p, NNG_OPT_ZT_NWID, &nwid) == 0);
|
|
So(nwid = 0xa09acf02337b057bull);
|
|
});
|
|
|
|
Convey("Network status property works", {
|
|
int s = 0;
|
|
|
|
So(nng_pipe_getopt_int(p, NNG_OPT_ZT_NETWORK_STATUS, &s) == 0);
|
|
So(s == NNG_ZT_STATUS_UP);
|
|
});
|
|
|
|
Convey("Ping properties work", {
|
|
int c = 0;
|
|
nng_duration t = 0;
|
|
|
|
So(nng_pipe_getopt_int(p, NNG_OPT_ZT_PING_TRIES, &c) == 0);
|
|
So(c > 0 && c <= 10);
|
|
|
|
So(nng_pipe_getopt_ms(p, NNG_OPT_ZT_PING_TIME, &t) == 0);
|
|
So(t > 1000 && t < 3600000); // 1 sec - 1 hour
|
|
});
|
|
|
|
Convey("Home property works", {
|
|
char *v;
|
|
So(nng_pipe_getopt_string(p, NNG_OPT_ZT_HOME, &v) == 0);
|
|
nng_strfree(v);
|
|
});
|
|
|
|
Convey("MTU property works", {
|
|
size_t mtu;
|
|
|
|
// Check MTU
|
|
So(nng_pipe_getopt_size(p, NNG_OPT_ZT_MTU, &mtu) == 0);
|
|
So(mtu >= 1000 && mtu <= 10000);
|
|
});
|
|
|
|
Convey("Network name property works", {
|
|
char *name;
|
|
|
|
So(nng_pipe_getopt_string(p, NNG_OPT_ZT_NETWORK_NAME, &name) ==
|
|
0);
|
|
So(strcmp(name, "nng_test_open") == 0);
|
|
nng_strfree(name);
|
|
});
|
|
|
|
return (0);
|
|
}
|
|
|
|
TestMain("ZeroTier Transport", {
|
|
char path1[NNG_MAXADDRLEN] = "/tmp/zt_server";
|
|
char path2[NNG_MAXADDRLEN] = "/tmp/zt_client";
|
|
unsigned port;
|
|
|
|
port = 5555;
|
|
|
|
Convey("We can register the zero tier transport",
|
|
{ So(nng_zt_register() == 0); });
|
|
|
|
Convey("We can create a zt listener", {
|
|
nng_listener l;
|
|
nng_socket s;
|
|
char addr[NNG_MAXADDRLEN];
|
|
|
|
So(nng_zt_register() == 0);
|
|
|
|
snprintf(addr, sizeof(addr), "zt://*." NWID ":%u", port);
|
|
|
|
So(nng_pair_open(&s) == 0);
|
|
Reset({ nng_close(s); });
|
|
|
|
So(nng_listener_create(&l, s, addr) == 0);
|
|
|
|
Convey("And it can be started...", {
|
|
mkdir(path1, 0700);
|
|
|
|
So(nng_listener_setopt(l, NNG_OPT_ZT_HOME, path1,
|
|
strlen(path1) + 1) == 0);
|
|
|
|
So(nng_listener_start(l, 0) == 0);
|
|
|
|
Convey("It has the right local address", {
|
|
nng_sockaddr sa;
|
|
So(nng_listener_getopt_sockaddr(
|
|
l, NNG_OPT_LOCADDR, &sa) == 0);
|
|
So(sa.s_zt.sa_family == NNG_AF_ZT);
|
|
So(sa.s_zt.sa_nwid == NWID_NUM);
|
|
So(sa.s_zt.sa_port == port);
|
|
So(sa.s_zt.sa_nodeid != 0);
|
|
});
|
|
Convey("And we can orbit a moon", {
|
|
uint64_t ids[2];
|
|
// Provided by Janjaap...
|
|
ids[0] = 0x622514484aull;
|
|
ids[1] = 0x622514484aull;
|
|
|
|
So(nng_listener_setopt(l, NNG_OPT_ZT_ORBIT,
|
|
ids, sizeof(ids)) == 0);
|
|
});
|
|
Convey("And we can deorbit anything", {
|
|
uint64_t id;
|
|
id = 0x12345678;
|
|
So(nng_listener_setopt(l, NNG_OPT_ZT_DEORBIT,
|
|
&id, sizeof(id)) == 0);
|
|
});
|
|
});
|
|
});
|
|
|
|
Convey("We can create a zt dialer", {
|
|
nng_dialer d;
|
|
nng_socket s;
|
|
char addr[NNG_MAXADDRLEN];
|
|
// uint64_t node = 0xb000072fa6ull; // my personal host
|
|
uint64_t node = 0x2d2f619cccull; // my personal host
|
|
|
|
So(nng_zt_register() == 0);
|
|
|
|
snprintf(addr, sizeof(addr), "zt://%llx." NWID ":%u",
|
|
(unsigned long long) node, port);
|
|
|
|
So(nng_pair_open(&s) == 0);
|
|
Reset({ nng_close(s); });
|
|
|
|
So(nng_dialer_create(&d, s, addr) == 0);
|
|
});
|
|
|
|
Convey("We can create an ephemeral listener", {
|
|
nng_dialer d;
|
|
nng_listener l;
|
|
nng_socket s;
|
|
char addr[NNG_MAXADDRLEN];
|
|
uint64_t node1 = 0;
|
|
uint64_t node2 = 0;
|
|
|
|
So(nng_zt_register() == 0);
|
|
|
|
snprintf(addr, sizeof(addr), "zt://*." NWID ":%u", port);
|
|
|
|
So(nng_pair_open(&s) == 0);
|
|
Reset({ nng_close(s); });
|
|
|
|
So(nng_listener_create(&l, s, addr) == 0);
|
|
|
|
So(nng_listener_getopt_uint64(l, NNG_OPT_ZT_NODE, &node1) ==
|
|
0);
|
|
So(node1 != 0);
|
|
|
|
Convey("Connection refused works", {
|
|
snprintf(addr, sizeof(addr), "zt://%llx." NWID ":%u",
|
|
(unsigned long long) node1, 42u);
|
|
So(nng_dialer_create(&d, s, addr) == 0);
|
|
So(nng_dialer_getopt_uint64(
|
|
d, NNG_OPT_ZT_NODE, &node2) == 0);
|
|
So(node2 == node1);
|
|
So(nng_dialer_start(d, 0) == NNG_ECONNREFUSED);
|
|
});
|
|
});
|
|
|
|
Convey("We can create a zt pair (dialer & listener)", {
|
|
nng_dialer d;
|
|
nng_listener l;
|
|
nng_socket s1;
|
|
nng_socket s2;
|
|
char addr1[NNG_MAXADDRLEN];
|
|
char addr2[NNG_MAXADDRLEN];
|
|
uint64_t node;
|
|
|
|
port = 9944;
|
|
So(nng_zt_register() == 0);
|
|
|
|
snprintf(addr1, sizeof(addr1), "zt://*." NWID ":%u", port);
|
|
|
|
So(nng_pair_open(&s1) == 0);
|
|
So(nng_pair_open(&s2) == 0);
|
|
Reset({
|
|
nng_close(s1);
|
|
// This sleep ensures disconnect messages work.
|
|
nng_msleep(500);
|
|
nng_close(s2);
|
|
});
|
|
|
|
So(nng_listener_create(&l, s1, addr1) == 0);
|
|
So(nng_listener_setopt(
|
|
l, NNG_OPT_ZT_HOME, path1, strlen(path1) + 1) == 0);
|
|
|
|
So(nng_listener_start(l, 0) == 0);
|
|
node = 0;
|
|
So(nng_listener_getopt_uint64(l, NNG_OPT_ZT_NODE, &node) == 0);
|
|
So(node != 0);
|
|
nng_msleep(40);
|
|
snprintf(addr2, sizeof(addr2), "zt://%llx." NWID ":%u",
|
|
(unsigned long long) node, port);
|
|
So(nng_dialer_create(&d, s2, addr2) == 0);
|
|
mkdir(path2, 0700);
|
|
So(nng_dialer_setopt(
|
|
d, NNG_OPT_ZT_HOME, path2, strlen(path2) + 1) == 0);
|
|
So(nng_dialer_start(d, 0) == 0);
|
|
nng_msleep(2000); // to give dialer time to start up
|
|
});
|
|
|
|
// We need to determine our ephemeral ID:
|
|
|
|
nng_socket s_test;
|
|
nng_listener l_test;
|
|
uint64_t node;
|
|
char fmt[128];
|
|
|
|
So(nng_pair_open(&s_test) == 0);
|
|
So(nng_listener_create(&l_test, s_test, "zt://*." NWID ":0") == 0);
|
|
So(nng_listener_start(l_test, 0) == 0);
|
|
So(nng_listener_getopt_uint64(l_test, NNG_OPT_ZT_NODE, &node) == 0);
|
|
snprintf(fmt, sizeof(fmt), "zt://%llx." NWID ":%%u",
|
|
(unsigned long long) node);
|
|
nng_listener_close(l_test);
|
|
|
|
trantest_test_extended(fmt, check_props);
|
|
})
|