sockwrap.h 9.14 KB
Newer Older
1 2 3 4 5 6
/* Berkley/WinSock socket API wrappers */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
7
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
8
 *																			*
9 10
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
11 12
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
13 14
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
15 16 17 18 19 20 21 22 23 24
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#ifndef _SOCKWRAP_H
#define _SOCKWRAP_H

25 26
#include "gen_defs.h"	/* BOOL */

27 28 29
/***************/
/* OS-specific */
/***************/
rswindell's avatar
rswindell committed
30
#if defined(_WIN32)	/* Use WinSock */
31 32
typedef const char* socket_send_buffer_t;
typedef char* socket_recv_buffer_t;
33 34

#ifndef _WINSOCKAPI_
35 36
	#include <winsock2.h>	/* socket/bind/etc. */
	#include <mswsock.h>	/* Microsoft WinSock2 extensions */
37 38 39 40
#if defined(__BORLANDC__)
// Borland C++ builder 6 comes with a broken ws2tcpip.h header for GCC.
#define _MSC_VER 7
#endif
41
    #include <ws2tcpip.h>	/* More stuff */
42 43 44
#if defined(__BORLANDC__)
#undef _MSC_VER
#endif
45
	#include <wspiapi.h>	/* getaddrinfo() for Windows 2k */
46
	#define SOCK_MAXADDRLEN sizeof(SOCKADDR_STORAGE)
47
	/* Let's agree on a standard WinSock symbol here, people */
48
	#define _WINSOCKAPI_
49
#endif
50 51 52
#ifndef MSG_WAITALL
#define MSG_WAITALL 0x08
#endif
53

54
#elif defined __unix__		/* Unix-variant */
55 56
typedef const void* socket_send_buffer_t;
typedef void* socket_recv_buffer_t;
Deucе's avatar
Deucе committed
57

58 59 60
#include <netdb.h>			/* gethostbyname */
#include <sys/types.h>		/* For u_int32_t on FreeBSD */
#include <netinet/in.h>		/* IPPROTO_IP */
61
#include <sys/un.h>
deuce's avatar
deuce committed
62
/* define _BSD_SOCKLEN_T_ in order to define socklen_t on darwin */
63
#ifdef __DARWIN__
deuce's avatar
deuce committed
64
#define _BSD_SOCKLEN_T_	int
65
#endif
66 67 68 69 70
#include <sys/socket.h>		/* socket/bind/etc. */
#include <sys/time.h>		/* struct timeval */
#include <arpa/inet.h>		/* inet_ntoa */
#include <netinet/tcp.h>	/* TCP_NODELAY */
#include <unistd.h>			/* close */
Deucе's avatar
Deucе committed
71
#include <poll.h>
72 73
#if defined(__solaris__)
	#include <sys/filio.h>  /* FIONBIO */
deuce's avatar
deuce committed
74
	#define INADDR_NONE -1L
75 76 77
#else
	#include <sys/ioctl.h>	/* FIONBIO */
#endif
78 79 80 81

#endif

#include <errno.h>		/* errno */
82
#include "wrapdll.h"	/* DLLEXPORT */
83

84 85
typedef struct {
	char*	name;
86
	int		type;		/* Supported socket types (or 0 for unspecified) */
87 88 89 90
	int		level;
	int		value;
} socket_option_t;

91 92 93 94 95 96 97 98 99 100 101 102
/*
 * Fancy sockaddr_* union
 */
union xp_sockaddr {
	struct sockaddr			addr;
	struct sockaddr_in		in;
	struct sockaddr_in6		in6;
#ifndef _WIN32
	struct sockaddr_un		un;
#endif
	struct sockaddr_storage	store;
};
103

deuce's avatar
deuce committed
104
#define xp_sockaddr_len(a) ((((struct sockaddr *)a)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
105

106 107
 

108 109 110
/**********************************/
/* Socket Implementation-specific */
/**********************************/
111
#if defined(_WINSOCKAPI_)
112 113 114 115 116

#undef  EINTR
#define EINTR			(WSAEINTR-WSABASEERR)
#undef  ENOTSOCK
#define ENOTSOCK		(WSAENOTSOCK-WSABASEERR)
117 118
#undef  EMSGSIZE
#define EMSGSIZE		(WSAEMSGSIZE-WSABASEERR)
119 120
#undef  EWOULDBLOCK
#define EWOULDBLOCK		(WSAEWOULDBLOCK-WSABASEERR)
121

