/* ========================================================================== * 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 /* strerror(3) */ #include /* mode_t socklen_t */ #include /* struct timeval */ #ifndef _WIN32 #include /* struct sockaddr struct sockaddr_storage */ #include /* struct sockaddr_un */ #include /* struct sockaddr_in struct sockaddr_in6 */ #else #include #include #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 */