1 | /* |
2 | +----------------------------------------------------------------------+ |
3 | | PHP Version 5 | |
4 | +----------------------------------------------------------------------+ |
5 | | Copyright (c) 1997-2015 The PHP Group | |
6 | +----------------------------------------------------------------------+ |
7 | | This source file is subject to version 3.01 of the PHP license, | |
8 | | that is bundled with this package in the file LICENSE, and is | |
9 | | available through the world-wide-web at the following url: | |
10 | | http://www.php.net/license/3_01.txt | |
11 | | If you did not receive a copy of the PHP license and are unable to | |
12 | | obtain it through the world-wide-web, please send a note to | |
13 | | license@php.net so we can mail you a copy immediately. | |
14 | +----------------------------------------------------------------------+ |
15 | | Author: Stig Venaas <venaas@uninett.no> | |
16 | +----------------------------------------------------------------------+ |
17 | */ |
18 | |
19 | /* $Id$ */ |
20 | |
21 | #ifndef _PHP_NETWORK_H |
22 | #define _PHP_NETWORK_H |
23 | |
24 | #include <php.h> |
25 | |
26 | #ifdef PHP_WIN32 |
27 | # include "win32/inet.h" |
28 | #else |
29 | # undef closesocket |
30 | # define closesocket close |
31 | #endif |
32 | |
33 | #ifndef HAVE_SHUTDOWN |
34 | #undef shutdown |
35 | #define shutdown(s,n) /* nothing */ |
36 | #endif |
37 | |
38 | #ifdef PHP_WIN32 |
39 | # ifdef EWOULDBLOCK |
40 | # undef EWOULDBLOCK |
41 | # endif |
42 | # ifdef EINPROGRESS |
43 | # undef EINPROGRESS |
44 | # endif |
45 | # define EWOULDBLOCK WSAEWOULDBLOCK |
46 | # define EINPROGRESS WSAEWOULDBLOCK |
47 | # define fsync _commit |
48 | # define ftruncate(a, b) chsize(a, b) |
49 | #endif /* defined(PHP_WIN32) */ |
50 | |
51 | #ifndef EWOULDBLOCK |
52 | # define EWOULDBLOCK EAGAIN |
53 | #endif |
54 | |
55 | #ifdef PHP_WIN32 |
56 | #define php_socket_errno() WSAGetLastError() |
57 | #else |
58 | #define php_socket_errno() errno |
59 | #endif |
60 | |
61 | /* like strerror, but caller must efree the returned string, |
62 | * unless buf is not NULL. |
63 | * Also works sensibly for win32 */ |
64 | BEGIN_EXTERN_C() |
65 | PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize); |
66 | END_EXTERN_C() |
67 | |
68 | #ifdef HAVE_NETINET_IN_H |
69 | # include <netinet/in.h> |
70 | #endif |
71 | |
72 | #ifdef HAVE_SYS_SOCKET_H |
73 | #include <sys/socket.h> |
74 | #endif |
75 | |
76 | /* These are here, rather than with the win32 counterparts above, |
77 | * since <sys/socket.h> defines them. */ |
78 | #ifndef SHUT_RD |
79 | # define SHUT_RD 0 |
80 | # define SHUT_WR 1 |
81 | # define SHUT_RDWR 2 |
82 | #endif |
83 | |
84 | #ifdef HAVE_SYS_TIME_H |
85 | #include <sys/time.h> |
86 | #endif |
87 | |
88 | #ifdef HAVE_STDDEF_H |
89 | #include <stddef.h> |
90 | #endif |
91 | |
92 | #ifdef PHP_WIN32 |
93 | typedef SOCKET php_socket_t; |
94 | #else |
95 | typedef int php_socket_t; |
96 | #endif |
97 | |
98 | #ifdef PHP_WIN32 |
99 | # define SOCK_ERR INVALID_SOCKET |
100 | # define SOCK_CONN_ERR SOCKET_ERROR |
101 | # define SOCK_RECV_ERR SOCKET_ERROR |
102 | #else |
103 | # define SOCK_ERR -1 |
104 | # define SOCK_CONN_ERR -1 |
105 | # define SOCK_RECV_ERR -1 |
106 | #endif |
107 | |
108 | /* uncomment this to debug poll(2) emulation on systems that have poll(2) */ |
109 | /* #define PHP_USE_POLL_2_EMULATION 1 */ |
110 | |
111 | #if defined(HAVE_SYS_POLL_H) && defined(HAVE_POLL) |
112 | # include <sys/poll.h> |
113 | typedef struct pollfd php_pollfd; |
114 | #else |
115 | typedef struct _php_pollfd { |
116 | php_socket_t fd; |
117 | short events; |
118 | short revents; |
119 | } php_pollfd; |
120 | |
121 | PHPAPI int php_poll2(php_pollfd *ufds, unsigned int nfds, int timeout); |
122 | |
123 | #ifndef POLLIN |
124 | # define POLLIN 0x0001 /* There is data to read */ |
125 | # define POLLPRI 0x0002 /* There is urgent data to read */ |
126 | # define POLLOUT 0x0004 /* Writing now will not block */ |
127 | # define POLLERR 0x0008 /* Error condition */ |
128 | # define POLLHUP 0x0010 /* Hung up */ |
129 | # define POLLNVAL 0x0020 /* Invalid request: fd not open */ |
130 | #endif |
131 | |
132 | # ifndef PHP_USE_POLL_2_EMULATION |
133 | # define PHP_USE_POLL_2_EMULATION 1 |
134 | # endif |
135 | #endif |
136 | |
137 | #define PHP_POLLREADABLE (POLLIN|POLLERR|POLLHUP) |
138 | |
139 | #ifndef PHP_USE_POLL_2_EMULATION |
140 | # define php_poll2(ufds, nfds, timeout) poll(ufds, nfds, timeout) |
141 | #endif |
142 | |
143 | /* timeval-to-timeout (for poll(2)) */ |
144 | static inline int php_tvtoto(struct timeval *timeouttv) |
145 | { |
146 | if (timeouttv) { |
147 | return (timeouttv->tv_sec * 1000) + (timeouttv->tv_usec / 1000); |
148 | } |
149 | return -1; |
150 | } |
151 | |
152 | /* hybrid select(2)/poll(2) for a single descriptor. |
153 | * timeouttv follows same rules as select(2), but is reduced to millisecond accuracy. |
154 | * Returns 0 on timeout, -1 on error, or the event mask (ala poll(2)). |
155 | */ |
156 | static inline int php_pollfd_for(php_socket_t fd, int events, struct timeval *timeouttv) |
157 | { |
158 | php_pollfd p; |
159 | int n; |
160 | |
161 | p.fd = fd; |
162 | p.events = events; |
163 | p.revents = 0; |
164 | |
165 | n = php_poll2(&p, 1, php_tvtoto(timeouttv)); |
166 | |
167 | if (n > 0) { |
168 | return p.revents; |
169 | } |
170 | |
171 | return n; |
172 | } |
173 | |
174 | static inline int php_pollfd_for_ms(php_socket_t fd, int events, int timeout) |
175 | { |
176 | php_pollfd p; |
177 | int n; |
178 | |
179 | p.fd = fd; |
180 | p.events = events; |
181 | p.revents = 0; |
182 | |
183 | n = php_poll2(&p, 1, timeout); |
184 | |
185 | if (n > 0) { |
186 | return p.revents; |
187 | } |
188 | |
189 | return n; |
190 | } |
191 | |
192 | /* emit warning and suggestion for unsafe select(2) usage */ |
193 | PHPAPI void _php_emit_fd_setsize_warning(int max_fd); |
194 | |
195 | #ifdef PHP_WIN32 |
196 | /* it is safe to FD_SET too many fd's under win32; the macro will simply ignore |
197 | * descriptors that go beyond the default FD_SETSIZE */ |
198 | # define PHP_SAFE_FD_SET(fd, set) FD_SET(fd, set) |
199 | # define PHP_SAFE_FD_CLR(fd, set) FD_CLR(fd, set) |
200 | # define PHP_SAFE_FD_ISSET(fd, set) FD_ISSET(fd, set) |
201 | # define PHP_SAFE_MAX_FD(m, n) do { if (n + 1 >= FD_SETSIZE) { _php_emit_fd_setsize_warning(n); }} while(0) |
202 | #else |
203 | # define PHP_SAFE_FD_SET(fd, set) do { if (fd < FD_SETSIZE) FD_SET(fd, set); } while(0) |
204 | # define PHP_SAFE_FD_CLR(fd, set) do { if (fd < FD_SETSIZE) FD_CLR(fd, set); } while(0) |
205 | # define PHP_SAFE_FD_ISSET(fd, set) ((fd < FD_SETSIZE) && FD_ISSET(fd, set)) |
206 | # define PHP_SAFE_MAX_FD(m, n) do { if (m >= FD_SETSIZE) { _php_emit_fd_setsize_warning(m); m = FD_SETSIZE - 1; }} while(0) |
207 | #endif |
208 | |
209 | |
210 | #define PHP_SOCK_CHUNK_SIZE 8192 |
211 | |
212 | #ifdef HAVE_SOCKADDR_STORAGE |
213 | typedef struct sockaddr_storage php_sockaddr_storage; |
214 | #else |
215 | typedef struct { |
216 | #ifdef HAVE_SOCKADDR_SA_LEN |
217 | unsigned char ss_len; |
218 | unsigned char ss_family; |
219 | #else |
220 | unsigned short ss_family; |
221 | #endif |
222 | char info[126]; |
223 | } php_sockaddr_storage; |
224 | #endif |
225 | |
226 | BEGIN_EXTERN_C() |
227 | PHPAPI int php_network_getaddresses(const char *host, int socktype, struct sockaddr ***sal, char **error_string TSRMLS_DC); |
228 | PHPAPI void php_network_freeaddresses(struct sockaddr **sal); |
229 | |
230 | PHPAPI php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short port, |
231 | int socktype, int asynchronous, struct timeval *timeout, char **error_string, |
232 | int *error_code, char *bindto, unsigned short bindport |
233 | TSRMLS_DC); |
234 | |
235 | PHPAPI int php_network_connect_socket(php_socket_t sockfd, |
236 | const struct sockaddr *addr, |
237 | socklen_t addrlen, |
238 | int asynchronous, |
239 | struct timeval *timeout, |
240 | char **error_string, |
241 | int *error_code); |
242 | |
243 | #define php_connect_nonb(sock, addr, addrlen, timeout) \ |
244 | php_network_connect_socket((sock), (addr), (addrlen), 0, (timeout), NULL, NULL) |
245 | |
246 | PHPAPI php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned port, |
247 | int socktype, char **error_string, int *error_code |
248 | TSRMLS_DC); |
249 | |
250 | PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock, |
251 | char **textaddr, long *textaddrlen, |
252 | struct sockaddr **addr, |
253 | socklen_t *addrlen, |
254 | struct timeval *timeout, |
255 | char **error_string, |
256 | int *error_code |
257 | TSRMLS_DC); |
258 | |
259 | PHPAPI int php_network_get_sock_name(php_socket_t sock, |
260 | char **textaddr, long *textaddrlen, |
261 | struct sockaddr **addr, |
262 | socklen_t *addrlen |
263 | TSRMLS_DC); |
264 | |
265 | PHPAPI int php_network_get_peer_name(php_socket_t sock, |
266 | char **textaddr, long *textaddrlen, |
267 | struct sockaddr **addr, |
268 | socklen_t *addrlen |
269 | TSRMLS_DC); |
270 | |
271 | PHPAPI void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short port); |
272 | PHPAPI int php_sockaddr_size(php_sockaddr_storage *addr); |
273 | END_EXTERN_C() |
274 | |
275 | struct _php_netstream_data_t { |
276 | php_socket_t socket; |
277 | char is_blocked; |
278 | struct timeval timeout; |
279 | char timeout_event; |
280 | size_t ownsize; |
281 | }; |
282 | typedef struct _php_netstream_data_t php_netstream_data_t; |
283 | PHPAPI extern php_stream_ops php_stream_socket_ops; |
284 | extern php_stream_ops php_stream_generic_socket_ops; |
285 | #define PHP_STREAM_IS_SOCKET (&php_stream_socket_ops) |
286 | |
287 | BEGIN_EXTERN_C() |
288 | PHPAPI php_stream *_php_stream_sock_open_from_socket(php_socket_t socket, const char *persistent_id STREAMS_DC TSRMLS_DC ); |
289 | /* open a connection to a host using php_hostconnect and return a stream */ |
290 | PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port, |
291 | int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC TSRMLS_DC); |
292 | PHPAPI void php_network_populate_name_from_sockaddr( |
293 | /* input address */ |
294 | struct sockaddr *sa, socklen_t sl, |
295 | /* output readable address */ |
296 | char **textaddr, long *textaddrlen, |
297 | /* output address */ |
298 | struct sockaddr **addr, |
299 | socklen_t *addrlen |
300 | TSRMLS_DC); |
301 | |
302 | PHPAPI int php_network_parse_network_address_with_port(const char *addr, |
303 | long addrlen, struct sockaddr *sa, socklen_t *sl TSRMLS_DC); |
304 | END_EXTERN_C() |
305 | |
306 | #define php_stream_sock_open_from_socket(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_CC TSRMLS_CC) |
307 | #define php_stream_sock_open_host(host, port, socktype, timeout, persistent) _php_stream_sock_open_host((host), (port), (socktype), (timeout), (persistent) STREAMS_CC TSRMLS_CC) |
308 | |
309 | /* {{{ memory debug */ |
310 | #define php_stream_sock_open_from_socket_rel(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_REL_CC TSRMLS_CC) |
311 | #define php_stream_sock_open_host_rel(host, port, socktype, timeout, persistent) _php_stream_sock_open_host((host), (port), (socktype), (timeout), (persistent) STREAMS_REL_CC TSRMLS_CC) |
312 | #define php_stream_sock_open_unix_rel(path, pathlen, persistent, timeval) _php_stream_sock_open_unix((path), (pathlen), (persistent), (timeval) STREAMS_REL_CC TSRMLS_CC) |
313 | |
314 | /* }}} */ |
315 | |
316 | #ifndef MAXFQDNLEN |
317 | #define MAXFQDNLEN 255 |
318 | #endif |
319 | |
320 | #endif /* _PHP_NETWORK_H */ |
321 | |
322 | /* |
323 | * Local variables: |
324 | * tab-width: 8 |
325 | * c-basic-offset: 8 |
326 | * End: |
327 | */ |
328 | |