122
#ifndef EPROTOTYPE
123
#define EPROTOTYPE		(WSAEPROTOTYPE-WSABASEERR)
124 125
#endif
#ifndef ENOPROTOOPT
126
#define ENOPROTOOPT		(WSAENOPROTOOPT-WSABASEERR)
127 128
#endif
#ifndef EPROTONOSUPPORT
129
#define EPROTONOSUPPORT	(WSAEPROTONOSUPPORT-WSABASEERR)
130 131
#endif
#ifndef ESOCKTNOSUPPORT
132
#define ESOCKTNOSUPPORT	(WSAESOCKTNOSUPPORT-WSABASEERR)
133 134
#endif
#ifndef EOPNOTSUPP
135
#define EOPNOTSUPP		(WSAEOPNOTSUPP-WSABASEERR)
136 137
#endif
#ifndef EPFNOSUPPORT
138
#define EPFNOSUPPORT	(WSAEPFNOSUPPORT-WSABASEERR)
139 140
#endif
#ifndef EAFNOSUPPORT
141
#define EAFNOSUPPORT	(WSAEAFNOSUPPORT-WSABASEERR)
142
#endif
143 144 145 146 147 148 149

#undef  EADDRINUSE
#define EADDRINUSE		(WSAEADDRINUSE-WSABASEERR)
#undef  EADDRNOTAVAIL
#define EADDRNOTAVAIL	(WSAEADDRNOTAVAIL-WSABASEERR)
#undef  ECONNABORTED
#define ECONNABORTED	(WSAECONNABORTED-WSABASEERR)
150 151
#undef  ECONNRESET
#define ECONNRESET		(WSAECONNRESET-WSABASEERR)
152 153 154 155 156 157
#undef  ENOBUFS
#define ENOBUFS			(WSAENOBUFS-WSABASEERR)
#undef  EISCONN
#define EISCONN			(WSAEISCONN-WSABASEERR)
#undef  ENOTCONN
#define ENOTCONN		(WSAENOTCONN-WSABASEERR)
158 159
#undef  ESHUTDOWN
#define ESHUTDOWN		(WSAESHUTDOWN-WSABASEERR)
160 161 162 163
#undef  ETIMEDOUT
#define ETIMEDOUT		(WSAETIMEDOUT-WSABASEERR)
#undef  ECONNREFUSED
#define ECONNREFUSED	(WSAECONNREFUSED-WSABASEERR)
164 165
#undef	EINPROGRESS
#define EINPROGRESS		(WSAEINPROGRESS-WSABASEERR)
166

167 168 169 170 171
/* for shutdown() */
#define SHUT_RD			SD_RECEIVE
#define SHUT_WR			SD_SEND
#define SHUT_RDWR		SD_BOTH

172
#define s_addr			S_un.S_addr
deuce's avatar
deuce committed
173
#define sa_family_t		ushort
deuce's avatar
deuce committed
174
typedef uint32_t                in_addr_t;
175

176
static  int wsa_error;
177
#define ERROR_VALUE			((wsa_error=WSAGetLastError())>0 ? wsa_error-WSABASEERR : wsa_error)
178
#define socket_errno		WSAGetLastError()
179
#define sendsocket(s,b,l)	send(s,b,l,0)
180 181 182 183 184 185
typedef ULONG nfds_t;
/*
 * NOTE: WSAPoll() has a bug where a non-blocking socket which has connect()
 *       called on it that is trying to connect to a closed port will timeout
 *       instead of returning a failure, even with POLLOUT specified.
 */
Deucе's avatar
Deucе committed
186
#define poll(s, c, t)		WSAPoll(s, c, t)
187

188 189 190 191 192 193 194 195
/* For getaddrinfo() */
#ifndef AI_ADDRCONFIG
# define AI_ADDRCONFIG 0x400 // Vista or later
#endif
#ifndef AI_NUMERICSERV
# define AI_NUMERICSERV 0		// Not supported by Win32
#endif

196 197 198 199
#else	/* BSD sockets */

/* WinSock-isms */
#define HOSTENT			struct hostent
200
#define IN_ADDR			struct in_addr
201
#define SOCKADDR		struct sockaddr
202 203 204 205 206 207 208 209
#define SOCKADDR_IN		struct sockaddr_in
#define LINGER			struct linger
#define SOCKET			int
#define SOCKET_ERROR	-1
#define INVALID_SOCKET  (SOCKET)(~0)
#define closesocket		close
#define ioctlsocket		ioctl
#define ERROR_VALUE		errno
210
#define socket_errno	errno
deuce's avatar
Linting  
deuce committed
211
#define sendsocket		write		/* FreeBSD send() is broken */
212

rswindell's avatar
rswindell committed
213 214 215 216
#ifdef __WATCOMC__
	#define socklen_t		int
