1
0
Fork 0
dnsperf/src/net.h
Daniel Baumann 07b818f278
Adding upstream version 2.9.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-02-09 09:03:07 +01:00

187 lines
6.9 KiB
C

/*
* Copyright 2019-2021 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PERF_NET_H
#define PERF_NET_H 1
#include <sys/types.h>
#include <sys/socket.h>
#include <openssl/ssl.h>
#include <pthread.h>
#include <netinet/in.h>
#include <assert.h>
#include <stdbool.h>
#define TCP_RECV_BUF_SIZE (16 * 1024)
#define TCP_SEND_BUF_SIZE (4 * 1024)
struct perf_sockaddr {
union {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} sa;
socklen_t length;
};
typedef struct perf_sockaddr perf_sockaddr_t;
enum perf_net_mode {
sock_none,
sock_file,
sock_pipe,
sock_udp,
sock_tcp,
sock_dot,
sock_doh
};
struct perf_net_socket;
typedef ssize_t (*perf_net_recv_t)(struct perf_net_socket* sock, void* buf, size_t len, int flags);
typedef ssize_t (*perf_net_sendto_t)(struct perf_net_socket* sock, uint16_t qid, const void* buf, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addrlen);
typedef int (*perf_net_close_t)(struct perf_net_socket* sock);
typedef int (*perf_net_sockeq_t)(struct perf_net_socket* sock, struct perf_net_socket* other);
/* sockready return:
* -1: socket readiness timed out / canceled / interrupted or unknown error
* 0: Socket is not ready, may still be connecting, negotiating or sending
* 1: Socket is ready and can be used for sending to
*/
typedef int (*perf_net_sockready_t)(struct perf_net_socket* sock, int pipe_fd, int64_t timeout);
/* Indicates if there are more data to be read in buffers of the transport */
typedef bool (*perf_net_have_more_t)(struct perf_net_socket* sock);
/* Callback for when a query has been sent if it was delayed due to partily sent or reconnection */
typedef void (*perf_net_sent_cb_t)(struct perf_net_socket* sock, uint16_t qid);
typedef enum perf_socket_event {
perf_socket_event_connecting,
perf_socket_event_connected,
perf_socket_event_reconnecting,
perf_socket_event_reconnected
} perf_socket_event_t;
/* Callback for socket events related to connection oriented protocols, for statistics */
typedef void (*perf_net_event_cb_t)(struct perf_net_socket* sock, perf_socket_event_t event, uint64_t elapsed_time);
typedef void (*perf_net_num_queries_per_conn_t)(struct perf_net_socket* sock, size_t num_queries_per_conn, size_t timeout);
struct perf_net_socket {
void* data; /* user data */
enum perf_net_mode mode;
perf_net_recv_t recv;
perf_net_sendto_t sendto;
perf_net_close_t close;
perf_net_sockeq_t sockeq;
perf_net_sockready_t sockready;
perf_net_have_more_t have_more;
perf_net_num_queries_per_conn_t num_queries_per_conn;
/*
* Not set by protocol, set by caller.
* May be 0 if caller don't care.
* MUST NOT be called from sendto(), only called if query is delayed in some way.
*/
perf_net_sent_cb_t sent;
/* Used if caller want info on connection oriented events */
perf_net_event_cb_t event;
/*
* The system file descriptor that is used for transport, this is used
* in os functions to poll/wait for read/write.
*/
int fd;
};
static inline ssize_t perf_net_recv(struct perf_net_socket* sock, void* buf, size_t len, int flags)
{
return sock->recv(sock, buf, len, flags);
}
static inline ssize_t perf_net_sendto(struct perf_net_socket* sock, uint16_t qid, const void* buf, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addrlen)
{
return sock->sendto(sock, qid, buf, len, flags, dest_addr, addrlen);
}
static inline int perf_net_close(struct perf_net_socket* sock)
{
return sock->close(sock);
}
static inline int perf_net_sockeq(struct perf_net_socket* sock_a, struct perf_net_socket* sock_b)
{
assert(sock_a);
assert(sock_b);
assert(sock_a->mode == sock_b->mode);
return sock_a->sockeq(sock_a, sock_b);
}
static inline int perf_net_sockready(struct perf_net_socket* sock, int pipe_fd, int64_t timeout)
{
return sock->sockready(sock, pipe_fd, timeout);
}
static inline int perf_net_have_more(struct perf_net_socket* sock)
{
return sock->have_more ? sock->have_more(sock) : false;
}
enum perf_net_mode perf_net_parsemode(const char* mode);
int perf_net_parsefamily(const char* family);
void perf_net_parseserver(int family, const char* name, unsigned int port, perf_sockaddr_t* addr);
void perf_net_parselocal(int family, const char* name, unsigned int port, perf_sockaddr_t* addr);
void perf_sockaddr_fromin(perf_sockaddr_t* sockaddr, const struct in_addr* in, in_port_t port);
void perf_sockaddr_fromin6(perf_sockaddr_t* sockaddr, const struct in6_addr* in, in_port_t port);
in_port_t perf_sockaddr_port(const perf_sockaddr_t* sockaddr);
void perf_sockaddr_setport(perf_sockaddr_t* sockaddr, in_port_t port);
void perf_sockaddr_format(const perf_sockaddr_t* sockaddr, char* buf, size_t len);
static inline int perf_sockaddr_isinet6(const perf_sockaddr_t* sockaddr)
{
return sockaddr->sa.sa.sa_family == AF_INET6;
}
struct perf_net_socket* perf_net_opensocket(enum perf_net_mode mode, const perf_sockaddr_t* server, const perf_sockaddr_t* local, unsigned int offset, size_t bufsize, void* data, perf_net_sent_cb_t sent, perf_net_event_cb_t event);
struct perf_net_socket* perf_net_udp_opensocket(const perf_sockaddr_t*, const perf_sockaddr_t*, size_t, void* data, perf_net_sent_cb_t sent, perf_net_event_cb_t event);
struct perf_net_socket* perf_net_tcp_opensocket(const perf_sockaddr_t*, const perf_sockaddr_t*, size_t, void* data, perf_net_sent_cb_t sent, perf_net_event_cb_t event);
struct perf_net_socket* perf_net_dot_opensocket(const perf_sockaddr_t*, const perf_sockaddr_t*, size_t, void* data, perf_net_sent_cb_t sent, perf_net_event_cb_t event);
struct perf_net_socket* perf_net_doh_opensocket(const perf_sockaddr_t*, const perf_sockaddr_t*, size_t, void* data, perf_net_sent_cb_t sent, perf_net_event_cb_t event);
#define DEFAULT_DOH_URI "https://localhost/dns-query"
#define DEFAULT_DOH_METHOD "GET"
void perf_net_doh_parse_uri(const char*);
void perf_net_doh_parse_method(const char*);
void perf_net_doh_set_max_concurrent_streams(size_t);
void perf_net_stats_init(enum perf_net_mode);
void perf_net_stats_compile(enum perf_net_mode, struct perf_net_socket*);
void perf_net_stats_print(enum perf_net_mode);
void perf_net_doh_stats_init();
void perf_net_doh_stats_compile(struct perf_net_socket*);
void perf_net_doh_stats_print();
#endif