8 changed files with 1899 additions and 558 deletions
@ -0,0 +1,816 @@
|
||||
/**
|
||||
* Selftest. To be run for every commit. |
||||
*/ |
||||
|
||||
#include <assert.h> |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include <time.h> |
||||
#include <stdlib.h> |
||||
#include <limits.h> |
||||
#include <math.h> |
||||
#include <time.h> |
||||
|
||||
#include <ZeroTierSockets.h> |
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-value" |
||||
|
||||
int random32() { |
||||
const int BITS_PER_RAND = (int)(log2(RAND_MAX/2 + 1) + 1.0); |
||||
int ret = 0; |
||||
for (int i = 0; i < sizeof(int) * CHAR_BIT; i += BITS_PER_RAND) { |
||||
ret <<= BITS_PER_RAND; |
||||
ret |= rand(); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
uint64_t random64() { |
||||
return ((uint64_t)random32() << 32) | random32(); |
||||
} |
||||
|
||||
int is_online = 0; |
||||
int has_ip4 = 0; |
||||
int has_ip6 = 0; |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Event Handler //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void on_zts_event(void *msgPtr) |
||||
{ |
||||
struct zts_callback_msg *msg = (struct zts_callback_msg *)msgPtr; |
||||
fprintf(stderr, "event=%d\n", msg->eventCode); |
||||
if (msg->eventCode == ZTS_EVENT_NODE_ONLINE) { |
||||
fprintf(stderr, "ZTS_EVENT_NODE_ONLINE\n"); |
||||
is_online = 1; |
||||
} |
||||
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP4) { |
||||
fprintf(stderr, "ZTS_EVENT_NETWORK_READY_IP4\n"); |
||||
has_ip4 = 1; |
||||
} |
||||
if (msg->eventCode == ZTS_EVENT_NETWORK_READY_IP6) { |
||||
fprintf(stderr, "ZTS_EVENT_NETWORK_READY_IP6\n"); |
||||
has_ip6 = 1; |
||||
} |
||||
} |
||||
|
||||
void api_value_arg_test( |
||||
int8_t i8, int16_t i16, int32_t i32, int64_t i64, void* nullable) |
||||
{ |
||||
//fprintf(stderr, "%d, %d, %d, %lld, %p\n", i8, i16, i32, i64, nullable);
|
||||
int res = ZTS_ERR_OK; |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Test uninitialized Network Stack API usage //
|
||||
//----------------------------------------------------------------------------//
|
||||
/*
|
||||
res = zts_get_all_stats((struct zts_stats *)nullable); |
||||
assert(("pre-init call to zts_get_all_stats(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_get_protocol_stats(i32, nullable); |
||||
assert(("pre-init call to zts_get_protocol_stats(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
*/ |
||||
res = zts_dns_set_server(i8, (const zts_ip_addr *)nullable); |
||||
assert(("pre-init call to zts_add_dns_nameserver(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
const zts_ip_addr *res_ptr = zts_dns_get_server(i8); |
||||
assert(("pre-init call to zts_del_dns_nameserver(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Test uninitialized Node API usage //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
res = zts_stop(); |
||||
assert(("pre-init call to zts_stop(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_restart(); |
||||
assert(("pre-init call to zts_restart(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_free(); |
||||
assert(("pre-init call to zts_free(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_join(i64); |
||||
assert(("pre-init call to zts_join(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_leave(i64); |
||||
assert(("pre-init call to zts_leave(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_orbit(i64,i64); |
||||
assert(("pre-init call to zts_orbit(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_deorbit(i64); |
||||
assert(("pre-init call to zts_deorbit(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Test uninitialized Socket API usage //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
res = zts_socket(i32,i32,i32); |
||||
assert(("pre-init call to zts_socket(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_connect(i32, (const struct zts_sockaddr *)nullable, i32); |
||||
assert(("pre-init call to zts_connect(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_bind(i32, (const struct zts_sockaddr *)nullable, i32); |
||||
assert(("pre-init call to zts_bind(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_listen(i32, i32); |
||||
assert(("pre-init call to zts_listen(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_accept(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_accept(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_setsockopt(i32, i32, i32, nullable, i32); |
||||
assert(("pre-init call to zts_setsockopt(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_getsockopt(i32, i32, i32, nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_getsockopt(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_getsockname(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_getsockname(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_getpeername(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_getpeername(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_close(i32); |
||||
assert(("pre-init call to zts_close(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_select(i32, (zts_fd_set *)nullable, (zts_fd_set *)nullable, (zts_fd_set *)nullable, (struct zts_timeval *)nullable); |
||||
assert(("pre-init call to zts_select(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_fcntl(i32, i32, i32); |
||||
assert(("pre-init call to zts_fcntl(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_poll((struct zts_pollfd *)nullable, i32, i32); |
||||
assert(("pre-init call to zts_poll(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_ioctl(i32, i64, nullable); |
||||
assert(("pre-init call to zts_ioctl(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_send(i32, nullable, i32, i32); |
||||
assert(("pre-init call to zts_send(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_sendto(i32, nullable, i32, i32, (const struct zts_sockaddr *)nullable, i32); |
||||
assert(("pre-init call to zts_sendto(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_sendmsg(i32, (const struct zts_msghdr *)nullable, i32); |
||||
assert(("pre-init call to zts_sendmsg(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_recv(i32, nullable, i32, i32); |
||||
assert(("pre-init call to zts_recv(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_recvfrom(i32, nullable, i32, i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_recvfrom(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_recvmsg(i32, (struct zts_msghdr *)nullable, i32); |
||||
assert(("pre-init call to zts_recvmsg(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_read(i32, nullable, i32); |
||||
assert(("pre-init call to zts_read(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_readv(i32, (const struct zts_iovec *)nullable, i32); |
||||
assert(("pre-init call to zts_readv(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_write(i32, nullable, i32); |
||||
assert(("pre-init call to zts_write(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_writev(i32, (const struct zts_iovec *)nullable, i32); |
||||
assert(("pre-init call to zts_writev(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_shutdown(i32, i32); |
||||
assert(("pre-init call to zts_shutdown(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
} |
||||
|
||||
void test_pre_service() |
||||
{ |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Test service-related API functions before initializing service //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
// Test null values
|
||||
api_value_arg_test(0,0,0,0,NULL); |
||||
|
||||
// Test wild values
|
||||
for (int i=0; i<4096; i++) { |
||||
int8_t i8 = (uint8_t)random64(); |
||||
int16_t i16 = (uint16_t)random64(); |
||||
int32_t i32 = (uint32_t)random64(); |
||||
int64_t i64 = (uint64_t)random64(); |
||||
int x; |
||||
void* nullable = &x; |
||||
api_value_arg_test(i8,i16,i32,i64,nullable); |
||||
} |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Test non-service helper functions //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
// (B) Test zts_inet_ntop
|
||||
|
||||
char ipstr[ZTS_INET6_ADDRSTRLEN]; |
||||
int16_t port = 0; |
||||
struct zts_sockaddr_in in4; |
||||
|
||||
in4.sin_port = htons(8080); |
||||
#if defined(_WIN32) |
||||
zts_inet_pton(ZTS_AF_INET, "192.168.22.1", &(in4.sin_addr.S_addr)); |
||||
#else |
||||
zts_inet_pton(ZTS_AF_INET, "192.168.22.1", &(in4.sin_addr.s_addr)); |
||||
#endif |
||||
|
||||
in4.sin_family = ZTS_AF_INET; |
||||
|
||||
struct zts_sockaddr *sa = (struct zts_sockaddr *)&in4; |
||||
if (sa->sa_family == ZTS_AF_INET) { |
||||
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)sa; |
||||
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), |
||||
ipstr, ZTS_INET_ADDRSTRLEN); |
||||
port = ntohs(in4->sin_port); |
||||
} |
||||
if (sa->sa_family == ZTS_AF_INET6) { |
||||
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)sa; |
||||
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), |
||||
ipstr, ZTS_INET6_ADDRSTRLEN); |
||||
} |
||||
|
||||
assert(("zts_inet_ntop(): port != 8080", port == 8080)); |
||||
assert(("zts_inet_ntop(): strcmp(ipstr, \"192.168.22.1\") != 0", |
||||
!strcmp(ipstr, "192.168.22.1"))); |
||||
|
||||
// (C) Test zts_inet_pton
|
||||
|
||||
uint8_t buf[sizeof(struct zts_in6_addr)]; |
||||
char str[ZTS_INET6_ADDRSTRLEN]; |
||||
|
||||
zts_inet_pton(ZTS_AF_INET, "192.168.22.2", buf); |
||||
zts_inet_ntop(ZTS_AF_INET, buf, str, ZTS_INET6_ADDRSTRLEN); |
||||
assert(("zts_inet_pton(): strcmp(ipstr, \"192.168.22.2\") != 0", |
||||
!strcmp(str, "192.168.22.2"))); |
||||
} |
||||
|
||||
void test_service() |
||||
{ |
||||
int res = ZTS_ERR_OK; |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Test simplified API, proxy for setsockopt/getsockopt/ioctl etc //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
int s4 = zts_socket(ZTS_AF_INET6, ZTS_SOCK_STREAM, 0); |
||||
assert(s4 >= 0); |
||||
|
||||
// TCP_NODELAY
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_no_delay(s4); |
||||
assert(res == 0); |
||||
// Turn on
|
||||
res = zts_set_no_delay(s4, 1); |
||||
assert(res == ZTS_ERR_OK); |
||||
res = zts_get_no_delay(s4); |
||||
// Should return value instead of error code
|
||||
assert(res == 1); |
||||
// Turn off
|
||||
res = zts_set_no_delay(s4, 0); |
||||
assert(res == ZTS_ERR_OK); |
||||
res = zts_get_no_delay(s4); |
||||
assert(res == ZTS_ERR_OK); |
||||
assert(res == 0); |
||||
|
||||
// SO_LINGER
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_linger_enabled(s4); |
||||
assert(res == 0); |
||||
res = zts_get_linger_value(s4); |
||||
assert(res == 0); |
||||
// Turn on, set to 7 seconds
|
||||
res = zts_set_linger(s4, 1, 7); |
||||
res = zts_get_linger_enabled(s4); |
||||
assert(res == 1); |
||||
res = zts_get_linger_value(s4); |
||||
assert(res == 7); |
||||
res = zts_set_linger(s4, 0, 0); |
||||
// Turn off
|
||||
res = zts_get_linger_enabled(s4); |
||||
assert(res == 0); |
||||
res = zts_get_linger_value(s4); |
||||
assert(res == 0); |
||||
|
||||
// SO_REUSEADDR
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_reuse_addr(s4); |
||||
assert(res == 0); |
||||
// Turn on
|
||||
res = zts_set_reuse_addr(s4, 1); |
||||
assert(res == ZTS_ERR_OK); |
||||
res = zts_get_reuse_addr(s4); |
||||
// Should return value instead of error code
|
||||
assert(res == 1); |
||||
// Turn off
|
||||
res = zts_set_reuse_addr(s4, 0); |
||||
assert(res == ZTS_ERR_OK); |
||||
res = zts_get_reuse_addr(s4); |
||||
assert(res == ZTS_ERR_OK); |
||||
assert(res == 0); |
||||
|
||||
// SO_RCVTIMEO
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_recv_timeout(s4); |
||||
assert(res == 0); |
||||
// Set to value
|
||||
res = zts_set_recv_timeout(s4, 3, 0); |
||||
res = zts_get_recv_timeout(s4); |
||||
assert(res == 3); |
||||
res = zts_set_recv_timeout(s4, 0, 0); |
||||
// Set to zero
|
||||
res = zts_get_recv_timeout(s4); |
||||
assert(res == 0); |
||||
|
||||
// SO_SNDTIMEO
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_send_timeout(s4); |
||||
assert(res == 0); |
||||
// Set to value
|
||||
res = zts_set_send_timeout(s4, 4, 0); |
||||
res = zts_get_send_timeout(s4); |
||||
assert(res == 4); |
||||
res = zts_set_send_timeout(s4, 0, 0); |
||||
// Set to zero
|
||||
res = zts_get_send_timeout(s4); |
||||
assert(res == 0); |
||||
|
||||
// SO_SNDBUF
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_send_buf_size(s4); |
||||
assert(res == -1); // Unimplemented as of writing of test
|
||||
// Set to 7 seconds
|
||||
res = zts_set_send_buf_size(s4, 1024); |
||||
res = zts_get_send_buf_size(s4); |
||||
assert(res == -1); // Unimplemented as of writing of test
|
||||
res = zts_set_send_buf_size(s4, 0); |
||||
// Set to zero
|
||||
res = zts_get_send_buf_size(s4); |
||||
assert(res == -1); // Unimplemented as of writing of test
|
||||
|
||||
// SO_RCVBUF
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_recv_buf_size(s4); |
||||
assert(res > 0); |
||||
// Set to value
|
||||
res = zts_set_recv_buf_size(s4, 1024); |
||||
res = zts_get_recv_buf_size(s4); |
||||
assert(res == 1024); |
||||
res = zts_set_recv_buf_size(s4, 0); |
||||
// Set to zero
|
||||
res = zts_get_recv_buf_size(s4); |
||||
assert(res == 0); |
||||
|
||||
// IP_TTL
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_ttl(s4); |
||||
assert(res == 255); // Defaults to max
|
||||
// Set to value
|
||||
res = zts_set_ttl(s4, 128); |
||||
res = zts_get_ttl(s4); |
||||
assert(res == 128); |
||||
res = zts_set_ttl(s4, 0); |
||||
// Set to zero
|
||||
res = zts_get_ttl(s4); |
||||
assert(res == 0); |
||||
|
||||
// O_NONBLOCK
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_blocking(s4); |
||||
assert(res == 1); |
||||
// Turn off (non-blocking)
|
||||
res = zts_set_blocking(s4, 0); |
||||
assert(res == ZTS_ERR_OK); |
||||
res = zts_get_blocking(s4); |
||||
// Should return value instead of error code
|
||||
assert(res == 0); |
||||
// Turn off
|
||||
res = zts_set_blocking(s4, 1); |
||||
assert(res == ZTS_ERR_OK); |
||||
res = zts_get_blocking(s4); |
||||
assert(res == 1); |
||||
|
||||
// SO_KEEPALIVE
|
||||
|
||||
// Check value before doing anything
|
||||
res = zts_get_keepalive(s4); |
||||
assert(res == 0); |
||||
// Turn on
|
||||
res = zts_set_keepalive(s4, 1); |
||||
assert(res == ZTS_ERR_OK); |
||||
res = zts_get_keepalive(s4); |
||||
// Should return value instead of error code
|
||||
assert(res == 1); |
||||
// Turn off
|
||||
res = zts_set_keepalive(s4, 0); |
||||
assert(res == ZTS_ERR_OK); |
||||
res = zts_get_keepalive(s4); |
||||
assert(res == ZTS_ERR_OK); |
||||
assert(res == 0); |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Test *_easy API //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
//zts_connect_easy(0, ZTS_AF_INET, "192.168.7.9", 7878);
|
||||
//zts_connect_easy(0, ZTS_AF_INET6, "FCC5:205E:4FF5:5311:DFF0::1", 7878);
|
||||
//res = zts_bind_easy(0, ZTS_AF_INET6, "::", 8080);
|
||||
//fprintf(stderr, "res=%d, zts_errno=%d\n", res, zts_errno);
|
||||
//zts_delay_ms(60000);
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Test DNS client functionality //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/*
|
||||
// Set first nameserver
|
||||
|
||||
char *ns1_addr_str = "FCC5:205E:4FF5:5311:DFF0::1"; |
||||
zts_ip_addr ns1; |
||||
zts_ipaddr_aton(ns1_addr_str, &ns1); |
||||
zts_dns_set_server(0, &ns1); |
||||
|
||||
// Get first nameserver
|
||||
|
||||
const zts_ip_addr *ns1_result; |
||||
ns1_result = zts_dns_get_server(0); |
||||
printf("dns1 = %s\n", zts_ipaddr_ntoa(ns1_result)); |
||||
|
||||
// Set second nameserver
|
||||
|
||||
char *ns2_addr_str = "192.168.22.1"; |
||||
zts_ip_addr ns2; |
||||
zts_ipaddr_aton(ns2_addr_str, &ns2); |
||||
zts_dns_set_server(1, &ns2); |
||||
|
||||
// Get second nameserver
|
||||
|
||||
const zts_ip_addr *ns2_result; |
||||
ns2_result = zts_dns_get_server(1); |
||||
printf("dns1 = %s\n", zts_ipaddr_ntoa(ns2_result)); |
||||
|
||||
// Check that each nameserver address was properly set and get
|
||||
|
||||
assert(("zts_dns_get_server(): Address mismatch", !strcmp(ns1_addr_str, zts_ipaddr_ntoa(ns1_result)))); |
||||
assert(("zts_dns_get_server(): Address mismatch", !strcmp(ns2_addr_str, zts_ipaddr_ntoa(ns2_result)))); |
||||
*/ |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Test shutting down the service //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
zts_stop(); |
||||
s4 = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0); |
||||
assert(("s4 != ZTS_ERR_SERVICE, not shut down", s4 == ZTS_ERR_SERVICE)); |
||||
} |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Server //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define MAX_CONNECT_TIME 60 |
||||
#define BUFLEN 128 |
||||
char *msg = "welcome to the machine"; |
||||
|
||||
void start_server_app(uint16_t port4, uint16_t port6) |
||||
{ |
||||
int err = ZTS_ERR_OK; |
||||
int bytes_read = 0; |
||||
int bytes_sent = 0; |
||||
|
||||
int msglen = strlen(msg); |
||||
char dstbuf[BUFLEN]; |
||||
int buflen = BUFLEN; |
||||
|
||||
struct timespec start, now; |
||||
int time_diff = 0; |
||||
|
||||
//
|
||||
// IPv4 test
|
||||
//
|
||||
|
||||
fprintf(stderr, "server4: will listen on: 0.0.0.0:%d\n", port4); |
||||
int s4 = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0); |
||||
assert(s4 == 0 && zts_errno == 0); |
||||
|
||||
err = zts_bind_easy(s4, ZTS_AF_INET, "0.0.0.0", port4); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
err = zts_listen(s4, 1); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
struct zts_sockaddr_in in4; |
||||
zts_socklen_t addrlen4 = sizeof(in4); |
||||
|
||||
int acc4 = -1; |
||||
clock_gettime(CLOCK_MONOTONIC, &start); |
||||
do { |
||||
fprintf(stderr, "server4: accepting...\n"); |
||||
acc4 = zts_accept(s4, &in4, &addrlen4); |
||||
zts_delay_ms(250); |
||||
clock_gettime(CLOCK_MONOTONIC, &now); |
||||
time_diff = (now.tv_sec - start.tv_sec); |
||||
} while (err < 0 && time_diff < MAX_CONNECT_TIME); |
||||
|
||||
assert(acc4 == 1 && zts_errno == 0); |
||||
|
||||
// Read message
|
||||
memset(dstbuf, 0, buflen); |
||||
bytes_read = zts_read(acc4, dstbuf, buflen); |
||||
fprintf(stderr, "server4: read (%d) bytes\n", bytes_read); |
||||
assert(bytes_read == msglen && zts_errno == 0); |
||||
|
||||
// Send message
|
||||
bytes_sent = zts_write(acc4, msg, msglen); |
||||
fprintf(stderr, "server4: wrote (%d) bytes\n", bytes_sent); |
||||
assert(bytes_sent == msglen && zts_errno == 0); |
||||
|
||||
zts_close(s4); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
zts_close(acc4); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
//
|
||||
// IPv6 test
|
||||
//
|
||||
|
||||
fprintf(stderr, "server: will listen on: [::]:%d\n", port6); |
||||
int s6 = zts_socket(ZTS_AF_INET6, ZTS_SOCK_STREAM, 0); |
||||
assert(s6 == 0 && zts_errno == 0); |
||||
|
||||
err = zts_bind_easy(s6, ZTS_AF_INET6, "::", port6); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
err = zts_listen(s6, 1); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
struct zts_sockaddr_in6 in6; |
||||
zts_socklen_t addrlen6 = sizeof(in6); |
||||
|
||||
int acc6 = -1; |
||||
clock_gettime(CLOCK_MONOTONIC, &start); |
||||
do { |
||||
fprintf(stderr, "server6: accepting...\n"); |
||||
acc6 = zts_accept(s6, &in6, &addrlen6); |
||||
zts_delay_ms(250); |
||||
clock_gettime(CLOCK_MONOTONIC, &now); |
||||
time_diff = (now.tv_sec - start.tv_sec); |
||||
} while (err < 0 && time_diff < MAX_CONNECT_TIME); |
||||
|
||||
fprintf(stderr, "server6: accepted connection (fd=%d)\n", acc6); |
||||
assert(acc6 == 1 && zts_errno == 0); |
||||
|
||||
// Read message
|
||||
memset(dstbuf, 0, buflen); |
||||
bytes_read = zts_read(acc6, dstbuf, buflen); |
||||
fprintf(stderr, "server6: read (%d) bytes\n", bytes_read); |
||||
assert(bytes_read == msglen && zts_errno == 0); |
||||
|
||||
// Send message
|
||||
bytes_sent = zts_write(acc6, msg, msglen); |
||||
fprintf(stderr, "server6: wrote (%d) bytes\n", bytes_sent); |
||||
assert(bytes_sent == msglen && zts_errno == 0); |
||||
|
||||
zts_close(s6); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
zts_close(acc6); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
zts_stop(); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
int s = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0); |
||||
assert(("s != ZTS_ERR_SERVICE, not shut down", s == ZTS_ERR_SERVICE)); |
||||
} |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Client //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void start_client_app(char *ip4, uint16_t port4, char *ip6, uint16_t port6) |
||||
{ |
||||
int err = ZTS_ERR_OK; |
||||
int bytes_read = 0; |
||||
int bytes_sent = 0; |
||||
|
||||
int msglen = strlen(msg); |
||||
char dstbuf[BUFLEN]; |
||||
int buflen = BUFLEN; |
||||
|
||||
struct timespec start, now; |
||||
int time_diff = 0; |
||||
|
||||
//
|
||||
// IPv4 test
|
||||
//
|
||||
|
||||
err = ZTS_ERR_OK; |
||||
int s4 = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
zts_set_blocking(s4, 1); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start); |
||||
do { |
||||
fprintf(stderr, "client4: connecting to: %s:%d\n", ip4, port4); |
||||
err = zts_connect_easy(s4, ZTS_AF_INET, ip4, port4); |
||||
zts_delay_ms(500); |
||||
clock_gettime(CLOCK_MONOTONIC, &now); |
||||
time_diff = (now.tv_sec - start.tv_sec); |
||||
} while (err < 0 && time_diff < MAX_CONNECT_TIME); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
fprintf(stderr, "client4: connected\n"); |
||||
// Send message
|
||||
bytes_sent = zts_write(s4, msg, msglen); |
||||
fprintf(stderr, "client4: wrote (%d) bytes\n", bytes_sent); |
||||
assert(bytes_sent == msglen && zts_errno == 0); |
||||
|
||||
// Read message
|
||||
memset(dstbuf, 0, buflen); |
||||
bytes_read = zts_read(s4, dstbuf, buflen); |
||||
assert(bytes_read == msglen && zts_errno == 0); |
||||
|
||||
fprintf(stderr, "client4: read (%d) bytes\n", bytes_read); |
||||
assert(bytes_sent == bytes_read && zts_errno == 0); |
||||
|
||||
zts_close(s4); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
//
|
||||
// IPv6 test
|
||||
//
|
||||
|
||||
err = ZTS_ERR_OK; |
||||
int s6 = zts_socket(ZTS_AF_INET6, ZTS_SOCK_STREAM, 0); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
zts_set_blocking(s6, 1); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start); |
||||
do { |
||||
fprintf(stderr, "client6: connecting to: %s:%d\n", ip6, port6); |
||||
err = zts_connect_easy(s6, ZTS_AF_INET6, ip6, port6); |
||||
zts_delay_ms(500); |
||||
clock_gettime(CLOCK_MONOTONIC, &now); |
||||
time_diff = (now.tv_sec - start.tv_sec); |
||||
} while (err < 0 && time_diff < MAX_CONNECT_TIME); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
fprintf(stderr, "client6: connected\n"); |
||||
// Send message
|
||||
bytes_sent = zts_write(s6, msg, msglen); |
||||
fprintf(stderr, "client6: wrote (%d) bytes\n", bytes_sent); |
||||
assert(bytes_sent == msglen && zts_errno == 0); |
||||
|
||||
// Read message
|
||||
memset(dstbuf, 0, buflen); |
||||
bytes_read = zts_read(s6, dstbuf, buflen); |
||||
assert(bytes_read == msglen && zts_errno == 0); |
||||
|
||||
fprintf(stderr, "client6: read (%d) bytes\n", bytes_read); |
||||
assert(bytes_sent == bytes_read && zts_errno == 0); |
||||
|
||||
zts_close(s6); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
|
||||
zts_stop(); |
||||
assert(err == ZTS_ERR_OK && zts_errno == 0); |
||||
int s = zts_socket(ZTS_AF_INET, ZTS_SOCK_STREAM, 0); |
||||
assert(("s != ZTS_ERR_SERVICE, not shut down", s == ZTS_ERR_SERVICE)); |
||||
} |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Start node //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void start_node(char *path, uint64_t nwid) |
||||
{ |
||||
struct timespec start, now; |
||||
int time_diff = 0; |
||||
|
||||
fprintf(stderr, "starting node...\n"); |
||||
clock_gettime(CLOCK_MONOTONIC, &start); |
||||
int res = zts_start(path, &on_zts_event, 0); |
||||
assert(("error starting service: res != ZTS_ERR_OK", res == ZTS_ERR_OK)); |
||||
do { |
||||
zts_delay_ms(25); |
||||
clock_gettime(CLOCK_MONOTONIC, &now); |
||||
time_diff = (now.tv_sec - start.tv_sec); |
||||
} while (!is_online && (time_diff < MAX_CONNECT_TIME)); |
||||
if (!is_online) { |
||||
fprintf(stderr, "node failed to come online\n"); |
||||
exit(-1); |
||||
} |
||||
|
||||
fprintf(stderr, "joining: %llx\n", nwid); |
||||
clock_gettime(CLOCK_MONOTONIC, &start); |
||||
if (nwid) { |
||||
zts_join(nwid); |
||||
do { |
||||
zts_delay_ms(25); |
||||
clock_gettime(CLOCK_MONOTONIC, &now); |
||||
time_diff = (now.tv_sec - start.tv_sec); |
||||
} while ((!has_ip4 || !has_ip6) && (time_diff < MAX_CONNECT_TIME)); |
||||
if (!has_ip4 || !has_ip6) { |
||||
fprintf(stderr, "node failed to receive assigned addresses\n"); |
||||
exit(-1); |
||||
} |
||||
} |
||||
} |
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Main //
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
if (argc != 1 && argc != 5 && argc != 7) { |
||||
fprintf(stderr, "Invalid number of arguments.\n"); |
||||
exit(-1); |
||||
} |
||||
|
||||
//
|
||||
// API fuzz test
|
||||
//
|
||||
|
||||
test_pre_service(); |
||||
|
||||
//
|
||||
// Default test
|
||||
//
|
||||
|
||||
// selftest
|
||||
if (argc == 1) { |
||||
srand(time(NULL)); |
||||
// Store identities in cwd, join 0x0
|
||||
start_node(".",0x0); |
||||
test_service(); |
||||
exit(0); |
||||
} |
||||
|
||||
// Default test (single node)
|
||||
// selftest <id-path>
|
||||
/*
|
||||
if (argc == 2) { |
||||
srand(time(NULL)); |
||||
start_node(argv[1],0x0); |
||||
test_service(); |
||||
exit(0); |
||||
}*/ |
||||
|
||||
//
|
||||
// Client/Server communication test
|
||||
//
|
||||
|
||||
// Server test
|
||||
if (argc == 5) { |
||||
//fprintf(stderr, "server.path = %s\n", argv[1]);
|
||||
//fprintf(stderr, "server.nwid = %s\n", argv[2]);
|
||||
//fprintf(stderr, "server.port4 = %s\n", argv[3]);
|
||||
//fprintf(stderr, "server.port6 = %s\n", argv[4]);
|
||||
uint64_t nwid = strtoull(argv[2],NULL,16); |
||||
int port4 = atoi(argv[3]); |
||||
int port6 = atoi(argv[4]); |
||||
start_node(argv[1],nwid); |
||||
start_server_app(port4, port6); |
||||
exit(0); |
||||
} |
||||
// Client test
|
||||
if (argc == 7) { |
||||
//fprintf(stderr, "client.path = %s\n", argv[1]);
|
||||
//fprintf(stderr, "client.nwid = %s\n", argv[2]);
|
||||
//fprintf(stderr, "client.port4 = %s\n", argv[3]);
|
||||
//fprintf(stderr, "client.ip4 = %s\n", argv[4]);
|
||||
//fprintf(stderr, "client.port6 = %s\n", argv[5]);
|
||||
//fprintf(stderr, "client.ip6 = %s\n", argv[6]);
|
||||
uint64_t nwid = strtoull(argv[2],NULL,16); |
||||
int port4 = atoi(argv[3]); |
||||
int port6 = atoi(argv[5]); |
||||
start_node(argv[1],nwid); |
||||
start_client_app(argv[4], port4, argv[6], port6); |
||||
exit(0); |
||||
} |
||||
return 0; |
||||
} |
||||
@ -1,272 +0,0 @@
|
||||
/**
|
||||
* Selftest. To be run for every commit. |
||||
*/ |
||||
|
||||
#include <assert.h> |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include <time.h> |
||||
#include <stdlib.h> |
||||
#include <limits.h> |
||||
#include <math.h> |
||||
|
||||
#include <ZeroTierSockets.h> |
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-value" |
||||
|
||||
int random32() { |
||||
const int BITS_PER_RAND = (int)(log2(RAND_MAX/2 + 1) + 1.0); |
||||
int ret = 0; |
||||
for (int i = 0; i < sizeof(int) * CHAR_BIT; i += BITS_PER_RAND) { |
||||
ret <<= BITS_PER_RAND; |
||||
ret |= rand(); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
uint64_t random64() { |
||||
return ((uint64_t)random32() << 32) | random32(); |
||||
} |
||||
|
||||
void api_value_arg_test(int8_t i8, int16_t i16, int32_t i32, int64_t i64, void* nullable) |
||||
{ |
||||
//fprintf(stderr, "%d, %d, %d, %lld, %p\n", i8, i16, i32, i64, nullable);
|
||||
int res = ZTS_ERR_OK; |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Test uninitialized Network Stack API usage |
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
res = zts_get_all_stats((struct zts_stats *)nullable); |
||||
assert(("pre-init call to zts_get_all_stats(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_get_protocol_stats(i32, nullable); |
||||
assert(("pre-init call to zts_get_protocol_stats(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_dns_set_server(i8, (const zts_ip_addr *)nullable); |
||||
assert(("pre-init call to zts_add_dns_nameserver(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
const zts_ip_addr *res_ptr = zts_dns_get_server(i8); |
||||
assert(("pre-init call to zts_del_dns_nameserver(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Test uninitialized Node API usage |
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
res = zts_stop(); |
||||
assert(("pre-init call to zts_stop(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_restart(); |
||||
assert(("pre-init call to zts_restart(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_free(); |
||||
assert(("pre-init call to zts_free(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_join(i64); |
||||
assert(("pre-init call to zts_join(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_leave(i64); |
||||
assert(("pre-init call to zts_leave(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_orbit(i64,i64); |
||||
assert(("pre-init call to zts_orbit(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_deorbit(i64); |
||||
assert(("pre-init call to zts_deorbit(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Test uninitialized Socket API usage |
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
res = zts_socket(i32,i32,i32); |
||||
assert(("pre-init call to zts_socket(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_connect(i32, (const struct zts_sockaddr *)nullable, i32); |
||||
assert(("pre-init call to zts_connect(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_bind(i32, (const struct zts_sockaddr *)nullable, i32); |
||||
assert(("pre-init call to zts_bind(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_listen(i32, i32); |
||||
assert(("pre-init call to zts_listen(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_accept(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_accept(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_setsockopt(i32, i32, i32, nullable, i32); |
||||
assert(("pre-init call to zts_setsockopt(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_getsockopt(i32, i32, i32, nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_getsockopt(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_getsockname(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_getsockname(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_getpeername(i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_getpeername(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_close(i32); |
||||
assert(("pre-init call to zts_close(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_select(i32, (zts_fd_set *)nullable, (zts_fd_set *)nullable, (zts_fd_set *)nullable, (struct zts_timeval *)nullable); |
||||
assert(("pre-init call to zts_select(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_fcntl(i32, i32, i32); |
||||
assert(("pre-init call to zts_fcntl(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_poll((struct zts_pollfd *)nullable, i32, i32); |
||||
assert(("pre-init call to zts_poll(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_ioctl(i32, i64, nullable); |
||||
assert(("pre-init call to zts_ioctl(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_send(i32, nullable, i32, i32); |
||||
assert(("pre-init call to zts_send(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_sendto(i32, nullable, i32, i32, (const struct zts_sockaddr *)nullable, i32); |
||||
assert(("pre-init call to zts_sendto(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_sendmsg(i32, (const struct zts_msghdr *)nullable, i32); |
||||
assert(("pre-init call to zts_sendmsg(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_recv(i32, nullable, i32, i32); |
||||
assert(("pre-init call to zts_recv(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_recvfrom(i32, nullable, i32, i32, (struct zts_sockaddr *)nullable, (zts_socklen_t *)nullable); |
||||
assert(("pre-init call to zts_recvfrom(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_recvmsg(i32, (struct zts_msghdr *)nullable, i32); |
||||
assert(("pre-init call to zts_recvmsg(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_read(i32, nullable, i32); |
||||
assert(("pre-init call to zts_read(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_readv(i32, (const struct zts_iovec *)nullable, i32); |
||||
assert(("pre-init call to zts_readv(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_write(i32, nullable, i32); |
||||
assert(("pre-init call to zts_write(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_writev(i32, (const struct zts_iovec *)nullable, i32); |
||||
assert(("pre-init call to zts_writev(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
res = zts_shutdown(i32, i32); |
||||
assert(("pre-init call to zts_shutdown(): res != ZTS_ERR_SERVICE", |
||||
res == ZTS_ERR_SERVICE)); |
||||
} |
||||
|
||||
int main() |
||||
{ |
||||
srand(time(NULL)); |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Test service-related API functions before initializing service |
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Test null values
|
||||
api_value_arg_test(0,0,0,0,NULL); |
||||
|
||||
// Test wild values
|
||||
for (int i=0; i<1024; i++) { |
||||
int8_t i8 = (uint8_t)random64(); |
||||
int16_t i16 = (uint16_t)random64(); |
||||
int32_t i32 = (uint32_t)random64(); |
||||
int64_t i64 = (uint64_t)random64(); |
||||
int x; |
||||
void* nullable = &x; |
||||
api_value_arg_test(i8,i16,i32,i64,nullable); |
||||
} |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Test non-service helper functions |
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// (B) Test zts_inet_ntop
|
||||
|
||||
char ipstr[ZTS_INET6_ADDRSTRLEN]; |
||||
int16_t port = 0; |
||||
struct zts_sockaddr_in in4; |
||||
|
||||
in4.sin_port = htons(8080); |
||||
#if defined(_WIN32) |
||||
zts_inet_pton(ZTS_AF_INET, "192.168.22.1", &(in4.sin_addr.S_addr)); |
||||
#else |
||||
zts_inet_pton(ZTS_AF_INET, "192.168.22.1", &(in4.sin_addr.s_addr)); |
||||
#endif |
||||
|
||||
in4.sin_family = ZTS_AF_INET; |
||||
|
||||
struct zts_sockaddr *sa = (struct zts_sockaddr *)&in4; |
||||
if (sa->sa_family == ZTS_AF_INET) { |
||||
struct zts_sockaddr_in *in4 = (struct zts_sockaddr_in*)sa; |
||||
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), |
||||
ipstr, ZTS_INET_ADDRSTRLEN); |
||||
port = ntohs(in4->sin_port); |
||||
} |
||||
if (sa->sa_family == ZTS_AF_INET6) { |
||||
struct zts_sockaddr_in6 *in6 = (struct zts_sockaddr_in6*)sa; |
||||
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), |
||||
ipstr, ZTS_INET6_ADDRSTRLEN); |
||||
} |
||||
|
||||
assert(("zts_inet_ntop(): port != 8080", port == 8080)); |
||||
assert(("zts_inet_ntop(): strcmp(ipstr, \"192.168.22.1\") != 0", |
||||
!strcmp(ipstr, "192.168.22.1"))); |
||||
|
||||
// (C) Test zts_inet_pton
|
||||
|
||||
uint8_t buf[sizeof(struct zts_in6_addr)]; |
||||
char str[ZTS_INET6_ADDRSTRLEN]; |
||||
|
||||
zts_inet_pton(ZTS_AF_INET, "192.168.22.2", buf); |
||||
zts_inet_ntop(ZTS_AF_INET, buf, str, ZTS_INET6_ADDRSTRLEN); |
||||
assert(("zts_inet_pton(): strcmp(ipstr, \"192.168.22.2\") != 0", |
||||
!strcmp(str, "192.168.22.2"))); |
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Start the service and test a few things |
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// zts_start();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Test DNS client functionality |
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
// Set first nameserver
|
||||
|
||||
char *ns1_addr_str = "FCC5:205E:4FF5:5311:DFF0::1"; |
||||
zts_ip_addr ns1; |
||||
zts_ipaddr_aton(ns1_addr_str, &ns1); |
||||
zts_dns_set_server(0, &ns1); |
||||
|
||||
// Get first nameserver
|
||||
|
||||
const zts_ip_addr *ns1_result; |
||||
ns1_result = zts_dns_get_server(0); |
||||
printf("dns1 = %s\n", zts_ipaddr_ntoa(ns1_result)); |
||||
|
||||
// Set second nameserver
|
||||
|
||||
char *ns2_addr_str = "192.168.22.1"; |
||||
zts_ip_addr ns2; |
||||
zts_ipaddr_aton(ns2_addr_str, &ns2); |
||||
zts_dns_set_server(1, &ns2); |
||||
|
||||
// Get second nameserver
|
||||
|
||||
const zts_ip_addr *ns2_result; |
||||
ns2_result = zts_dns_get_server(1); |
||||
printf("dns1 = %s\n", zts_ipaddr_ntoa(ns2_result)); |
||||
|
||||
// Check that each nameserver address was properly set and get
|
||||
|
||||
assert(("zts_dns_get_server(): Address mismatch", !strcmp(ns1_addr_str, zts_ipaddr_ntoa(ns1_result)))); |
||||
assert(("zts_dns_get_server(): Address mismatch", !strcmp(ns2_addr_str, zts_ipaddr_ntoa(ns2_result)))); |
||||
*/ |
||||
|
||||
return 0; |
||||
} |
||||
Loading…
Reference in new issue