#ifndef SOCK_HPP_
#define SOCK_HPP_
#include "poll.hpp"
#include "common.hpp"
#include <netinet/in.h>
#include <vector>


#ifndef SOCK_KEEPALIVE
#define SOCK_KEEPALIVE 1 // additionally enable/disable tcp keepalive for early down clients detection and preventing e.g. NAT timeouts
#endif

typedef char ip_str_t[INET6_ADDRSTRLEN+cstrlen(":65535")+1];


typedef struct {
    void (*pre_accept_handler)(int, const ip_str_t);
    void (*accept_handler)(int, const ip_str_t);
    ssize_t (*read_handler)(int, void*, size_t);
    ssize_t (*write_handler)(int, const void*, size_t);
    int (*close_handler)(int);
} io_handlers_t;

extern io_handlers_t io_handlers;


int socket_listen(in_port_t); ///< non-blocking any listening socket on given port
bool socket_listen(std::vector<int>&);
void socket_accept(int, event_t); ///< accepts new non-blocking connections, sets options, and calls io_handlers


extern volatile int SHUTDOWN;
void register_signals(); ///< catch signals and set #SHUTDOWN (once)

bool goto_jail(const char* user, const char* path); ///< chroot() and drop root to other user


#endif