2017-04-06 19:16:01 -07:00
|
|
|
/*
|
2021-02-04 11:03:55 -08:00
|
|
|
* Copyright (c)2013-2021 ZeroTier, Inc.
|
2017-04-06 19:16:01 -07:00
|
|
|
*
|
2020-04-13 23:38:06 -07:00
|
|
|
* Use of this software is governed by the Business Source License included
|
|
|
|
|
* in the LICENSE.TXT file in the project's root directory.
|
2017-04-06 19:16:01 -07:00
|
|
|
*
|
2021-04-22 11:20:04 -07:00
|
|
|
* Change Date: 2026-01-01
|
2017-04-06 19:16:01 -07:00
|
|
|
*
|
2020-04-13 23:38:06 -07:00
|
|
|
* 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.
|
2017-04-06 19:16:01 -07:00
|
|
|
*/
|
2020-04-13 23:38:06 -07:00
|
|
|
/****/
|
2017-04-06 19:16:01 -07:00
|
|
|
|
2017-09-27 02:29:04 -07:00
|
|
|
/**
|
|
|
|
|
* @file
|
|
|
|
|
*
|
2019-01-14 12:01:29 -08:00
|
|
|
* ZeroTier Socket API
|
2017-09-27 02:29:04 -07:00
|
|
|
*/
|
2017-04-06 19:16:01 -07:00
|
|
|
|
2017-09-27 02:29:04 -07:00
|
|
|
#include "lwip/sockets.h"
|
2021-04-17 23:46:21 -07:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
#include "Events.hpp"
|
|
|
|
|
#include "Utilities.hpp"
|
2021-04-17 23:46:21 -07:00
|
|
|
#include "ZeroTierSockets.h"
|
2019-02-06 22:00:39 -08:00
|
|
|
#include "lwip/def.h"
|
2021-03-16 00:31:45 -07:00
|
|
|
#include "lwip/dns.h"
|
2021-04-17 23:46:21 -07:00
|
|
|
#include "lwip/inet.h"
|
2021-03-16 00:31:45 -07:00
|
|
|
#include "lwip/ip_addr.h"
|
2021-04-17 23:46:21 -07:00
|
|
|
#include "lwip/netdb.h"
|
2020-05-30 18:29:04 -07:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
// errno-like reporting variable
|
|
|
|
|
int zts_errno;
|
|
|
|
|
extern int last_state_check;
|
2019-02-06 22:00:39 -08:00
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
namespace ZeroTier {
|
2017-10-18 17:57:51 -07:00
|
|
|
|
2017-11-06 13:50:20 -08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
2017-10-18 17:57:51 -07:00
|
|
|
#endif
|
|
|
|
|
|
2020-05-01 19:15:38 -07:00
|
|
|
int zts_socket(const int socket_family, const int socket_type, const int protocol)
|
2017-04-07 17:56:05 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
return lwip_socket(socket_family, socket_type, protocol);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-04-07 17:56:05 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_connect(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen)
|
2019-01-14 12:01:29 -08:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! addr) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-04-22 11:20:04 -07:00
|
|
|
if (addrlen > (zts_socklen_t)sizeof(struct zts_sockaddr_storage)
|
|
|
|
|
|| addrlen < (zts_socklen_t)sizeof(struct zts_sockaddr_in)) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_connect(fd, (sockaddr*)addr, addrlen);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-04-07 17:56:05 -07:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_connect(int fd, const char* ipstr, int port, int timeout_ms)
|
2021-04-17 23:46:21 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-03-26 16:33:22 -07:00
|
|
|
if (timeout_ms < 0) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
if (timeout_ms == 0) {
|
2021-04-17 23:46:21 -07:00
|
|
|
timeout_ms = 30000; // Default
|
2021-03-26 16:33:22 -07:00
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
int div = 4; // Must be > 0, Four connection attempts per second
|
2021-03-26 16:33:22 -07:00
|
|
|
int n_tries = (timeout_ms / 1000) * div;
|
|
|
|
|
int connect_delay = 1000 / div;
|
|
|
|
|
int err = ZTS_ERR_SOCKET;
|
|
|
|
|
|
|
|
|
|
zts_socklen_t addrlen = 0;
|
|
|
|
|
struct zts_sockaddr_storage ss;
|
2021-04-17 23:46:21 -07:00
|
|
|
struct zts_sockaddr* sa = NULL;
|
2021-03-26 16:33:22 -07:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
// 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;
|
|
|
|
|
|
2021-03-26 16:33:22 -07:00
|
|
|
if (addrlen > 0 && sa != NULL) {
|
2021-04-22 11:20:04 -07:00
|
|
|
if (zts_simple_get_blocking(fd)) {
|
2021-03-26 16:33:22 -07:00
|
|
|
do {
|
|
|
|
|
err = zts_connect(fd, sa, addrlen);
|
2021-04-22 11:20:04 -07:00
|
|
|
zts_util_delay(connect_delay);
|
2021-03-26 16:33:22 -07:00
|
|
|
n_tries--;
|
2021-04-17 23:46:21 -07:00
|
|
|
} while ((err < 0) && (zts_errno != 0) && (n_tries > 0));
|
2021-03-26 16:33:22 -07:00
|
|
|
}
|
|
|
|
|
return err;
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_bind(int fd, const struct zts_sockaddr* addr, zts_socklen_t addrlen)
|
2019-01-14 12:01:29 -08:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! addr) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2021-03-24 12:20:39 -07:00
|
|
|
if (addrlen > (int)sizeof(struct zts_sockaddr_storage)
|
2021-04-17 23:46:21 -07:00
|
|
|
|| addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_bind(fd, (sockaddr*)addr, addrlen);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2021-02-24 01:25:15 -08:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_bind(int fd, const char* ipstr, int port)
|
2021-04-17 23:46:21 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
2021-04-22 11:20:04 -07:00
|
|
|
|
|
|
|
|
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);
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2017-09-27 13:42:27 -07:00
|
|
|
int zts_listen(int fd, int backlog)
|
2017-04-07 17:56:05 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
return lwip_listen(fd, backlog);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-09-22 14:14:14 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_accept(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
|
2017-09-27 02:29:04 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
return lwip_accept(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-04-07 17:56:05 -07:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_accept(int fd, char* remote_addr, int len, int* port)
|
2021-03-26 16:33:22 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
|
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-03-26 16:33:22 -07:00
|
|
|
if (len != ZTS_INET6_ADDRSTRLEN) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
zts_sockaddr_storage ss;
|
|
|
|
|
zts_socklen_t addrlen = sizeof(ss);
|
|
|
|
|
|
|
|
|
|
int acc_fd = zts_accept(fd, (zts_sockaddr*)&ss, (zts_socklen_t*)&addrlen);
|
2021-04-17 23:46:21 -07:00
|
|
|
struct zts_sockaddr* sa = (struct zts_sockaddr*)&ss;
|
2021-03-26 16:33:22 -07:00
|
|
|
if (sa->sa_family == ZTS_AF_INET) {
|
2021-04-17 23:46:21 -07:00
|
|
|
struct zts_sockaddr_in* in4 = (struct zts_sockaddr_in*)sa;
|
2021-04-22 11:20:04 -07:00
|
|
|
zts_inet_ntop(ZTS_AF_INET, &(in4->sin_addr), remote_addr, ZTS_INET_ADDRSTRLEN);
|
2021-03-26 16:33:22 -07:00
|
|
|
*port = ntohs(in4->sin_port);
|
|
|
|
|
}
|
|
|
|
|
if (sa->sa_family == ZTS_AF_INET6) {
|
2021-04-17 23:46:21 -07:00
|
|
|
struct zts_sockaddr_in6* in6 = (struct zts_sockaddr_in6*)sa;
|
2021-04-22 11:20:04 -07:00
|
|
|
zts_inet_ntop(ZTS_AF_INET6, &(in6->sin6_addr), remote_addr, ZTS_INET6_ADDRSTRLEN);
|
2021-03-26 16:33:22 -07:00
|
|
|
*port = ntohs(in6->sin6_port);
|
|
|
|
|
}
|
|
|
|
|
return acc_fd;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_setsockopt(int fd, int level, int optname, const void* optval, zts_socklen_t optlen)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
return lwip_setsockopt(fd, level, optname, optval, optlen);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-04-14 17:23:28 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_getsockopt(int fd, int level, int optname, void* optval, zts_socklen_t* optlen)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
return lwip_getsockopt(fd, level, optname, optval, (socklen_t*)optlen);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-04-14 17:23:28 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_getsockname(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! addr) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-03-24 12:20:39 -07:00
|
|
|
if (*addrlen > (int)sizeof(struct zts_sockaddr_storage)
|
2021-04-17 23:46:21 -07:00
|
|
|
|| *addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_getsockname(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-04-14 17:23:28 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_getpeername(int fd, struct zts_sockaddr* addr, zts_socklen_t* addrlen)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! addr) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2021-03-24 12:20:39 -07:00
|
|
|
if (*addrlen > (int)sizeof(struct zts_sockaddr_storage)
|
2021-04-17 23:46:21 -07:00
|
|
|
|| *addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_getpeername(fd, (sockaddr*)addr, (socklen_t*)addrlen);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-09-22 14:14:14 -07:00
|
|
|
|
|
|
|
|
int zts_close(int fd)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
return lwip_close(fd);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-07-12 11:44:31 -07:00
|
|
|
|
2021-03-24 12:20:39 -07:00
|
|
|
int zts_select(
|
2021-04-17 23:46:21 -07:00
|
|
|
int nfds,
|
|
|
|
|
zts_fd_set* readfds,
|
|
|
|
|
zts_fd_set* writefds,
|
|
|
|
|
zts_fd_set* exceptfds,
|
|
|
|
|
struct zts_timeval* timeout)
|
2017-07-12 11:44:31 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-03-24 12:20:39 -07:00
|
|
|
return lwip_select(
|
2021-04-17 23:46:21 -07:00
|
|
|
nfds,
|
|
|
|
|
(fd_set*)readfds,
|
|
|
|
|
(fd_set*)writefds,
|
|
|
|
|
(fd_set*)exceptfds,
|
|
|
|
|
(timeval*)timeout);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-07-12 11:44:31 -07:00
|
|
|
|
2017-09-22 14:14:14 -07:00
|
|
|
int zts_fcntl(int fd, int cmd, int flags)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2020-05-05 14:35:22 -07:00
|
|
|
return lwip_fcntl(fd, cmd, flags);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-09-22 14:14:14 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_poll(struct zts_pollfd* fds, nfds_t nfds, int timeout)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
return lwip_poll((pollfd*)fds, nfds, timeout);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_ioctl(int fd, unsigned long request, void* argp)
|
2017-08-02 14:39:21 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! argp) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_ioctl(fd, request, argp);
|
2017-08-02 14:39:21 -07:00
|
|
|
}
|
2019-01-14 12:01:29 -08:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_send(int fd, const void* buf, size_t len, int flags)
|
2019-01-14 12:01:29 -08:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! buf) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_send(fd, buf, len, flags);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-08-02 14:39:21 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_sendto(
|
|
|
|
|
int fd,
|
|
|
|
|
const void* buf,
|
|
|
|
|
size_t len,
|
|
|
|
|
int flags,
|
|
|
|
|
const struct zts_sockaddr* addr,
|
|
|
|
|
zts_socklen_t addrlen)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! addr || ! buf) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-03-24 12:20:39 -07:00
|
|
|
if (addrlen > (int)sizeof(struct zts_sockaddr_storage)
|
2021-04-17 23:46:21 -07:00
|
|
|
|| addrlen < (int)sizeof(struct zts_sockaddr_in)) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_ARG;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_sendto(fd, buf, len, flags, (sockaddr*)addr, addrlen);
|
2017-09-22 14:14:14 -07:00
|
|
|
}
|
2017-08-18 07:43:29 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_sendmsg(int fd, const struct zts_msghdr* msg, int flags)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return lwip_sendmsg(fd, (const struct msghdr*)msg, flags);
|
2017-09-22 14:14:14 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_recv(int fd, void* buf, size_t len, int flags)
|
2017-08-18 07:43:29 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! buf) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_recv(fd, buf, len, flags);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-08-18 07:43:29 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_recvfrom(
|
|
|
|
|
int fd,
|
|
|
|
|
void* buf,
|
|
|
|
|
size_t len,
|
|
|
|
|
int flags,
|
|
|
|
|
struct zts_sockaddr* addr,
|
|
|
|
|
zts_socklen_t* addrlen)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! buf) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return lwip_recvfrom(fd, buf, len, flags, (sockaddr*)addr, (socklen_t*)addrlen);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-04-14 17:23:28 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_recvmsg(int fd, struct zts_msghdr* msg, int flags)
|
2017-04-14 17:23:28 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! msg) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return lwip_recvmsg(fd, (struct msghdr*)msg, flags);
|
2017-09-22 14:14:14 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_read(int fd, void* buf, size_t len)
|
2017-09-29 15:37:50 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! buf) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_read(fd, buf, len);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-09-22 14:14:14 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_readv(int fd, const struct zts_iovec* iov, int iovcnt)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-03-24 12:20:39 -07:00
|
|
|
return lwip_readv(fd, (iovec*)iov, iovcnt);
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_write(int fd, const void* buf, size_t len)
|
2017-09-29 15:37:50 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! buf) {
|
2021-03-14 01:02:43 -08:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2020-05-01 19:15:38 -07:00
|
|
|
return lwip_write(fd, buf, len);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-09-22 14:14:14 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
ssize_t zts_writev(int fd, const struct zts_iovec* iov, int iovcnt)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
return lwip_writev(fd, (iovec*)iov, iovcnt);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-22 14:14:14 -07:00
|
|
|
int zts_shutdown(int fd, int how)
|
2017-07-12 11:44:31 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
return lwip_shutdown(fd, how);
|
2019-01-14 12:01:29 -08:00
|
|
|
}
|
2017-08-24 11:45:39 -07:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
struct zts_hostent* zts_gethostbyname(const char* name)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-16 00:31:45 -07:00
|
|
|
return NULL;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! name) {
|
2021-03-16 00:31:45 -07:00
|
|
|
return NULL;
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return (struct zts_hostent*)lwip_gethostbyname(name);
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_dns_set_server(uint8_t index, const zts_ip_addr* addr)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2020-05-01 19:15:38 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-03-16 00:31:45 -07:00
|
|
|
if (index >= DNS_MAX_SERVERS) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! addr) {
|
2021-03-16 00:31:45 -07:00
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
dns_setserver(index, (const ip_addr_t*)addr);
|
2021-03-16 00:31:45 -07:00
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
const zts_ip_addr* zts_dns_get_server(uint8_t index)
|
2021-03-16 00:31:45 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-16 00:31:45 -07:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if (index >= DNS_MAX_SERVERS) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return (const zts_ip_addr*)dns_getserver(index);
|
2021-03-16 00:31:45 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
char* zts_ipaddr_ntoa(const zts_ip_addr* addr)
|
2021-03-16 00:31:45 -07:00
|
|
|
{
|
2021-04-17 23:46:21 -07:00
|
|
|
return ipaddr_ntoa((ip_addr_t*)addr);
|
2021-03-16 00:31:45 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_ipaddr_aton(const char* cp, zts_ip_addr* addr)
|
2021-03-16 00:31:45 -07:00
|
|
|
{
|
2021-04-17 23:46:21 -07:00
|
|
|
return ipaddr_aton(cp, (ip_addr_t*)addr);
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
const char* zts_inet_ntop(int family, const void* src, char* dst, zts_socklen_t size)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-17 23:46:21 -07:00
|
|
|
return lwip_inet_ntop(family, src, dst, size);
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
int zts_inet_pton(int family, const char* src, void* dst)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-17 23:46:21 -07:00
|
|
|
return lwip_inet_pton(family, src, dst);
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_util_ipstr_to_saddr(
|
|
|
|
|
const char* src_ipstr,
|
2021-04-17 23:46:21 -07:00
|
|
|
int port,
|
|
|
|
|
struct zts_sockaddr* dest_addr,
|
|
|
|
|
zts_socklen_t* addrlen)
|
|
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
int family = zts_util_get_ip_family(src_ipstr);
|
|
|
|
|
|
2021-03-24 12:20:39 -07:00
|
|
|
if (family == ZTS_AF_INET) {
|
|
|
|
|
struct zts_sockaddr_in in4;
|
|
|
|
|
in4.sin_port = htons(port);
|
|
|
|
|
in4.sin_family = family;
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
|
zts_inet_pton(family, src_ipstr, &(in4.sin_addr.S_addr));
|
|
|
|
|
#else
|
|
|
|
|
zts_inet_pton(family, src_ipstr, &(in4.sin_addr.s_addr));
|
|
|
|
|
#endif
|
2021-04-17 23:46:21 -07:00
|
|
|
dest_addr = (struct zts_sockaddr*)&in4;
|
2021-03-24 12:20:39 -07:00
|
|
|
*addrlen = sizeof(in4);
|
|
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
if (family == ZTS_AF_INET6) {
|
|
|
|
|
struct zts_sockaddr_in6 in6;
|
|
|
|
|
in6.sin6_port = htons(port);
|
|
|
|
|
in6.sin6_family = family;
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
|
zts_inet_pton(family, src_ipstr, &(in6.sin6_addr));
|
|
|
|
|
#else
|
|
|
|
|
zts_inet_pton(family, src_ipstr, &(in6.sin6_addr));
|
|
|
|
|
#endif
|
2021-04-17 23:46:21 -07:00
|
|
|
dest_addr = (struct zts_sockaddr*)&in6;
|
2021-03-24 12:20:39 -07:00
|
|
|
*addrlen = sizeof(in6);
|
|
|
|
|
return ZTS_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
// Convenience functions //
|
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
|
|
/**
|
2021-04-17 23:46:21 -07:00
|
|
|
* Helper functions that simplify API wrapper generation and usage in other
|
2021-04-22 11:20:04 -07:00
|
|
|
* 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.
|
2021-04-17 23:46:21 -07:00
|
|
|
*/
|
2021-03-24 12:20:39 -07:00
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_no_delay(int fd, int enabled)
|
2021-04-17 23:46:21 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (enabled != 0 && enabled != 1) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return zts_setsockopt(fd, ZTS_IPPROTO_TCP, ZTS_TCP_NODELAY, (void*)&enabled, sizeof(int));
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_no_delay(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
int err, optval = 0;
|
|
|
|
|
zts_socklen_t len = sizeof(optval);
|
2021-04-17 23:46:21 -07:00
|
|
|
if ((err = zts_getsockopt(fd, ZTS_IPPROTO_TCP, ZTS_TCP_NODELAY, (void*)&optval, &len)) < 0) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
return optval != 0;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_linger(int fd, int enabled, int value)
|
2021-04-17 23:46:21 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (enabled != 0 && enabled != 1) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
if (value < 0) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
struct zts_linger linger;
|
|
|
|
|
linger.l_onoff = enabled;
|
|
|
|
|
linger.l_linger = value;
|
2021-04-17 23:46:21 -07:00
|
|
|
return zts_setsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_LINGER, (void*)&linger, sizeof(linger));
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_linger_enabled(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
struct zts_linger linger;
|
|
|
|
|
zts_socklen_t len = sizeof(linger);
|
2021-04-22 11:20:04 -07:00
|
|
|
int err;
|
2021-04-17 23:46:21 -07:00
|
|
|
if ((err = zts_getsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_LINGER, (void*)&linger, &len)) < 0) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
return linger.l_onoff;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_linger_value(int fd)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
struct zts_linger linger;
|
|
|
|
|
zts_socklen_t len = sizeof(linger);
|
2021-04-22 11:20:04 -07:00
|
|
|
int err;
|
2021-04-17 23:46:21 -07:00
|
|
|
if ((err = zts_getsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_LINGER, (void*)&linger, &len)) < 0) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
return linger.l_linger;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_reuse_addr(int fd, int enabled)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (enabled != 0 && enabled != 1) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return zts_setsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_REUSEADDR, (void*)&enabled, sizeof(enabled));
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_reuse_addr(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-22 11:20:04 -07:00
|
|
|
int err, optval = 0;
|
2021-03-24 12:20:39 -07:00
|
|
|
zts_socklen_t optlen = sizeof(optval);
|
2021-04-17 23:46:21 -07:00
|
|
|
if ((err = zts_getsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_REUSEADDR, (void*)&optval, &optlen)) < 0) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
return optval != 0;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_recv_timeout(int fd, int seconds, int microseconds)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (seconds < 0 || microseconds < 0) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
struct timeval tv;
|
|
|
|
|
tv.tv_sec = seconds;
|
|
|
|
|
tv.tv_usec = microseconds;
|
2021-04-17 23:46:21 -07:00
|
|
|
return zts_setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void*)&tv, sizeof(tv));
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_recv_timeout(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
struct timeval tv;
|
|
|
|
|
zts_socklen_t optlen = sizeof(tv);
|
|
|
|
|
int err;
|
2021-04-17 23:46:21 -07:00
|
|
|
if ((err = zts_getsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void*)&tv, &optlen)) < 0) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return err;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return tv.tv_sec; // TODO microseconds
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_send_timeout(int fd, int seconds, int microseconds)
|
2020-05-01 19:15:38 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (seconds < 0 || microseconds < 0) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
struct timeval tv;
|
|
|
|
|
tv.tv_sec = seconds;
|
|
|
|
|
tv.tv_usec = microseconds;
|
2021-04-17 23:46:21 -07:00
|
|
|
return zts_setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (void*)&tv, sizeof(tv));
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_send_timeout(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
struct zts_timeval tv;
|
|
|
|
|
zts_socklen_t optlen = sizeof(tv);
|
|
|
|
|
int err;
|
2021-04-17 23:46:21 -07:00
|
|
|
if ((err = zts_getsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (void*)&tv, &optlen)) < 0) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return err;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return tv.tv_sec; // TODO microseconds
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_send_buf_size(int fd, int size)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (size < 0) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return zts_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&size, sizeof(int));
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_send_buf_size(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
int err, optval = 0;
|
|
|
|
|
zts_socklen_t optlen = sizeof(optval);
|
2021-04-17 23:46:21 -07:00
|
|
|
if ((err = zts_getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&optval, &optlen)) < 0) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
return optval;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_recv_buf_size(int fd, int size)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (size < 0) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return zts_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&size, sizeof(int));
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_recv_buf_size(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
int err, optval = 0;
|
|
|
|
|
zts_socklen_t optlen = sizeof(optval);
|
2021-04-17 23:46:21 -07:00
|
|
|
if ((err = zts_getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&optval, &optlen)) < 0) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
return optval;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_ttl(int fd, int ttl)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (ttl < 0 || ttl > 255) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
return zts_setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_ttl(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
int err, ttl = 0;
|
|
|
|
|
zts_socklen_t optlen = sizeof(ttl);
|
|
|
|
|
if ((err = zts_getsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, &optlen)) < 0) {
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
return ttl;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_blocking(int fd, int enabled)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (enabled != 0 && enabled != 1) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
int flags = zts_fcntl(fd, ZTS_F_GETFL, 0);
|
2021-04-17 23:46:21 -07:00
|
|
|
if (! enabled) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return zts_fcntl(fd, ZTS_F_SETFL, flags | ZTS_O_NONBLOCK);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// Default
|
|
|
|
|
return zts_fcntl(fd, ZTS_F_SETFL, flags & (~ZTS_O_NONBLOCK));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_blocking(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
int flags = zts_fcntl(fd, ZTS_F_GETFL, 0);
|
|
|
|
|
if (flags < 0) {
|
|
|
|
|
return flags;
|
|
|
|
|
}
|
2021-04-17 23:46:21 -07:00
|
|
|
return ! (flags & ZTS_O_NONBLOCK);
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_set_keepalive(int fd, int enabled)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
|
|
|
|
if (enabled != 0 && enabled != 1) {
|
|
|
|
|
return ZTS_ERR_ARG;
|
|
|
|
|
}
|
|
|
|
|
int keepalive = enabled;
|
2021-04-17 23:46:21 -07:00
|
|
|
return zts_setsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_KEEPALIVE, &keepalive, sizeof(keepalive));
|
2021-03-24 12:20:39 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 11:20:04 -07:00
|
|
|
int zts_simple_get_keepalive(int fd)
|
2021-03-24 12:20:39 -07:00
|
|
|
{
|
2021-04-22 11:20:04 -07:00
|
|
|
if (! transport_ok()) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return ZTS_ERR_SERVICE;
|
|
|
|
|
}
|
2021-04-22 11:20:04 -07:00
|
|
|
int err, optval = 0;
|
2021-03-24 12:20:39 -07:00
|
|
|
zts_socklen_t optlen = sizeof(optval);
|
2021-04-17 23:46:21 -07:00
|
|
|
if ((err = zts_getsockopt(fd, ZTS_SOL_SOCKET, ZTS_SO_KEEPALIVE, (void*)&optval, &optlen)) < 0) {
|
2021-03-24 12:20:39 -07:00
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
return optval != 0;
|
2020-05-01 19:15:38 -07:00
|
|
|
}
|
|
|
|
|
|
2017-04-06 19:16:01 -07:00
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
2017-09-27 13:42:27 -07:00
|
|
|
#endif
|
2019-02-06 22:00:39 -08:00
|
|
|
|
2021-04-17 23:46:21 -07:00
|
|
|
} // namespace ZeroTier
|