git subrepo clone https://github.com/libretro/libretro-common.git deps/libretro-common
[pcsx_rearmed.git] / deps / libretro-common / include / net / net_compat.h
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