diff options
Diffstat (limited to 'src/net.h')
-rw-r--r-- | src/net.h | 128 |
1 files changed, 105 insertions, 23 deletions
@@ -25,6 +25,11 @@ #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 { @@ -42,43 +47,120 @@ enum perf_net_mode { sock_pipe, sock_udp, sock_tcp, - sock_tls + sock_dot }; +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: An error occurred, see errno + * - EINPROGRESS: socket is still sending + * 0: Socket is not ready, may still be connecting or negotiating + * 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_connect, + perf_socket_event_reconnect +} 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); + struct perf_net_socket { - enum perf_net_mode mode; - int fd, have_more, is_ready, flags, is_ssl_ready; - char* recvbuf; - size_t at, sending; - char* sendbuf; - struct sockaddr_storage dest_addr; - socklen_t addrlen; - SSL* ssl; - pthread_mutex_t lock; + 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; + + /* + * 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; }; -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 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); +} -ssize_t perf_net_recv(struct perf_net_socket* sock, void* buf, size_t len, int flags); -ssize_t perf_net_sendto(struct perf_net_socket* sock, const void* buf, size_t len, int flags, - const struct sockaddr* dest_addr, socklen_t addrlen); +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); +} -int perf_net_close(struct perf_net_socket* sock); -int perf_net_sockeq(struct perf_net_socket* sock_a, struct perf_net_socket* 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); -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, int bufsize); +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); -enum perf_net_mode perf_net_parsemode(const char* mode); +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); -int perf_net_sockready(struct perf_net_socket* sock, int pipe_fd, int64_t timeout); +struct perf_net_socket* perf_net_udp_opensocket(const perf_sockaddr_t*, const perf_sockaddr_t*, size_t); +struct perf_net_socket* perf_net_tcp_opensocket(const perf_sockaddr_t*, const perf_sockaddr_t*, size_t); +struct perf_net_socket* perf_net_dot_opensocket(const perf_sockaddr_t*, const perf_sockaddr_t*, size_t); #endif |