Expand C API and simplify NodeService

This commit is contained in:
Joseph Henry
2021-04-22 11:20:04 -07:00
parent 565b56d290
commit 43350691b5
30 changed files with 7697 additions and 5467 deletions

View File

@@ -4,7 +4,7 @@
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2025-01-01
* Change Date: 2026-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2.0 of the Apache License.
@@ -19,33 +19,28 @@
#include "lwip/sockets.h"
#include "Events.hpp"
#include "Utilities.hpp"
#include "ZeroTierSockets.h"
#include "lwip/def.h"
#include "lwip/dns.h"
#include "lwip/inet.h"
#include "lwip/ip_addr.h"
#include "lwip/netdb.h"
#include "lwip/stats.h"
#define ZTS_STATE_NODE_RUNNING 0x01
#define ZTS_STATE_STACK_RUNNING 0x02
#define ZTS_STATE_NET_SERVICE_RUNNING 0x04
#define ZTS_STATE_CALLBACKS_RUNNING 0x08
#define ZTS_STATE_FREE_CALLED 0x10
extern int zts_errno;
// errno-like reporting variable
int zts_errno;
extern int last_state_check;
namespace ZeroTier {
extern uint8_t _serviceStateFlags;
#ifdef __cplusplus
extern "C" {
#endif
int zts_socket(const int socket_family, const int socket_type, const int protocol)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_socket(socket_family, socket_type, protocol);
@@ -53,21 +48,24 @@ int zts_socket(const int socket_family, const int socket_type, const int protoco
int zts_connect(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! addr) {
return ZTS_ERR_ARG;
}
if (addrlen > (int)sizeof(struct zts_sockaddr_storage)
|| addrlen < (int)sizeof(struct zts_sockaddr_in)) {
if (addrlen > (zts_socklen_t)sizeof(struct zts_sockaddr_storage)
|| addrlen < (zts_socklen_t)sizeof(struct zts_sockaddr_in)) {
return ZTS_ERR_ARG;
}
return lwip_connect(fd, (sockaddr*)addr, addrlen);
}
int zts_connect_easy(int fd, int family, char* ipstr, int port, int timeout_ms)
int zts_simple_connect(int fd, const char* ipstr, int port, int timeout_ms)
{
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (timeout_ms < 0) {
return ZTS_ERR_ARG;
}
@@ -83,21 +81,17 @@ int zts_connect_easy(int fd, int family, char* ipstr, int port, int timeout_ms)
struct zts_sockaddr_storage ss;
struct zts_sockaddr* sa = NULL;
if (family == ZTS_AF_INET) {
addrlen = sizeof(ss);
ipstr2sockaddr(family, ipstr, port, (struct zts_sockaddr*)&ss, &addrlen);
sa = (struct zts_sockaddr*)&ss;
}
if (family == ZTS_AF_INET6) {
addrlen = sizeof(ss);
ipstr2sockaddr(family, ipstr, port, (struct zts_sockaddr*)&ss, &addrlen);
sa = (struct zts_sockaddr*)&ss;
}
// Convert to standard address structure
addrlen = sizeof(ss);
zts_util_ipstr_to_saddr(ipstr, port, (struct zts_sockaddr*)&ss, &addrlen);
sa = (struct zts_sockaddr*)&ss;
if (addrlen > 0 && sa != NULL) {
if (zts_get_blocking(fd)) {
if (zts_simple_get_blocking(fd)) {
do {
err = zts_connect(fd, sa, addrlen);
zts_delay_ms(connect_delay);
zts_util_delay(connect_delay);
n_tries--;
} while ((err < 0) && (zts_errno != 0) && (n_tries > 0));
}
@@ -108,7 +102,7 @@ int zts_connect_easy(int fd, int family, char* ipstr, int port, int timeout_ms)
int zts_bind(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! addr) {
@@ -121,28 +115,26 @@ int zts_bind(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen)
return lwip_bind(fd, (sockaddr*)addr, addrlen);
}
int zts_bind_easy(int fd, int family, char* ipstr, int port)
int zts_simple_bind(int fd, const char* ipstr, int port)
{
if (family == ZTS_AF_INET) {
struct zts_sockaddr_in in4;
zts_socklen_t addrlen = sizeof(in4);
ipstr2sockaddr(family, ipstr, port, (struct zts_sockaddr*)&in4, &addrlen);
struct zts_sockaddr* sa = (struct zts_sockaddr*)&in4;
return zts_bind(fd, sa, addrlen);
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (family == ZTS_AF_INET6) {
struct zts_sockaddr_in6 in6;
zts_socklen_t addrlen = sizeof(in6);
ipstr2sockaddr(family, ipstr, port, (struct zts_sockaddr*)&in6, &addrlen);
struct zts_sockaddr* sa = (struct zts_sockaddr*)&in6;
return zts_bind(fd, sa, addrlen);
}
return ZTS_ERR_ARG;
zts_socklen_t addrlen = 0;
struct zts_sockaddr_storage ss;
struct zts_sockaddr* sa = NULL;
addrlen = sizeof(ss);
zts_util_ipstr_to_saddr(ipstr, port, (struct zts_sockaddr*)&ss, &addrlen);
sa = (struct zts_sockaddr*)&ss;
return zts_bind(fd, sa, addrlen);
}
int zts_listen(int fd, int backlog)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_listen(fd, backlog);
@@ -150,20 +142,20 @@ int zts_listen(int fd, int backlog)
int zts_accept(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_accept(fd, (sockaddr*)addr, (socklen_t*)addrlen);
}
int zts_accept_easy(int fd, char* remoteIpStr, int len, int* port)
int zts_simple_accept(int fd, char* remote_addr, int len, int* port)
{
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (len != ZTS_INET6_ADDRSTRLEN) {
return ZTS_ERR_ARG;
}
char ipstr[ZTS_INET6_ADDRSTRLEN];
memset(ipstr, 0, ZTS_INET6_ADDRSTRLEN);
zts_sockaddr_storage ss;
zts_socklen_t addrlen = sizeof(ss);
@@ -171,20 +163,82 @@ int zts_accept_easy(int fd, char* remoteIpStr, int len, int* port)
struct zts_sockaddr* sa = (struct zts_sockaddr*)&ss;
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), remoteIpStr, ZTS_INET_ADDRSTRLEN);
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), remote_addr, 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), remoteIpStr, ZTS_INET6_ADDRSTRLEN);
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), remote_addr, ZTS_INET6_ADDRSTRLEN);
*port = ntohs(in6->sin6_port);
}
return acc_fd;
}
int zts_simple_tcp_client(const char* remote_ipstr, int remote_port)
{
int fd, family = zts_util_get_ip_family(remote_ipstr);
if ((fd = zts_socket(family, ZTS_SOCK_STREAM, 0)) < 0) {
return fd; // Failed to create socket
}
int timeout = 0;
if ((fd = zts_simple_connect(fd, remote_ipstr, remote_port, timeout)) < 0) {
zts_close(fd);
return fd; // Failed to connect
}
return fd;
}
int zts_simple_tcp_server(
const char* local_ipstr,
int local_port,
char* remote_ipstr,
int len,
int* remote_port)
{
int listen_fd, family = zts_util_get_ip_family(local_ipstr);
if ((listen_fd = zts_socket(family, ZTS_SOCK_STREAM, 0)) < 0) {
return listen_fd; // Failed to create socket
}
if ((listen_fd = zts_simple_bind(listen_fd, local_ipstr, local_port)) < 0) {
return listen_fd; // Failed to bind
}
int backlog = 0;
if ((listen_fd = zts_listen(listen_fd, backlog)) < 0) {
return listen_fd; // Failed to listen
}
int acc_fd = 0;
if ((acc_fd = zts_simple_accept(listen_fd, remote_ipstr, len, remote_port)) < 0) {
return acc_fd; // Failed to accept
}
zts_close(listen_fd);
return acc_fd;
}
int zts_simple_udp_server(const char* local_ipstr, int local_port)
{
int fd, family = zts_util_get_ip_family(local_ipstr);
if ((fd = zts_socket(family, ZTS_SOCK_DGRAM, 0)) < 0) {
return fd; // Failed to create socket
}
if ((fd = zts_simple_bind(fd, local_ipstr, local_port)) < 0) {
zts_close(fd);
return fd; // Failed to connect
}
return fd;
}
int zts_simple_udp_client(const char* remote_ipstr)
{
int fd, family = zts_util_get_ip_family(remote_ipstr);
if ((fd = zts_socket(family, ZTS_SOCK_DGRAM, 0)) < 0) {
return fd; // Failed to create socket
}
return fd;
}
int zts_setsockopt(int fd, int level, int optname, const void* optval, zts_socklen_t optlen)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_setsockopt(fd, level, optname, optval, optlen);
@@ -192,7 +246,7 @@ int zts_setsockopt(int fd, int level, int optname, const void* optval, zts_sockl
int zts_getsockopt(int fd, int level, int optname, void* optval, zts_socklen_t* optlen)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_getsockopt(fd, level, optname, optval, (socklen_t*)optlen);
@@ -200,7 +254,7 @@ int zts_getsockopt(int fd, int level, int optname, void* optval, zts_socklen_t*
int zts_getsockname(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! addr) {
@@ -215,7 +269,7 @@ int zts_getsockname(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
int zts_getpeername(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! addr) {
@@ -230,7 +284,7 @@ int zts_getpeername(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
int zts_close(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_close(fd);
@@ -243,7 +297,7 @@ int zts_select(
zts_fd_set* exceptfds,
struct zts_timeval* timeout)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_select(
@@ -256,7 +310,7 @@ int zts_select(
int zts_fcntl(int fd, int cmd, int flags)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_fcntl(fd, cmd, flags);
@@ -264,7 +318,7 @@ int zts_fcntl(int fd, int cmd, int flags)
int zts_poll(struct zts_pollfd* fds, nfds_t nfds, int timeout)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_poll((pollfd*)fds, nfds, timeout);
@@ -272,7 +326,7 @@ int zts_poll(struct zts_pollfd* fds, nfds_t nfds, int timeout)
int zts_ioctl(int fd, unsigned long request, void* argp)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! argp) {
@@ -283,7 +337,7 @@ int zts_ioctl(int fd, unsigned long request, void* argp)
ssize_t zts_send(int fd, const void* buf, size_t len, int flags)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! buf) {
@@ -300,7 +354,7 @@ ssize_t zts_sendto(
const struct zts_sockaddr* addr,
zts_socklen_t addrlen)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! addr || ! buf) {
@@ -315,16 +369,15 @@ ssize_t zts_sendto(
ssize_t zts_sendmsg(int fd, const struct zts_msghdr* msg, int flags)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_sendmsg(fd, (const struct msghdr*)msg, flags);
}
ssize_t zts_recv(int fd, void* buf, size_t len, int flags)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! buf) {
@@ -341,7 +394,7 @@ ssize_t zts_recvfrom(
struct zts_sockaddr* addr,
zts_socklen_t* addrlen)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! buf) {
@@ -352,7 +405,7 @@ ssize_t zts_recvfrom(
ssize_t zts_recvmsg(int fd, struct zts_msghdr* msg, int flags)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! msg) {
@@ -363,7 +416,7 @@ ssize_t zts_recvmsg(int fd, struct zts_msghdr* msg, int flags)
ssize_t zts_read(int fd, void* buf, size_t len)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! buf) {
@@ -374,19 +427,17 @@ ssize_t zts_read(int fd, void* buf, size_t len)
ssize_t zts_readv(int fd, const struct zts_iovec* iov, int iovcnt)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_readv(fd, (iovec*)iov, iovcnt);
}
ssize_t zts_write(int fd, const void* buf, size_t len)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (! buf) {
return ZTS_ERR_ARG;
}
@@ -395,16 +446,15 @@ ssize_t zts_write(int fd, const void* buf, size_t len)
ssize_t zts_writev(int fd, const struct zts_iovec* iov, int iovcnt)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_writev(fd, (iovec*)iov, iovcnt);
}
int zts_shutdown(int fd, int how)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
return lwip_shutdown(fd, how);
@@ -412,7 +462,7 @@ int zts_shutdown(int fd, int how)
struct zts_hostent* zts_gethostbyname(const char* name)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return NULL;
}
if (! name) {
@@ -423,7 +473,7 @@ struct zts_hostent* zts_gethostbyname(const char* name)
int zts_dns_set_server(uint8_t index, const zts_ip_addr* addr)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (index >= DNS_MAX_SERVERS) {
@@ -438,7 +488,7 @@ int zts_dns_set_server(uint8_t index, const zts_ip_addr* addr)
const zts_ip_addr* zts_dns_get_server(uint8_t index)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return NULL;
}
if (index >= DNS_MAX_SERVERS) {
@@ -467,13 +517,14 @@ int zts_inet_pton(int family, const char* src, void* dst)
return lwip_inet_pton(family, src, dst);
}
int ipstr2sockaddr(
int family,
char* src_ipstr,
int zts_util_ipstr_to_saddr(
const char* src_ipstr,
int port,
struct zts_sockaddr* dest_addr,
zts_socklen_t* addrlen)
{
int family = zts_util_get_ip_family(src_ipstr);
if (family == ZTS_AF_INET) {
struct zts_sockaddr_in in4;
in4.sin_port = htons(port);
@@ -509,14 +560,15 @@ int ipstr2sockaddr(
/**
* Helper functions that simplify API wrapper generation and usage in other
* non-C-like languages. Use simple integer types instead of bit flags, limit
* the number of operations each function performs, prevent the user from
* needing to manipulate the content of structures in a non-native language.
* non-C-like languages. Use simple integer types instead of bit flags,
* limit the number of operations each function performs, prevent the user
* from needing to manipulate the content of structures in a non-native
* language.
*/
int zts_set_no_delay(int fd, int enabled)
int zts_simple_set_no_delay(int fd, int enabled)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (enabled != 0 && enabled != 1) {
@@ -525,9 +577,9 @@ int zts_set_no_delay(int fd, int enabled)
return zts_setsockopt(fd, ZTS_IPPROTO_TCP, ZTS_TCP_NODELAY, (void*)&enabled, sizeof(int));
}
int zts_get_no_delay(int fd)
int zts_simple_get_no_delay(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
int err, optval = 0;
@@ -538,9 +590,9 @@ int zts_get_no_delay(int fd)
return optval != 0;
}
int zts_set_linger(int fd, int enabled, int value)
int zts_simple_set_linger(int fd, int enabled, int value)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (enabled != 0 && enabled != 1) {
@@ -555,37 +607,37 @@ int zts_set_linger(int fd, int enabled, int value)
return zts_setsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_LINGER, (void*)&linger, sizeof(linger));
}
int zts_get_linger_enabled(int fd)
int zts_simple_get_linger_enabled(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
int err;
struct zts_linger linger;
zts_socklen_t len = sizeof(linger);
int err;
if ((err = zts_getsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_LINGER, (void*)&linger, &len)) < 0) {
return err;
}
return linger.l_onoff;
}
int zts_get_linger_value(int fd)
int zts_simple_get_linger_value(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
int err;
struct zts_linger linger;
zts_socklen_t len = sizeof(linger);
int err;
if ((err = zts_getsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_LINGER, (void*)&linger, &len)) < 0) {
return err;
}
return linger.l_linger;
}
int zts_set_reuse_addr(int fd, int enabled)
int zts_simple_set_reuse_addr(int fd, int enabled)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (enabled != 0 && enabled != 1) {
@@ -594,13 +646,12 @@ int zts_set_reuse_addr(int fd, int enabled)
return zts_setsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_REUSEADDR, (void*)&enabled, sizeof(enabled));
}
int zts_get_reuse_addr(int fd)
int zts_simple_get_reuse_addr(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
int err;
int optval = 0;
int err, optval = 0;
zts_socklen_t optlen = sizeof(optval);
if ((err = zts_getsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_REUSEADDR, (void*)&optval, &optlen)) < 0) {
return err;
@@ -608,9 +659,9 @@ int zts_get_reuse_addr(int fd)
return optval != 0;
}
int zts_set_recv_timeout(int fd, int seconds, int microseconds)
int zts_simple_set_recv_timeout(int fd, int seconds, int microseconds)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (seconds < 0 || microseconds < 0) {
@@ -622,9 +673,9 @@ int zts_set_recv_timeout(int fd, int seconds, int microseconds)
return zts_setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void*)&tv, sizeof(tv));
}
int zts_get_recv_timeout(int fd)
int zts_simple_get_recv_timeout(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
struct timeval tv;
@@ -636,9 +687,9 @@ int zts_get_recv_timeout(int fd)
return tv.tv_sec; // TODO microseconds
}
int zts_set_send_timeout(int fd, int seconds, int microseconds)
int zts_simple_set_send_timeout(int fd, int seconds, int microseconds)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (seconds < 0 || microseconds < 0) {
@@ -650,9 +701,9 @@ int zts_set_send_timeout(int fd, int seconds, int microseconds)
return zts_setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (void*)&tv, sizeof(tv));
}
int zts_get_send_timeout(int fd)
int zts_simple_get_send_timeout(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
struct zts_timeval tv;
@@ -664,9 +715,9 @@ int zts_get_send_timeout(int fd)
return tv.tv_sec; // TODO microseconds
}
int zts_set_send_buf_size(int fd, int size)
int zts_simple_set_send_buf_size(int fd, int size)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (size < 0) {
@@ -675,9 +726,9 @@ int zts_set_send_buf_size(int fd, int size)
return zts_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&size, sizeof(int));
}
int zts_get_send_buf_size(int fd)
int zts_simple_get_send_buf_size(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
int err, optval = 0;
@@ -688,9 +739,9 @@ int zts_get_send_buf_size(int fd)
return optval;
}
int zts_set_recv_buf_size(int fd, int size)
int zts_simple_set_recv_buf_size(int fd, int size)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (size < 0) {
@@ -699,9 +750,9 @@ int zts_set_recv_buf_size(int fd, int size)
return zts_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&size, sizeof(int));
}
int zts_get_recv_buf_size(int fd)
int zts_simple_get_recv_buf_size(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
int err, optval = 0;
@@ -712,9 +763,9 @@ int zts_get_recv_buf_size(int fd)
return optval;
}
int zts_set_ttl(int fd, int ttl)
int zts_simple_set_ttl(int fd, int ttl)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (ttl < 0 || ttl > 255) {
@@ -723,9 +774,9 @@ int zts_set_ttl(int fd, int ttl)
return zts_setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
}
int zts_get_ttl(int fd)
int zts_simple_get_ttl(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
int err, ttl = 0;
@@ -736,9 +787,9 @@ int zts_get_ttl(int fd)
return ttl;
}
int zts_set_blocking(int fd, int enabled)
int zts_simple_set_blocking(int fd, int enabled)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (enabled != 0 && enabled != 1) {
@@ -754,9 +805,9 @@ int zts_set_blocking(int fd, int enabled)
}
}
int zts_get_blocking(int fd)
int zts_simple_get_blocking(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
int flags = zts_fcntl(fd, ZTS_F_GETFL, 0);
@@ -766,10 +817,9 @@ int zts_get_blocking(int fd)
return ! (flags & ZTS_O_NONBLOCK);
}
int zts_set_keepalive(int fd, int enabled)
int zts_simple_set_keepalive(int fd, int enabled)
{
//
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
if (enabled != 0 && enabled != 1) {
@@ -779,13 +829,12 @@ int zts_set_keepalive(int fd, int enabled)
return zts_setsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_KEEPALIVE, &keepalive, sizeof(keepalive));
}
int zts_get_keepalive(int fd)
int zts_simple_get_keepalive(int fd)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
if (! transport_ok()) {
return ZTS_ERR_SERVICE;
}
int err;
int optval = 0;
int err, optval = 0;
zts_socklen_t optlen = sizeof(optval);
if ((err = zts_getsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_KEEPALIVE, (void*)&optval, &optlen)) < 0) {
return err;
@@ -793,102 +842,6 @@ int zts_get_keepalive(int fd)
return optval != 0;
}
//----------------------------------------------------------------------------//
// Statistics //
//----------------------------------------------------------------------------//
#ifdef ZTS_ENABLE_STATS
extern struct stats_ lwip_stats;
int zts_get_all_stats(struct zts_stats* statsDest)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
return ZTS_ERR_SERVICE;
}
#if LWIP_STATS
if (! statsDest) {
return ZTS_ERR_ARG;
}
memset(statsDest, 0, sizeof(struct zts_stats));
// Copy lwIP stats
memcpy(&(statsDest->link), &(lwip_stats.link), sizeof(struct stats_proto));
memcpy(&(statsDest->etharp), &(lwip_stats.etharp), sizeof(struct stats_proto));
memcpy(&(statsDest->ip_frag), &(lwip_stats.ip_frag), sizeof(struct stats_proto));
memcpy(&(statsDest->ip), &(lwip_stats.ip), sizeof(struct stats_proto));
memcpy(&(statsDest->icmp), &(lwip_stats.icmp), sizeof(struct stats_proto));
// memcpy(&(statsDest->igmp), &(lwip_stats.igmp), sizeof(struct stats_igmp));
memcpy(&(statsDest->udp), &(lwip_stats.udp), sizeof(struct stats_proto));
memcpy(&(statsDest->tcp), &(lwip_stats.tcp), sizeof(struct stats_proto));
// mem omitted
// memp omitted
memcpy(&(statsDest->sys), &(lwip_stats.sys), sizeof(struct stats_sys));
memcpy(&(statsDest->ip6), &(lwip_stats.ip6), sizeof(struct stats_proto));
memcpy(&(statsDest->icmp6), &(lwip_stats.icmp6), sizeof(struct stats_proto));
memcpy(&(statsDest->ip6_frag), &(lwip_stats.ip6_frag), sizeof(struct stats_proto));
memcpy(&(statsDest->mld6), &(lwip_stats.mld6), sizeof(struct stats_igmp));
memcpy(&(statsDest->nd6), &(lwip_stats.nd6), sizeof(struct stats_proto));
memcpy(&(statsDest->ip_frag), &(lwip_stats.ip_frag), sizeof(struct stats_proto));
// mib2 omitted
// Copy ZT stats
// ...
return ZTS_ERR_OK;
#else
return ZTS_ERR_NO_RESULT;
#endif
}
int zts_get_protocol_stats(int protocolType, void* protoStatsDest)
{
if (! (_serviceStateFlags & ZTS_STATE_NET_SERVICE_RUNNING)) {
return ZTS_ERR_SERVICE;
}
#if LWIP_STATS
if (! protoStatsDest) {
return ZTS_ERR_ARG;
}
memset(protoStatsDest, 0, sizeof(struct stats_proto));
switch (protocolType) {
case ZTS_STATS_PROTOCOL_LINK:
memcpy(protoStatsDest, &(lwip_stats.link), sizeof(struct stats_proto));
break;
case ZTS_STATS_PROTOCOL_ETHARP:
memcpy(protoStatsDest, &(lwip_stats.etharp), sizeof(struct stats_proto));
break;
case ZTS_STATS_PROTOCOL_IP:
memcpy(protoStatsDest, &(lwip_stats.ip), sizeof(struct stats_proto));
break;
case ZTS_STATS_PROTOCOL_UDP:
memcpy(protoStatsDest, &(lwip_stats.udp), sizeof(struct stats_proto));
break;
case ZTS_STATS_PROTOCOL_TCP:
memcpy(protoStatsDest, &(lwip_stats.tcp), sizeof(struct stats_proto));
break;
case ZTS_STATS_PROTOCOL_ICMP:
memcpy(protoStatsDest, &(lwip_stats.icmp), sizeof(struct stats_proto));
break;
case ZTS_STATS_PROTOCOL_IP_FRAG:
memcpy(protoStatsDest, &(lwip_stats.ip_frag), sizeof(struct stats_proto));
break;
case ZTS_STATS_PROTOCOL_IP6:
memcpy(protoStatsDest, &(lwip_stats.ip6), sizeof(struct stats_proto));
break;
case ZTS_STATS_PROTOCOL_ICMP6:
memcpy(protoStatsDest, &(lwip_stats.icmp6), sizeof(struct stats_proto));
break;
case ZTS_STATS_PROTOCOL_IP6_FRAG:
memcpy(protoStatsDest, &(lwip_stats.ip6_frag), sizeof(struct stats_proto));
break;
default: return ZTS_ERR_ARG;
}
return ZTS_ERR_OK;
#else
return ZTS_ERR_NO_RESULT;
#endif
}
#endif // ZTS_ENABLE_STATS
#ifdef __cplusplus
}
#endif