Commit | Line | Data |
---|---|---|
3719602c PC |
1 | /* Copyright (C) 2010-2022 The RetroArch team |
2 | * | |
3 | * --------------------------------------------------------------------------------------- | |
4 | * The following license statement only applies to this file (net_compat.h). | |
5 | * --------------------------------------------------------------------------------------- | |
6 | * | |
7 | * Permission is hereby granted, free of charge, | |
8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), | |
9 | * to deal in the Software without restriction, including without limitation the rights to | |
10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, | |
11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | |
14 | * | |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |
16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
21 | */ | |
22 | ||
23 | #ifndef _LIBRETRO_SDK_NET_COMPAT_H | |
24 | #define _LIBRETRO_SDK_NET_COMPAT_H | |
25 | ||
26 | #include <stdint.h> | |
27 | #include <boolean.h> | |
28 | #include <retro_inline.h> | |
29 | ||
30 | #include <errno.h> | |
31 | ||
32 | #ifndef _WIN32 | |
33 | #include <sys/time.h> | |
34 | #include <unistd.h> | |
35 | #endif | |
36 | ||
37 | #include <retro_common_api.h> | |
38 | ||
39 | #if defined(_WIN32) && !defined(_XBOX) | |
40 | #define WIN32_LEAN_AND_MEAN | |
41 | ||
42 | #include <winsock2.h> | |
43 | #include <windows.h> | |
44 | #include <ws2tcpip.h> | |
45 | ||
46 | #if _MSC_VER && _MSC_VER <= 1600 | |
47 | /* If we are using MSVC2010 or lower, disable WSAPoll support | |
48 | * to ensure Windows XP and earlier backwards compatibility */ | |
49 | #else | |
50 | #ifndef WIN32_SUPPORTS_POLL | |
51 | #define WIN32_SUPPORTS_POLL 1 | |
52 | #endif | |
53 | #endif | |
54 | ||
55 | #if defined(WIN32_SUPPORTS_POLL) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 | |
56 | #define NETWORK_HAVE_POLL 1 | |
57 | #endif | |
58 | ||
59 | #elif defined(_XBOX) | |
60 | #define NOD3D | |
61 | ||
62 | #include <xtl.h> | |
63 | #include <io.h> | |
64 | ||
65 | #ifndef SO_KEEPALIVE | |
66 | #define SO_KEEPALIVE 0 /* verify if correct */ | |
67 | #endif | |
68 | ||
69 | #define socklen_t unsigned int | |
70 | ||
71 | #elif defined(VITA) | |
72 | #include <psp2/net/net.h> | |
73 | #include <psp2/net/netctl.h> | |
74 | ||
75 | #define NETWORK_HAVE_POLL 1 | |
76 | ||
77 | #define AF_UNSPEC 0 | |
78 | #define AF_INET SCE_NET_AF_INET | |
79 | ||
80 | #define SOCK_STREAM SCE_NET_SOCK_STREAM | |
81 | #define SOCK_DGRAM SCE_NET_SOCK_DGRAM | |
82 | ||
83 | #define INADDR_ANY SCE_NET_INADDR_ANY | |
84 | #define INADDR_NONE 0xFFFFFFFF | |
85 | ||
86 | #define SOL_SOCKET SCE_NET_SOL_SOCKET | |
87 | #define SO_REUSEADDR SCE_NET_SO_REUSEADDR | |
88 | #define SO_KEEPALIVE SCE_NET_SO_KEEPALIVE | |
89 | #define SO_BROADCAST SCE_NET_SO_BROADCAST | |
90 | #define SO_SNDBUF SCE_NET_SO_SNDBUF | |
91 | #define SO_RCVBUF SCE_NET_SO_RCVBUF | |
92 | #define SO_SNDTIMEO SCE_NET_SO_SNDTIMEO | |
93 | #define SO_RCVTIMEO SCE_NET_SO_RCVTIMEO | |
94 | #define SO_ERROR SCE_NET_SO_ERROR | |
95 | #define SO_NBIO SCE_NET_SO_NBIO | |
96 | ||
97 | #define IPPROTO_IP SCE_NET_IPPROTO_IP | |
98 | #define IP_MULTICAST_TTL SCE_NET_IP_MULTICAST_TTL | |
99 | ||
100 | #define IPPROTO_TCP SCE_NET_IPPROTO_TCP | |
101 | #define TCP_NODELAY SCE_NET_TCP_NODELAY | |
102 | ||
103 | #define IPPROTO_UDP SCE_NET_IPPROTO_UDP | |
104 | ||
105 | #define MSG_DONTWAIT SCE_NET_MSG_DONTWAIT | |
106 | ||
107 | #define POLLIN SCE_NET_EPOLLIN | |
108 | #define POLLOUT SCE_NET_EPOLLOUT | |
109 | #define POLLERR SCE_NET_EPOLLERR | |
110 | #define POLLHUP SCE_NET_EPOLLHUP | |
111 | #define POLLNVAL 0 | |
112 | ||
113 | #define sockaddr SceNetSockaddr | |
114 | #define sockaddr_in SceNetSockaddrIn | |
115 | #define in_addr SceNetInAddr | |
116 | #define socklen_t unsigned int | |
117 | ||
118 | #define socket(a,b,c) sceNetSocket("unknown",a,b,c) | |
119 | #define getsockname sceNetGetsockname | |
120 | #define getsockopt sceNetGetsockopt | |
121 | #define setsockopt sceNetSetsockopt | |
122 | #define bind sceNetBind | |
123 | #define listen sceNetListen | |
124 | #define accept sceNetAccept | |
125 | #define connect sceNetConnect | |
126 | #define send sceNetSend | |
127 | #define sendto sceNetSendto | |
128 | #define recv sceNetRecv | |
129 | #define recvfrom sceNetRecvfrom | |
130 | #define htonl sceNetHtonl | |
131 | #define ntohl sceNetNtohl | |
132 | #define htons sceNetHtons | |
133 | #define ntohs sceNetNtohs | |
134 | #define inet_ntop sceNetInetNtop | |
135 | #define inet_pton sceNetInetPton | |
136 | ||
137 | #elif defined(GEKKO) | |
138 | #include <network.h> | |
139 | ||
140 | #define NETWORK_HAVE_POLL 1 | |
141 | ||
142 | #define pollfd pollsd | |
143 | ||
144 | #define socket(a,b,c) net_socket(a,b,c) | |
145 | #define getsockopt(a,b,c,d,e) net_getsockopt(a,b,c,d,e) | |
146 | #define setsockopt(a,b,c,d,e) net_setsockopt(a,b,c,d,e) | |
147 | #define bind(a,b,c) net_bind(a,b,c) | |
148 | #define listen(a,b) net_listen(a,b) | |
149 | #define accept(a,b,c) net_accept(a,b,c) | |
150 | #define connect(a,b,c) net_connect(a,b,c) | |
151 | #define send(a,b,c,d) net_send(a,b,c,d) | |
152 | #define sendto(a,b,c,d,e,f) net_sendto(a,b,c,d,e,f) | |
153 | #define recv(a,b,c,d) net_recv(a,b,c,d) | |
154 | #define recvfrom(a,b,c,d,e,f) net_recvfrom(a,b,c,d,e,f) | |
155 | #define select(a,b,c,d,e) net_select(a,b,c,d,e) | |
156 | #define gethostbyname(a) net_gethostbyname(a) | |
157 | ||
158 | #else | |
159 | #include <sys/types.h> | |
160 | #include <sys/socket.h> | |
161 | #include <sys/select.h> | |
162 | ||
163 | #include <netinet/in.h> | |
164 | #ifndef __PSL1GHT__ | |
165 | #include <netinet/tcp.h> | |
166 | #endif | |
167 | ||
168 | #include <arpa/inet.h> | |
169 | #include <netdb.h> | |
170 | #include <fcntl.h> | |
171 | ||
172 | #if !defined(__PSL1GHT__) && defined(__PS3__) | |
173 | #include <netex/libnetctl.h> | |
174 | #include <netex/errno.h> | |
175 | #else | |
176 | #include <signal.h> | |
177 | #endif | |
178 | ||
179 | #if defined(__PSL1GHT__) | |
180 | #include <net/poll.h> | |
181 | ||
182 | #define NETWORK_HAVE_POLL 1 | |
183 | ||
184 | #elif defined(WIIU) | |
185 | #define WIIU_RCVBUF 0x40000 | |
186 | #define WIIU_SNDBUF 0x40000 | |
187 | ||
188 | #elif !defined(__PS3__) | |
189 | #include <poll.h> | |
190 | ||
191 | #define NETWORK_HAVE_POLL 1 | |
192 | ||
193 | #endif | |
194 | #endif | |
195 | ||
196 | #ifndef MSG_NOSIGNAL | |
197 | #define MSG_NOSIGNAL 0 | |
198 | #endif | |
199 | ||
200 | #if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY) && !defined(_3DS) | |
201 | #define HAVE_INET6 1 | |
202 | #endif | |
203 | ||
204 | #ifdef NETWORK_HAVE_POLL | |
205 | #ifdef GEKKO | |
206 | #define NET_POLL_FD(sockfd, sockfds) (sockfds)->socket = (sockfd) | |
207 | #else | |
208 | #define NET_POLL_FD(sockfd, sockfds) (sockfds)->fd = (sockfd) | |
209 | #endif | |
210 | #define NET_POLL_EVENT(sockev, sockfds) (sockfds)->events |= (sockev) | |
211 | #define NET_POLL_HAS_EVENT(sockev, sockfds) ((sockfds)->revents & (sockev)) | |
212 | #endif | |
213 | ||
214 | RETRO_BEGIN_DECLS | |
215 | ||
216 | /* Compatibility layer for legacy or incomplete BSD socket implementations. | |
217 | * Only for IPv4. Mostly useful for the consoles which do not support | |
218 | * anything reasonably modern on the socket API side of things. */ | |
219 | #ifdef HAVE_SOCKET_LEGACY | |
220 | #define sockaddr_storage sockaddr_in | |
221 | ||
222 | #ifdef AI_PASSIVE | |
223 | #undef AI_PASSIVE | |
224 | #endif | |
225 | #ifdef AI_CANONNAME | |
226 | #undef AI_CANONNAME | |
227 | #endif | |
228 | #ifdef AI_NUMERICHOST | |
229 | #undef AI_NUMERICHOST | |
230 | #endif | |
231 | #ifdef AI_NUMERICSERV | |
232 | #undef AI_NUMERICSERV | |
233 | #endif | |
234 | ||
235 | #ifdef NI_NUMERICHOST | |
236 | #undef NI_NUMERICHOST | |
237 | #endif | |
238 | #ifdef NI_NUMERICSERV | |
239 | #undef NI_NUMERICSERV | |
240 | #endif | |
241 | #ifdef NI_NOFQDN | |
242 | #undef NI_NOFQDN | |
243 | #endif | |
244 | #ifdef NI_NAMEREQD | |
245 | #undef NI_NAMEREQD | |
246 | #endif | |
247 | #ifdef NI_DGRAM | |
248 | #undef NI_DGRAM | |
249 | #endif | |
250 | ||
251 | #define AI_PASSIVE 1 | |
252 | #define AI_CANONNAME 2 | |
253 | #define AI_NUMERICHOST 4 | |
254 | #define AI_NUMERICSERV 8 | |
255 | ||
256 | #define NI_NUMERICHOST 1 | |
257 | #define NI_NUMERICSERV 2 | |
258 | #define NI_NOFQDN 4 | |
259 | #define NI_NAMEREQD 8 | |
260 | #define NI_DGRAM 16 | |
261 | ||
262 | #ifndef __PS3__ | |
263 | struct addrinfo | |
264 | { | |
265 | int ai_flags; | |
266 | int ai_family; | |
267 | int ai_socktype; | |
268 | int ai_protocol; | |
269 | socklen_t ai_addrlen; | |
270 | struct sockaddr *ai_addr; | |
271 | char *ai_canonname; | |
272 | struct addrinfo *ai_next; | |
273 | }; | |
274 | #endif | |
275 | ||
276 | /* gai_strerror() not used, so we skip that. */ | |
277 | ||
278 | #else | |
279 | /* Ensure that getaddrinfo and getnameinfo flags are always defined. */ | |
280 | #ifndef AI_PASSIVE | |
281 | #define AI_PASSIVE 0 | |
282 | #endif | |
283 | #ifndef AI_CANONNAME | |
284 | #define AI_CANONNAME 0 | |
285 | #endif | |
286 | #ifndef AI_NUMERICHOST | |
287 | #define AI_NUMERICHOST 0 | |
288 | #endif | |
289 | #ifndef AI_NUMERICSERV | |
290 | #define AI_NUMERICSERV 0 | |
291 | #endif | |
292 | ||
293 | #ifndef NI_NUMERICHOST | |
294 | #define NI_NUMERICHOST 0 | |
295 | #endif | |
296 | #ifndef NI_NUMERICSERV | |
297 | #define NI_NUMERICSERV 0 | |
298 | #endif | |
299 | #ifndef NI_NOFQDN | |
300 | #define NI_NOFQDN 0 | |
301 | #endif | |
302 | #ifndef NI_NAMEREQD | |
303 | #define NI_NAMEREQD 0 | |
304 | #endif | |
305 | #ifndef NI_DGRAM | |
306 | #define NI_DGRAM 0 | |
307 | #endif | |
308 | ||
309 | #endif | |
310 | ||
311 | #if defined(_XBOX) | |
312 | struct hostent | |
313 | { | |
314 | char *h_name; | |
315 | char **h_aliases; | |
316 | int h_addrtype; | |
317 | int h_length; | |
318 | char **h_addr_list; | |
319 | char *h_addr; | |
320 | char *h_end; | |
321 | }; | |
322 | ||
323 | #elif defined(VITA) | |
324 | struct pollfd | |
325 | { | |
326 | int fd; | |
327 | unsigned events; | |
328 | unsigned revents; | |
329 | unsigned __pad; /* Align to 64-bits boundary */ | |
330 | }; | |
331 | ||
332 | struct hostent | |
333 | { | |
334 | char *h_name; | |
335 | char **h_aliases; | |
336 | int h_addrtype; | |
337 | int h_length; | |
338 | char **h_addr_list; | |
339 | char *h_addr; | |
340 | char *h_end; | |
341 | }; | |
342 | ||
343 | #endif | |
344 | ||
345 | static INLINE bool isagain(int val) | |
346 | { | |
347 | #if defined(_WIN32) | |
348 | return (val == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK); | |
349 | #elif !defined(__PSL1GHT__) && defined(__PS3__) | |
350 | return (sys_net_errno == SYS_NET_EAGAIN) || (sys_net_errno == SYS_NET_EWOULDBLOCK); | |
351 | #elif defined(VITA) | |
352 | return (val == SCE_NET_ERROR_EAGAIN) || (val == SCE_NET_ERROR_EWOULDBLOCK); | |
353 | #elif defined(WIIU) | |
354 | return (val == -1) && (socketlasterr() == SO_SUCCESS || socketlasterr() == SO_EWOULDBLOCK); | |
355 | #else | |
356 | return (val < 0) && (errno == EAGAIN || errno == EWOULDBLOCK); | |
357 | #endif | |
358 | } | |
359 | ||
360 | static INLINE bool isinprogress(int val) | |
361 | { | |
362 | #if defined(_WIN32) | |
363 | return (val == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK); | |
364 | #elif !defined(__PSL1GHT__) && defined(__PS3__) | |
365 | return (sys_net_errno == SYS_NET_EINPROGRESS); | |
366 | #elif defined(VITA) | |
367 | return (val == SCE_NET_ERROR_EINPROGRESS); | |
368 | #elif defined(WIIU) | |
369 | return (val == -1) && (socketlasterr() == SO_EINPROGRESS); | |
370 | #else | |
371 | return (val < 0) && (errno == EINPROGRESS); | |
372 | #endif | |
373 | } | |
374 | ||
375 | #if defined(_WIN32) && !defined(_XBOX) | |
376 | #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600 | |
377 | const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); | |
378 | int inet_pton(int af, const char *src, void *dst); | |
379 | #endif | |
380 | ||
381 | #elif defined(_XBOX) | |
382 | struct hostent *gethostbyname(const char *name); | |
383 | ||
384 | #elif defined(VITA) | |
385 | char *inet_ntoa(struct in_addr in); | |
386 | int inet_aton(const char *cp, struct in_addr *inp); | |
387 | uint32_t inet_addr(const char *cp); | |
388 | ||
389 | struct hostent *gethostbyname(const char *name); | |
390 | ||
391 | #elif defined(GEKKO) | |
392 | const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); | |
393 | int inet_pton(int af, const char *src, void *dst); | |
394 | ||
395 | #endif | |
396 | ||
397 | int getaddrinfo_retro(const char *node, const char *service, | |
398 | struct addrinfo *hints, struct addrinfo **res); | |
399 | ||
400 | void freeaddrinfo_retro(struct addrinfo *res); | |
401 | ||
402 | int getnameinfo_retro(const struct sockaddr *addr, socklen_t addrlen, | |
403 | char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags); | |
404 | ||
405 | bool addr_6to4(struct sockaddr_storage *addr); | |
406 | ||
407 | bool ipv4_is_lan_address(const struct sockaddr_in *addr); | |
408 | bool ipv4_is_cgnat_address(const struct sockaddr_in *addr); | |
409 | ||
410 | /** | |
411 | * network_init: | |
412 | * | |
413 | * Platform specific socket library initialization. | |
414 | * | |
415 | * @return true if successful, otherwise false. | |
416 | **/ | |
417 | bool network_init(void); | |
418 | ||
419 | RETRO_END_DECLS | |
420 | ||
421 | #endif |