/*
 * socklib.h
 *
 * Handy functions for IPv4 socket sonnections.
 *
 * Limitations:
 * These are for the simplest case, as the recommended approach
 * is to integrate the sock_connect() timeout inside the main
 * loop as to don't be blocking.
 *
 * Documentation used:
 *   http://www.beej.us/guide/bgnet/output/html/multipage/getaddrinfoman.html
 *
 * Author: Dario Rodriguez dario@softhome.net
 * This file is licensed under the terms of the GNU LGPL v2+
 */

#ifndef SOCKLIB_H
#define SOCKLIB_H
#include <sys/select.h> /* fd_set */

typedef void sselect;

char *ipv4_genip(char *hostname, long *resulthostsize);
int ipv4_genport(char *portname, int fallback);
int ipv4_preconnect(char *host, long hostsize, int port); /* setup socket, set non-blocking, connect(2) call */
int ipv4_connect(int fd, long timeoutmsec); /* tests writeability */
int ipv4_postconnect(int fd); /* hopefully connect(2) suceeded, set blocking */
int ipv4_server(int port);
int ipv4_serverbinded(char *host, long hostsize, int port);
int sock_accept(int fd);
int sock_getinfo(int fd, int *iplen, char *ip, int *port); /* ip must be at least 16 bytes to have room for an ipv6 address */
int sock_queued(int fd);
int sock_setblocking(int fd, int block);
int sock_readable(int fd);

sselect *sselect_init(void);
void sselect_free(sselect *ssel);
int sselect_reset(sselect *ssel);
int sselect_addread(sselect *ssel, int fd, void *userptr);
int sselect_addwrite(sselect *ssel, int fd, void *userptr);
int sselect_delread(sselect *ssel, int fd);
int sselect_delwrite(sselect *ssel, int fd);
int sselect_wait(sselect *ssel, int ms);
int sselect_getread(sselect *ssel, int *fds, int sizefds);
int sselect_getwrite(sselect *ssel, int *fds, int sizefds);
void *sselect_getuserptr(sselect *ssel, int fd);

/* advanced sselect functions */
int sselect_getreadfiltered(sselect *ssel, fd_set *filter, int *fds, int sizefds);
int sselect_getwritefiltered(sselect *ssel, fd_set *filter, int *fds, int sizefds);

/* socket configuration functions */
void sock_setfast(int fd); /* mark as low-bandwidth interactive stream */
void sock_setunsafe(int fd); /* for server sockets, configure reuseaddress, linger: only suitable for intranet usage */
void sock_setsafe(int fd); /* for non-server sockets, configure reuseaddress, linger: make them suitable for internet usage */

#endif