/* ==========================================================================
* libevnet/src/socket.h - Network server library for libevent.
* --------------------------------------------------------------------------
* Copyright (c) 2006 William Ahern
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
* ==========================================================================
*/
#ifndef EVNET_SOCKET_H
#define EVNET_SOCKET_H
#include <string.h> /* strerror(3) */
#include <sys/types.h> /* mode_t socklen_t */
#include <sys/time.h> /* struct timeval */
#ifndef _WIN32
#include <sys/socket.h> /* struct sockaddr struct sockaddr_storage */
#include <sys/un.h> /* struct sockaddr_un */
#include <netinet/in.h> /* struct sockaddr_in struct sockaddr_in6 */
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#ifndef SOCKET
#define SOCKET int
#endif
struct event_base;
struct arena_prototype;
struct tls_identity;
struct tls;
struct bufio_source;
struct bufio_sink;
#define SOCKET_SA_P(s) ((struct sockaddr *)(s))
#if !_WIN32
#if USE_IPV6
#define SOCKET_SA_LENOF(s) \
( (SOCKET_SA_P(s)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
: (SOCKET_SA_P(s)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
: (SOCKET_SA_P(s)->sa_family == AF_UNIX) ? sizeof(struct sockaddr_un) \
: 0 )
#else
#define SOCKET_SA_LENOF(s) \
( (SOCKET_SA_P(s)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
: (SOCKET_SA_P(s)->sa_family == AF_UNIX) ? sizeof(struct sockaddr_un) \
: 0 )
#endif /* USE_IPV6 */
#else
#if USE_UPV6
#define SOCKET_SA_LENOF(s) \
( (SOCKET_SA_P(s)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
: (SOCKET_SA_P(s)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
: 0 )
#else
#define SOCKET_SA_LENOF(s) \
( (SOCKET_SA_P(s)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \
: 0 )
#endif /* USE_IPV6 */
#endif /* !_WIN32 */
#define SOCKET_UN_P(s) ((struct sockaddr_un *)(s))
enum socket_errno {
SOCKET_ESUCCESS,
SOCKET_ESYSTEM,
SOCKET_ETIMEDOUT,
SOCKET_ECANCELLED,
SOCKET_ENOTFOUND,
SOCKET_ENOTLS,
SOCKET_ENOTCONNECTED,
}; /* enum socket_errno */
extern const char *socket_errlist[];
extern const int socket_nerr;
enum socket_mode {
SOCKET_MODE_NONE,
SOCKET_MODE_SERVER,
SOCKET_MODE_CLIENT,
}; /* enum socket_mode */
struct socket_name {
void *type;
union {
struct sockaddr sa;
struct sockaddr_storage ss;
struct sockaddr_in sin;
#if USE_IPV6
struct sockaddr_in6 sin6;
#endif
#ifndef _WIN32
struct sockaddr_un sun;
#endif
} addr;
struct {
char name[256];
char port[32]; /* More than enough for +/-2^64 in decimal. */
int rtype;
int flags;
} host;
#ifndef _WIN32
struct {
char path[sizeof (((struct sockaddr_un *)0)->sun_path)];
} local;
#endif
}; /* struct socket_name */
struct socket_info {
struct {
union {
struct sockaddr_in sin;
#if USE_IPV6
struct sockaddr_in6 sin6;
#endif
#ifndef _WIN32
struct sockaddr_un sun;
#endif
struct sockaddr_storage ss;
} sa;
socklen_t salen;
} peer, self;
struct tls *tls;
}; /* struct socket_info */
extern const struct socket_options {
mode_t sun_mask;
int sun_unlink;
#if _WIN32
BOOL sa_reuseaddr;
#else
int sa_reuseaddr;
#endif
int so_type;
int so_nonblock;
int so_backlog;
#if _WIN32
BOOL so_nodelay;
#else
int so_nodelay;
#endif
int sin_resolv;
} socket_defaults;
struct socket;
struct socket *socket_open(struct socket_name *, const struct socket_options *, struct event_base *, const struct arena_prototype *, enum socket_errno *so_errno);
void socket_cancel(struct socket *, int);
void socket_close(struct socket *);
void socket_enable_tls(struct socket *, struct tls_identity *);
void socket_start_tls(struct socket *, struct tls_identity *, void (*)(struct socket *, enum socket_errno, void *), void *, struct timeval *);
void socket_getsockinfo(struct socket *, SOCKET *, struct tls **);
void socket_discard(struct socket *, SOCKET *, struct tls **);
struct bufio_source *socket_to_source(struct socket *s);
struct bufio_sink *socket_to_sink(struct socket *s);
enum socket_errno socket_getpeername(struct socket *, struct sockaddr *, socklen_t *, const char **);
enum socket_errno socket_getsockname(struct socket *, struct sockaddr *, socklen_t *, const char **);
enum socket_errno socket_setsockstate(struct socket *, SOCKET, enum socket_mode);
enum socket_errno socket_errno(struct socket *);
const char *socket_strerror(enum socket_errno);
const char *socket_errstring(struct socket *);
#define SOCKET_SO_TYPE so_type
#define SOCKET_SO_NONBLOCK so_nonblock
#define SOCKET_SO_MODE so_mode
#define so_paste(a, b) a##b
#define socket_getoption(s, t, p) so_paste(socket_getoption_, t)((s), (p))
void socket_getoption_so_type(struct socket *, int *);
void socket_getoption_so_nonblock(struct socket *, int *);
void socket_getoption_so_mode(struct socket *, enum socket_mode *);
typedef void (*socket_accept_cb)(struct socket *, struct socket *, enum socket_errno, void *);
void socket_accept(struct socket *, socket_accept_cb, void *, struct timeval *);
typedef void (*socket_connect_cb)(struct socket *, enum socket_errno, void *);
void socket_connect(struct socket *, socket_connect_cb, void *, struct timeval *);
struct socket_name *socket_name_init_addr(struct socket_name *dst, const struct sockaddr *src, socklen_t srclen);
struct socket_name *socket_name_init_host(struct socket_name *dst, const char *src, const char *port, int rr, int flags);
struct socket_name *socket_name_init_unix(struct socket_name *dst, const char *src);
#endif /* EVNET_SOCKET_H */
syntax highlighted by Code2HTML, v. 0.9.1