#pragma once
#include "common.hpp"
#include "config.hpp"
#include "test.hpp"
#include <sys/socket.h>
#include <netinet/in.h>
#ifndef SO_ORIGINAL_DST
#define SO_ORIGINAL_DST 80
#endif
#define ADDRSTRLEN cstrlen("0000:0000:0000:0000:0000:0000:0000:0000:12345")+1
typedef union sockaddr_u {
sa_family_t family; // for convenience
struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
INLINE bool operator==(const sockaddr_u& that) const {
return (memcmp(this, &that, sizeof(sockaddr_u)) == 0);
}
INLINE bool operator>=(const sockaddr_u& that) const {
return family && family == that.family && family == AF_INET?
(htonl(addr4.sin_addr.s_addr) >= htonl(that.addr4.sin_addr.s_addr)):
false; // TODO: (memcmp(&addr6.sin6_addr, &that.addr6.sin6_addr, sizeof(struct in6_addr)) >= 0);
}
INLINE bool operator<=(const sockaddr_u& that) const {
return family && family == that.family && family == AF_INET?
(htonl(addr4.sin_addr.s_addr) <= htonl(that.addr4.sin_addr.s_addr)):
false; // TODO: (memcmp(&addr6.sin6_addr, &that.addr6.sin6_addr, sizeof(struct in6_addr)) <= 0);
}
bool apply_mask_lower(unsigned);
bool apply_mask_upper(unsigned);
} sockaddr_t;
typedef char ip_str_t[INET6_ADDRSTRLEN];
char* addr2str(const sockaddr_t&, char*, bool port); ///< w/ port, returns \0 pointer, requires at least #ADDRSTRLEN
const char* addr2str(const sockaddr_t&, bool port=false); ///< returns static pointer
bool str2addr(const char*, sockaddr_t&); ///< parses ipv4:port string
sockaddr_t str2addr(const char*);
ssize_t peek(int, char**); ///< peeks from socket to static buffer
void read_empty(int); ///< read all available data in order to prevent sending RST to the client upon close() with a non-empty receive-queue. should be immediately followed by close().
int uds_listen(const char*); ///< creates blocking listening UDS
int uds_connect(const char*); ///< non-blocking connect to UDS
int socket_listen(in_port_t); ///< non-blocking any listening socket fd on given port or -1
int socket_accept(int, sockaddr_t&, sockaddr_t&);
int socket_connect(const sockaddr_t* src, const sockaddr_t* dst);
bool find_mac(const char*);