#endif

217 218
#endif	/* __unix__ */

219 220 221 222
#ifdef __cplusplus
extern "C" {
#endif

223 224
DLLEXPORT socket_option_t* getSocketOptionList(void);
DLLEXPORT int getSocketOptionByName(const char* name, int* level);
225

226 227
DLLEXPORT off_t sendfilesocket(int sock, int file, off_t* offset, off_t count);
DLLEXPORT off_t recvfilesocket(int sock, int file, off_t* offset, off_t count);
228 229
DLLEXPORT BOOL socket_check(SOCKET sock, BOOL* rd_p, BOOL* wr_p, DWORD timeout);
DLLEXPORT int retry_bind(SOCKET s, const struct sockaddr *addr, socklen_t addrlen
230
				   ,uint retries, uint wait_secs, const char* prot
231
				   ,int (*lprintf)(int level, const char *fmt, ...));
232
DLLEXPORT int nonblocking_connect(SOCKET, struct sockaddr*, size_t, unsigned timeout /* seconds */);
233
DLLEXPORT union xp_sockaddr* inet_ptoaddr(const char *addr_str, union xp_sockaddr *addr, size_t size);
234 235 236 237
DLLEXPORT const char* inet_addrtop(union xp_sockaddr *addr, char *dest, size_t size);
DLLEXPORT uint16_t inet_addrport(union xp_sockaddr *addr);
DLLEXPORT void inet_setaddrport(union xp_sockaddr *addr, uint16_t port);
DLLEXPORT BOOL inet_addrmatch(union xp_sockaddr* addr1, union xp_sockaddr* addr2);
238
DLLEXPORT char* socket_strerror(int, char*, size_t);
239
DLLEXPORT void set_socket_errno(int);
240 241 242
DLLEXPORT int xp_inet_pton(int af, const char *src, void *dst);
#if defined(_WIN32) // mingw and WinXP's WS2_32.DLL don't have inet_pton():
	#define inet_pton	xp_inet_pton
Deucе's avatar
Deucе committed
243
DLLEXPORT int socketpair(int domain, int type, int protocol, SOCKET *sv);
Deucе's avatar
Deucе committed
244 245
#endif

246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
/*
 * Return TRUE if recv() will not block on socket
 * Will block for timeout ms or forever if timeout is negative
 *
 * This means it will return true if recv() will return an error
 * as well as if the socket is closed (and recv() will return 0)
 */
DLLEXPORT BOOL socket_readable(SOCKET sock, int timeout);

/*
 * Return TRUE if send() will not block on socket
 * Will block for timeout ms or forever if timeout is negative
 *
 * This means it will return true if send() will return an error
 * as well as if the socket is closed (and send() will return 0)
 */
DLLEXPORT BOOL socket_writable(SOCKET sock, int timeout);

/*
 * Return TRUE if recv() will not block and will return zero
 * or an error. This is *not* a test if a socket is
 * disconnected, but rather that it is disconnected *AND* all
 * data has been recv()ed.
 */
DLLEXPORT BOOL socket_recvdone(SOCKET sock, int timeout);

272 273 274
#ifdef __cplusplus
}
#endif
275

276
#ifndef IPPORT_HTTP
277
#define IPPORT_HTTP			80
278
#endif
deuce's avatar
deuce committed
279 280 281
#ifndef IPPORT_HTTPS
#define IPPORT_HTTPS			443
#endif
282
#ifndef IPPORT_FTP
283
#define IPPORT_FTP			21
284 285
#endif
#ifndef IPPORT_TELNET
286
#define IPPORT_TELNET		23
287 288
#endif
#ifndef IPPORT_SMTP
289
#define IPPORT_SMTP			25
290 291
#endif
#ifndef IPPORT_POP3
292
#define IPPORT_POP3			110
293
#endif
deuce's avatar
deuce committed
294 295 296
#ifndef IPPORT_POP3S
#define IPPORT_POP3S			995
#endif
rswindell's avatar
rswindell committed
297
#ifndef IPPORT_IDENT
298
#define IPPORT_IDENT		113
rswindell's avatar
rswindell committed
299
#endif
300 301 302
#ifndef IPPORT_SUBMISSION
#define IPPORT_SUBMISSION	587
#endif
deuce's avatar
deuce committed
303 304 305
#ifndef IPPORT_SUBMISSIONS
#define IPPORT_SUBMISSIONS	465
#endif
306 307 308
#ifndef IPPORT_BINKP
#define IPPORT_BINKP		24554
#endif
309 310

#endif	/* Don't add anything after this line */