#ifndef SOCK_H
#define SOCK_H
/*
* Low-level socket-related functions
*/
#include "error.h"
#include <sys/types.h>
#include <event2/event.h>
/*
* The generic socket handle
*/
struct sock_stream;
/*
* Async callbacks for socket operation
*/
struct sock_stream_callbacks {
/* Sockeet is readable */
void (*on_read)(struct sock_stream *sock, void *arg);
/* Socket is writeable */
void (*on_write)(struct sock_stream *sock, void *arg);
};
/*
* Initialize the socket module's global state. Call this before calling any other sock_* functions.
*
* The given \a ev_base is the libevent base to use for nonblocking operation.
*/
err_t sock_init (struct event_base *ev_base, struct error_info *err);
/*
* A simple blocking TCP connect to the given host/service, using getaddrinfo. The connected socket is returned via
* *sock_ptr. In case of errors, additional error information is stored in *err.
*
* @return zero on success, nonzero on error
*
* XXX: blocking
*/
err_t sock_tcp_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err);
/*
* A simple blocking SSL connect to the given host/service. The connected/handshake'd SSL socket is returned via
* *sock_ptr. In case of errors, additional error information is stored in *err.
*
* XXX: blocking
* XXX: doesn't do any certificate verification.
*/
err_t sock_gnutls_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err);
/*
* The generic read/write API for stream sockets. These are mostly identical to the equivalent read/write syscalls, but
* the handling of EOF and EAGAIN is different. Normally, these return the (positive) number of bytes written. For
* EAGAIN, these return zero. For EOF, these return -ERR_READ_EOF/ERR_WRITE_EOF. Otherwise, these return the -ERR_*
* code.
*/
int sock_stream_read (struct sock_stream *sock, void *buf, size_t len);
int sock_stream_write (struct sock_stream *sock, const void *buf, size_t len);
/*
* Initialize event-based operation for this sock_stream. This will set the stream into nonblocking mode, and the given
* callbacks will be fired once enabled using sock_stream_event_enable().
*
* Note that the callbacks struct isn't copied - it's used as-is-given.
*/
err_t sock_stream_event_init (struct sock_stream *sock, const struct sock_stream_callbacks *callbacks, void *arg);
/*
* Enable the events for this sock, as set up earlier with event_init. Mask should contain EV_READ/EV_WRITE.
*
* The implementation of this is slightly hazy for complex protocols; this should only be used to map from
* sock_stream_read/write to the corresponding sock_stream_callback. That is, if sock_stream_read returns zero, then
* call event_enable(EV_READ), wherepon on_read will later be called.
*/
err_t sock_stream_event_enable (struct sock_stream *sock, short mask);
/**
* Get current error_info for \a sock.
*/
const struct error_info* sock_stream_error (struct sock_stream *sock);
#endif