1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Chris Vandomelen <chrisv@b0rked.dhs.org> |
14 | Sterling Hughes <sterling@php.net> |
15 | |
16 | WinSock: Daniel Beulshausen <daniel@php4win.de> |
17 +----------------------------------------------------------------------+
18 */
19
20 #ifndef PHP_SOCKETS_H
21 #define PHP_SOCKETS_H
22
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #ifdef HAVE_SOCKETS
28
29 #include <php.h>
30 #ifdef PHP_WIN32
31 # include "windows_common.h"
32 #else
33 # define IS_INVALID_SOCKET(a) (a->bsd_socket < 0)
34 #endif
35
36 #define PHP_SOCKETS_VERSION PHP_VERSION
37
38 extern zend_module_entry sockets_module_entry;
39 #define phpext_sockets_ptr &sockets_module_entry
40
41 #ifdef PHP_WIN32
42 #include <Winsock2.h>
43 #else
44 #ifdef HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>
46 #endif
47 #endif
48
49 #ifndef PHP_WIN32
50 typedef int PHP_SOCKET;
51 #else
52 typedef SOCKET PHP_SOCKET;
53 #endif
54
55 #ifdef PHP_WIN32
56 # ifdef PHP_SOCKETS_EXPORTS
57 # define PHP_SOCKETS_API __declspec(dllexport)
58 # else
59 # define PHP_SOCKETS_API __declspec(dllimport)
60 # endif
61 #elif defined(__GNUC__) && __GNUC__ >= 4
62 # define PHP_SOCKETS_API __attribute__ ((visibility("default")))
63 #else
64 # define PHP_SOCKETS_API
65 #endif
66
67 /* Socket class */
68
69 typedef struct {
70 PHP_SOCKET bsd_socket;
71 int type;
72 int error;
73 int blocking;
74 zval zstream;
75 zend_object std;
76 } php_socket;
77
78 extern PHP_SOCKETS_API zend_class_entry *socket_ce;
79
socket_from_obj(zend_object * obj)80 static inline php_socket *socket_from_obj(zend_object *obj) {
81 return (php_socket *)((char *)(obj) - XtOffsetOf(php_socket, std));
82 }
83
84 #define Z_SOCKET_P(zv) socket_from_obj(Z_OBJ_P(zv))
85
86 #define ENSURE_SOCKET_VALID(php_sock) do { \
87 if (IS_INVALID_SOCKET(php_sock)) { \
88 zend_argument_error(NULL, 1, "has already been closed"); \
89 RETURN_THROWS(); \
90 } \
91 } while (0)
92
93 #ifdef PHP_WIN32
94 struct sockaddr_un {
95 short sun_family;
96 char sun_path[108];
97 };
98 #endif
99
100 #define PHP_SOCKET_ERROR(socket, msg, errn) \
101 do { \
102 int _err = (errn); /* save value to avoid repeated calls to WSAGetLastError() on Windows */ \
103 (socket)->error = _err; \
104 SOCKETS_G(last_error) = _err; \
105 if (_err != EAGAIN && _err != EWOULDBLOCK && _err != EINPROGRESS) { \
106 php_error_docref(NULL, E_WARNING, "%s [%d]: %s", msg, _err, sockets_strerror(_err)); \
107 } \
108 } while (0)
109
110 ZEND_BEGIN_MODULE_GLOBALS(sockets)
111 int last_error;
112 char *strerror_buf;
113 #ifdef PHP_WIN32
114 uint32_t wsa_child_count;
115 HashTable wsa_info;
116 #endif
117 ZEND_END_MODULE_GLOBALS(sockets)
118
119 PHP_SOCKETS_API ZEND_EXTERN_MODULE_GLOBALS(sockets)
120 #define SOCKETS_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(sockets, v)
121
122 enum sockopt_return {
123 SOCKOPT_ERROR,
124 SOCKOPT_CONTINUE,
125 SOCKOPT_SUCCESS
126 };
127
128 PHP_SOCKETS_API char *sockets_strerror(int error);
129 PHP_SOCKETS_API bool socket_import_file_descriptor(PHP_SOCKET socket, php_socket *retsock);
130
131 #else
132 #define phpext_sockets_ptr NULL
133 #endif
134
135 #if defined(_AIX) && !defined(HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY)
136 # define ss_family __ss_family
137 #endif
138
139 #ifndef MSG_EOF
140 #ifdef MSG_FIN
141 #define MSG_EOF MSG_FIN
142 #endif
143 #endif
144
145 #ifndef MSG_WAITALL
146 #ifdef LINUX
147 #define MSG_WAITALL 0x00000100
148 #else
149 #define MSG_WAITALL 0x00000000
150 #endif
151 #endif
152
153 #define PHP_NORMAL_READ 0x0001
154 #define PHP_BINARY_READ 0x0002
155
156 #ifdef PHP_WIN32
157 #define PHP_SOCKET_EINTR WSAEINTR
158 #elif defined(EINTR)
159 #define PHP_SOCKET_EINTR EINTR
160 #endif
161
162 #ifdef PHP_WIN32
163 #define PHP_SOCKET_EBADF WSAEBADF
164 #elif defined(EBADF)
165 #define PHP_SOCKET_EBADF EBADF
166 #endif
167
168 #ifdef PHP_WIN32
169 #define PHP_SOCKET_EACCES WSAEACCES
170 #elif defined(EACCES)
171 #define PHP_SOCKET_EACCES EACCES
172 #endif
173
174 #ifdef PHP_WIN32
175 #define PHP_SOCKET_EFAULT WSAEFAULT
176 #elif defined(EFAULT)
177 #define PHP_SOCKET_EFAULT EFAULT
178 #endif
179
180 #ifdef PHP_WIN32
181 #define PHP_SOCKET_EINVAL WSAEINVAL
182 #elif defined(EINVAL)
183 #define PHP_SOCKET_EINVAL EINVAL
184 #endif
185
186 #ifdef ENFILE
187 #define PHP_SOCKET_ENFILE ENFILE
188 #endif
189
190 #ifdef PHP_WIN32
191 #define PHP_SOCKET_EMFILE WSAEMFILE
192 #elif defined(EMFILE)
193 #define PHP_SOCKET_EMFILE EMFILE
194 #endif
195
196 #ifdef PHP_WIN32
197 #define PHP_SOCKET_EWOULDBLOCK WSAEWOULDBLOCK
198 #elif defined(EWOULDBLOCK)
199 #define PHP_SOCKET_EWOULDBLOCK EWOULDBLOCK
200 #endif
201
202 #ifdef PHP_WIN32
203 #define PHP_SOCKET_EINPROGRESS WSAEINPROGRESS
204 #elif defined(EINPROGRESS)
205 #define PHP_SOCKET_EINPROGRESS EINPROGRESS
206 #endif
207
208 #ifdef PHP_WIN32
209 #define PHP_SOCKET_EALREADY WSAEALREADY
210 #elif defined(EALREADY)
211 #define PHP_SOCKET_EALREADY EALREADY
212 #endif
213
214 #ifdef PHP_WIN32
215 #define PHP_SOCKET_ENOTSOCK WSAENOTSOCK
216 #elif defined(ENOTSOCK)
217 #define PHP_SOCKET_ENOTSOCK ENOTSOCK
218 #endif
219
220 #ifdef PHP_WIN32
221 #define PHP_SOCKET_EDESTADDRREQ WSAEDESTADDRREQ
222 #elif defined(EDESTADDRREQ)
223 #define PHP_SOCKET_EDESTADDRREQ EDESTADDRREQ
224 #endif
225
226 #ifdef PHP_WIN32
227 #define PHP_SOCKET_EMSGSIZE WSAEMSGSIZE
228 #elif defined(EMSGSIZE)
229 #define PHP_SOCKET_EMSGSIZE EMSGSIZE
230 #endif
231
232 #ifdef PHP_WIN32
233 #define PHP_SOCKET_EPROTOTYPE WSAEPROTOTYPE
234 #elif defined(EPROTOTYPE)
235 #define PHP_SOCKET_EPROTOTYPE EPROTOTYPE
236 #endif
237
238 #ifdef PHP_WIN32
239 #define PHP_SOCKET_ENOPROTOOPT WSAENOPROTOOPT
240 #elif defined(ENOPROTOOPT)
241 #define PHP_SOCKET_ENOPROTOOPT ENOPROTOOPT
242 #endif
243
244 #ifdef PHP_WIN32
245 #define PHP_SOCKET_EPROTONOSUPPORT WSAEPROTONOSUPPORT
246 #elif defined(EPROTONOSUPPORT)
247 #define PHP_SOCKET_EPROTONOSUPPORT EPROTONOSUPPORT
248 #endif
249
250 #ifdef PHP_WIN32
251 #define PHP_SOCKET_ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
252 #elif defined(ESOCKTNOSUPPORT)
253 #define PHP_SOCKET_ESOCKTNOSUPPORT ESOCKTNOSUPPORT
254 #endif
255
256 #ifdef PHP_WIN32
257 #define PHP_SOCKET_EOPNOTSUPP WSAEOPNOTSUPP
258 #elif defined(EOPNOTSUPP)
259 #define PHP_SOCKET_EOPNOTSUPP EOPNOTSUPP
260 #endif
261
262 #ifdef PHP_WIN32
263 #define PHP_SOCKET_EPFNOSUPPORT WSAEPFNOSUPPORT
264 #elif defined(EPFNOSUPPORT)
265 #define PHP_SOCKET_EPFNOSUPPORT EPFNOSUPPORT
266 #endif
267
268 #ifdef PHP_WIN32
269 #define PHP_SOCKET_EAFNOSUPPORT WSAEAFNOSUPPORT
270 #elif defined(EAFNOSUPPORT)
271 #define PHP_SOCKET_EAFNOSUPPORT EAFNOSUPPORT
272 #endif
273
274 #ifdef PHP_WIN32
275 #define PHP_SOCKET_EADDRINUSE WSAEADDRINUSE
276 #elif defined(EADDRINUSE)
277 #define PHP_SOCKET_EADDRINUSE EADDRINUSE
278 #endif
279
280 #ifdef PHP_WIN32
281 #define PHP_SOCKET_EADDRNOTAVAIL WSAEADDRNOTAVAIL
282 #elif defined(EADDRNOTAVAIL)
283 #define PHP_SOCKET_EADDRNOTAVAIL EADDRNOTAVAIL
284 #endif
285
286 #ifdef PHP_WIN32
287 #define PHP_SOCKET_ENETDOWN WSAENETDOWN
288 #elif defined(ENETDOWN)
289 #define PHP_SOCKET_ENETDOWN ENETDOWN
290 #endif
291
292 #ifdef PHP_WIN32
293 #define PHP_SOCKET_ENETUNREACH WSAENETUNREACH
294 #elif defined(ENETUNREACH)
295 #define PHP_SOCKET_ENETUNREACH ENETUNREACH
296 #endif
297
298 #ifdef PHP_WIN32
299 #define PHP_SOCKET_ENETRESET WSAENETRESET
300 #elif defined(ENETRESET)
301 #define PHP_SOCKET_ENETRESET ENETRESET
302 #endif
303
304 #ifdef PHP_WIN32
305 #define PHP_SOCKET_ECONNABORTED WSAECONNABORTED
306 #elif defined(ECONNABORTED)
307 #define PHP_SOCKET_ECONNABORTED ECONNABORTED
308 #endif
309
310 #ifdef PHP_WIN32
311 #define PHP_SOCKET_ECONNRESET WSAECONNRESET
312 #elif defined(ECONNRESET)
313 #define PHP_SOCKET_ECONNRESET ECONNRESET
314 #endif
315
316 #ifdef PHP_WIN32
317 #define PHP_SOCKET_ENOBUFS WSAENOBUFS
318 #elif defined(ENOBUFS)
319 #define PHP_SOCKET_ENOBUFS ENOBUFS
320 #endif
321
322 #ifdef PHP_WIN32
323 #define PHP_SOCKET_EISCONN WSAEISCONN
324 #elif defined(EISCONN)
325 #define PHP_SOCKET_EISCONN EISCONN
326 #endif
327
328 #ifdef PHP_WIN32
329 #define PHP_SOCKET_ENOTCONN WSAENOTCONN
330 #elif defined(ENOTCONN)
331 #define PHP_SOCKET_ENOTCONN ENOTCONN
332 #endif
333
334 #ifdef PHP_WIN32
335 #define PHP_SOCKET_ESHUTDOWN WSAESHUTDOWN
336 #elif defined(ESHUTDOWN)
337 #define PHP_SOCKET_ESHUTDOWN ESHUTDOWN
338 #endif
339
340 #ifdef PHP_WIN32
341 #define PHP_SOCKET_ETOOMANYREFS WSAETOOMANYREFS
342 #elif defined(ETOOMANYREFS)
343 #define PHP_SOCKET_ETOOMANYREFS ETOOMANYREFS
344 #endif
345
346 #ifdef PHP_WIN32
347 #define PHP_SOCKET_ETIMEDOUT WSAETIMEDOUT
348 #elif defined(ETIMEDOUT)
349 #define PHP_SOCKET_ETIMEDOUT ETIMEDOUT
350 #endif
351
352 #ifdef PHP_WIN32
353 #define PHP_SOCKET_ECONNREFUSED WSAECONNREFUSED
354 #elif defined(ECONNREFUSED)
355 #define PHP_SOCKET_ECONNREFUSED ECONNREFUSED
356 #endif
357
358 #ifdef PHP_WIN32
359 #define PHP_SOCKET_ELOOP WSAELOOP
360 #elif defined(ELOOP)
361 #define PHP_SOCKET_ELOOP ELOOP
362 #endif
363
364 #ifdef PHP_WIN32
365 #define PHP_SOCKET_ENAMETOOLONG WSAENAMETOOLONG
366 #elif defined(ENAMETOOLONG)
367 #define PHP_SOCKET_ENAMETOOLONG ENAMETOOLONG
368 #endif
369
370 #ifdef PHP_WIN32
371 #define PHP_SOCKET_EHOSTDOWN WSAEHOSTDOWN
372 #elif defined(EHOSTDOWN)
373 #define PHP_SOCKET_EHOSTDOWN EHOSTDOWN
374 #endif
375
376 #ifdef PHP_WIN32
377 #define PHP_SOCKET_EHOSTUNREACH WSAEHOSTUNREACH
378 #elif defined(EHOSTUNREACH)
379 #define PHP_SOCKET_EHOSTUNREACH EHOSTUNREACH
380 #endif
381
382 #ifdef PHP_WIN32
383 #define PHP_SOCKET_ENOTEMPTY WSAENOTEMPTY
384 #elif defined(ENOTEMPTY)
385 #define PHP_SOCKET_ENOTEMPTY ENOTEMPTY
386 #endif
387
388 #ifdef PHP_WIN32
389 #define PHP_SOCKET_EUSERS WSAEUSERS
390 #elif defined(EUSERS)
391 #define PHP_SOCKET_EUSERS EUSERS
392 #endif
393
394 #ifdef PHP_WIN32
395 #define PHP_SOCKET_EDQUOT WSAEDQUOT
396 #elif defined(EDQUOT)
397 #define PHP_SOCKET_EDQUOT EDQUOT
398 #endif
399
400 #ifdef PHP_WIN32
401 #define PHP_SOCKET_EREMOTE WSAEREMOTE
402 #elif defined(EREMOTE)
403 #define PHP_SOCKET_EREMOTE EREMOTE
404 #endif
405
406 #endif
407