sockwrap.h 8.99 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

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

52
53
54
55
56
#elif defined __unix__		/* Unix-variant */
							
#include <netdb.h>			/* gethostbyname */
#include <sys/types.h>		/* For u_int32_t on FreeBSD */
#include <netinet/in.h>		/* IPPROTO_IP */
57
#include <sys/un.h>
deuce's avatar
deuce committed
58
/* define _BSD_SOCKLEN_T_ in order to define socklen_t on darwin */
59
#ifdef __DARWIN__
deuce's avatar
deuce committed
60
#define _BSD_SOCKLEN_T_	int
61
#endif
62
63
64
65
66
#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
67
#include <poll.h>
68
69
#if defined(__solaris__)
	#include <sys/filio.h>  /* FIONBIO */
deuce's avatar
deuce committed
70
	#define INADDR_NONE -1L
71
72
73
#else
	#include <sys/ioctl.h>	/* FIONBIO */
#endif
74
75
76
77

#endif

#include <errno.h>		/* errno */
78
#include "wrapdll.h"	/* DLLEXPORT */
79

80
81
typedef struct {
	char*	name;
82
	int		type;		/* Supported socket types (or 0 for unspecified) */
83
84
85
86
	int		level;
	int		value;
} socket_option_t;

87
88
89
90
91
92
93
94
95
96
97
98
/*
 * 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;
};
99

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

102
103
 

104
105
106
/**********************************/
/* Socket Implementation-specific */
/**********************************/
107
#if defined(_WINSOCKAPI_)
108
109
110
111
112

#undef  EINTR
#define EINTR			(WSAEINTR-WSABASEERR)
#undef  ENOTSOCK
#define ENOTSOCK		(WSAENOTSOCK-WSABASEERR)
113
114
#undef  EMSGSIZE
#define EMSGSIZE		(WSAEMSGSIZE-WSABASEERR)
115
116
#undef  EWOULDBLOCK
#define EWOULDBLOCK		(WSAEWOULDBLOCK-WSABASEERR)
117

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

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

163
164
165
166
167
/* for shutdown() */
#define SHUT_RD			SD_RECEIVE
#define SHUT_WR			SD_SEND
#define SHUT_RDWR		SD_BOTH

168
#define s_addr			S_un.S_addr
deuce's avatar
deuce committed
169
#define sa_family_t		ushort
deuce's avatar
deuce committed
170
typedef uint32_t                in_addr_t;
171

172
static  int wsa_error;
173
#define ERROR_VALUE			((wsa_error=WSAGetLastError())>0 ? wsa_error-WSABASEERR : wsa_error)
174
#define socket_errno		WSAGetLastError()
175
#define sendsocket(s,b,l)	send(s,b,l,0)
176
177
178
179
180
181
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
182
#define poll(s, c, t)		WSAPoll(s, c, t)
183

184
185
186
187
188
189
190
191
/* 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

192
193
194
195
#else	/* BSD sockets */

/* WinSock-isms */
#define HOSTENT			struct hostent
196
#define IN_ADDR			struct in_addr
197
#define SOCKADDR		struct sockaddr
198
199
200
201
202
203
204
205
#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
206
#define socket_errno	errno
deuce's avatar
Linting    
deuce committed
207
#define sendsocket		write		/* FreeBSD send() is broken */
208

rswindell's avatar
rswindell committed
209
210
211
212
#ifdef __WATCOMC__
	#define socklen_t		int
#endif

213
214
#endif	/* __unix__ */

215
216
217
218
#ifdef __cplusplus
extern "C" {
#endif

219
220
DLLEXPORT socket_option_t* getSocketOptionList(void);
DLLEXPORT int getSocketOptionByName(const char* name, int* level);
221

222
223
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);
224
225
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
226
				   ,uint retries, uint wait_secs, const char* prot
227
				   ,int (*lprintf)(int level, const char *fmt, ...));
228
229
230
231
232
233
DLLEXPORT int nonblocking_connect(SOCKET, struct sockaddr*, size_t, unsigned timeout /* seconds */);
DLLEXPORT union xp_sockaddr* inet_ptoaddr(char *addr_str, union xp_sockaddr *addr, size_t size);
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);
234
DLLEXPORT char* socket_strerror(int, char*, size_t);
235
DLLEXPORT void set_socket_errno(int);
236
237
238
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
239
DLLEXPORT int socketpair(int domain, int type, int protocol, SOCKET *sv);
Deucе's avatar
Deucе committed
240
241
#endif

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
 * 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);

268
269
270
#ifdef __cplusplus
}
#endif
271

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

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