Path: blob/main/crypto/krb5/src/include/port-sockets.h
34889 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1#ifndef _PORT_SOCKET_H2#define _PORT_SOCKET_H3#if defined(_WIN32)45#include <winsock2.h>6#include <ws2tcpip.h>7#include <errno.h>89/* Some of our own infrastructure where the Winsock stuff was too hairy10* to dump into a clean Unix program */1112typedef WSABUF sg_buf;1314#define SG_ADVANCE(SG, N) \15((SG)->len < (N) \16? (abort(), 0) \17: ((SG)->buf += (N), (SG)->len -= (N), 0))1819#define SG_LEN(SG) ((SG)->len + 0)20#define SG_BUF(SG) ((SG)->buf + 0)21#define SG_SET(SG, B, N) ((SG)->buf = (char *)(B),(SG)->len = (N))2223#define SOCKET_INITIALIZE() 024#define SOCKET_CLEANUP()25#define SOCKET_ERRNO (TranslatedWSAGetLastError())26#define SOCKET_SET_ERRNO(x) (TranslatedWSASetLastError(x))27#define SOCKET_NFDS(f) (0) /* select()'s first arg is ignored */28#define SOCKET_READ(fd, b, l) (recv(fd, b, l, 0))29#define SOCKET_WRITE(fd, b, l) (send(fd, b, l, 0))30#define SOCKET_CONNECT connect /* XXX */31#define SOCKET_GETSOCKNAME getsockname /* XXX */32#define SOCKET_CLOSE close /* XXX */33#define SOCKET_EINTR WSAEINTR3435/*36* Return -1 for error or number of bytes written. TMP is a temporary37* variable; must be declared by the caller, and must be used by this macro (to38* avoid compiler warnings).39*/40/* WSASend returns 0 or SOCKET_ERROR. */41#define SOCKET_WRITEV_TEMP DWORD42#define SOCKET_WRITEV(FD, SG, LEN, TMP) \43(WSASend((FD), (SG), (LEN), &(TMP), 0, 0, 0) ? \44(ssize_t)-1 : (ssize_t)(TMP))4546#define SHUTDOWN_READ SD_RECEIVE47#define SHUTDOWN_WRITE SD_SEND48#define SHUTDOWN_BOTH SD_BOTH4950/*51* Define any missing POSIX socket errors. This is for compatibility with52* older versions of MSVC (pre-2010).53*/54#ifndef EINPROGRESS55#define EINPROGRESS WSAEINPROGRESS56#endif57#ifndef EWOULDBLOCK58#define EWOULDBLOCK WSAEWOULDBLOCK59#endif60#ifndef ECONNRESET61#define ECONNRESET WSAECONNRESET62#endif63#ifndef ECONNABORTED64#define ECONNABORTED WSAECONNABORTED65#endif66#ifndef ECONNREFUSED67#define ECONNREFUSED WSAECONNREFUSED68#endif69#ifndef EHOSTUNREACH70#define EHOSTUNREACH WSAEHOSTUNREACH71#endif72#ifndef ETIMEDOUT73#define ETIMEDOUT WSAETIMEDOUT74#endif7576/* Translate posix_error to its Winsock counterpart and set the last Winsock77* error to the result. */78static __inline void TranslatedWSASetLastError(int posix_error)79{80int wsa_error;81switch (posix_error) {82case 0:83wsa_error = 0; break;84case EINPROGRESS:85wsa_error = WSAEINPROGRESS; break;86case EWOULDBLOCK:87wsa_error = WSAEWOULDBLOCK; break;88case ECONNRESET:89wsa_error = WSAECONNRESET; break;90case ECONNABORTED:91wsa_error = WSAECONNABORTED; break;92case ECONNREFUSED:93wsa_error = WSAECONNREFUSED; break;94case EHOSTUNREACH:95wsa_error = WSAEHOSTUNREACH; break;96case ETIMEDOUT:97wsa_error = WSAETIMEDOUT; break;98case EAFNOSUPPORT:99wsa_error = WSAEAFNOSUPPORT; break;100case EINVAL:101wsa_error = WSAEINVAL; break;102default:103/* Ideally, we would log via k5-trace here, but we have no context. */104wsa_error = WSAEINVAL; break;105}106WSASetLastError(wsa_error);107}108109/*110* Translate Winsock errors to their POSIX counterparts. This is necessary for111* MSVC 2010+, where both Winsock and POSIX errors are defined.112*/113static __inline int TranslatedWSAGetLastError(void)114{115int err = WSAGetLastError();116switch (err) {117case 0:118break;119case WSAEINPROGRESS:120err = EINPROGRESS; break;121case WSAEWOULDBLOCK:122err = EWOULDBLOCK; break;123case WSAECONNRESET:124err = ECONNRESET; break;125case WSAECONNABORTED:126err = ECONNABORTED; break;127case WSAECONNREFUSED:128err = ECONNREFUSED; break;129case WSAEHOSTUNREACH:130err = EHOSTUNREACH; break;131case WSAETIMEDOUT:132err = ETIMEDOUT; break;133case WSAEAFNOSUPPORT:134err = EAFNOSUPPORT; break;135case WSAEINVAL:136err = EINVAL; break;137default:138/* Ideally, we would log via k5-trace here, but we have no context. */139err = EINVAL; break;140}141return err;142}143144#elif defined(__palmos__)145146/* If this source file requires it, define struct sockaddr_in (and possibly147* other things related to network I/O). */148149#include "autoconf.h"150#include <netdb.h>151typedef int socklen_t;152153#else /* UNIX variants */154155#include "autoconf.h"156157#include <sys/types.h>158#include <netinet/in.h> /* For struct sockaddr_in and in_addr */159#include <sys/un.h> /* For struct sockaddr_un */160#include <arpa/inet.h> /* For inet_ntoa */161#include <netdb.h>162#include <string.h> /* For memset */163164#ifndef HAVE_NETDB_H_H_ERRNO165extern int h_errno; /* In case it's missing, e.g., HP-UX 10.20. */166#endif167168#include <sys/param.h> /* For MAXHOSTNAMELEN */169#include <sys/socket.h> /* For SOCK_*, AF_*, etc */170#include <sys/time.h> /* For struct timeval */171#include <net/if.h> /* For struct ifconf, for localaddr.c */172#ifdef HAVE_SYS_UIO_H173#include <sys/uio.h> /* For struct iovec, for sg_buf */174#endif175#ifdef HAVE_SYS_FILIO_H176#include <sys/filio.h> /* For FIONBIO on Solaris. */177#endif178179/*180* Either size_t or int or unsigned int is probably right. Under181* SunOS 4, it looks like int is desired, according to the accept man182* page.183*/184#ifndef HAVE_SOCKLEN_T185typedef int socklen_t;186#endif187188#ifndef HAVE_STRUCT_SOCKADDR_STORAGE189struct krb5int_sockaddr_storage {190struct sockaddr_in s;191/* Plenty of slop just in case we get an ipv6 address anyways. */192long extra[16];193};194#define sockaddr_storage krb5int_sockaddr_storage195#endif196197/* Unix equivalents of Winsock calls */198#define SOCKET int199#define INVALID_SOCKET ((SOCKET)~0)200#define closesocket close201#define ioctlsocket ioctl202#define SOCKET_ERROR (-1)203204typedef struct iovec sg_buf;205206#define SG_ADVANCE(SG, N) \207((SG)->iov_len < (N) \208? (abort(), 0) \209: ((SG)->iov_base = (char *) (SG)->iov_base + (N), \210(SG)->iov_len -= (N), 0))211212#define SG_LEN(SG) ((SG)->iov_len + 0)213#define SG_BUF(SG) ((char*)(SG)->iov_base + 0)214#define SG_SET(SG, B, L) ((SG)->iov_base = (char*)(B), (SG)->iov_len = (L))215216#define SOCKET_INITIALIZE() (0) /* No error (or anything else) */217#define SOCKET_CLEANUP() /* nothing */218#define SOCKET_ERRNO errno219#define SOCKET_SET_ERRNO(x) (errno = (x))220#define SOCKET_NFDS(f) ((f)+1) /* select() arg for a single fd */221#define SOCKET_READ read222#define SOCKET_WRITE write223static inline int224socket_connect(int fd, const struct sockaddr *addr, socklen_t addrlen)225{226int st;227#ifdef SO_NOSIGPIPE228int set = 1;229#endif230231st = connect(fd, addr, addrlen);232if (st == -1)233return st;234235#ifdef SO_NOSIGPIPE236st = setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set));237if (st != 0)238st = -1;239#endif240241return st;242}243#define SOCKET_CONNECT socket_connect244#define SOCKET_GETSOCKNAME getsockname245#define SOCKET_CLOSE close246#define SOCKET_EINTR EINTR247#define SOCKET_WRITEV_TEMP int248static inline ssize_t249socket_sendmsg(SOCKET fd, sg_buf *iov, int iovcnt)250{251struct msghdr msg;252int flags = 0;253254#ifdef MSG_NOSIGNAL255flags |= MSG_NOSIGNAL;256#endif257258memset(&msg, 0, sizeof(msg));259msg.msg_iov = iov;260msg.msg_iovlen = iovcnt;261262return sendmsg(fd, &msg, flags);263}264/* Use TMP to avoid compiler warnings and keep things consistent with265* Windows version. */266#define SOCKET_WRITEV(FD, SG, LEN, TMP) \267((TMP) = socket_sendmsg((FD), (SG), (LEN)), (TMP))268269#define SHUTDOWN_READ 0270#define SHUTDOWN_WRITE 1271#define SHUTDOWN_BOTH 2272273#ifndef HAVE_INET_NTOP274#define inet_ntop(AF,SRC,DST,CNT) \275((AF) == AF_INET \276? ((CNT) < 16 \277? (SOCKET_SET_ERRNO(ENOSPC), (const char *)NULL) \278: (sprintf((DST), "%d.%d.%d.%d", \279((const unsigned char *)(const void *)(SRC))[0] & 0xff, \280((const unsigned char *)(const void *)(SRC))[1] & 0xff, \281((const unsigned char *)(const void *)(SRC))[2] & 0xff, \282((const unsigned char *)(const void *)(SRC))[3] & 0xff), \283(DST))) \284: (SOCKET_SET_ERRNO(EAFNOSUPPORT), (const char *)NULL))285#define HAVE_INET_NTOP286#endif287288#endif /* _WIN32 */289290#if !defined(_WIN32)291/* UNIX or ...? */292# ifdef S_SPLINT_S293extern int socket (int, int, int) /*@*/;294# endif295#endif296297#endif /*_PORT_SOCKET_H*/298299300