1 /* Copyright  (C) 2010-2020 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_NETPLAY_COMPAT_H__
24 #define LIBRETRO_SDK_NETPLAY_COMPAT_H__
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include <boolean.h>
31 #include <retro_inline.h>
32 #include <stdint.h>
33 
34 #if defined(_WIN32) && !defined(_XBOX)
35 #ifndef _WIN32_WINNT
36 #define _WIN32_WINNT 0x0501
37 #endif
38 
39 #define WIN32_LEAN_AND_MEAN
40 
41 #include <winsock2.h>
42 #include <windows.h>
43 #include <ws2tcpip.h>
44 
45 #ifndef MSG_NOSIGNAL
46 #define MSG_NOSIGNAL 0
47 #endif
48 
49 #elif defined(_XBOX)
50 
51 #define NOD3D
52 #include <xtl.h>
53 #include <io.h>
54 
55 #elif defined(GEKKO)
56 
57 #include <network.h>
58 
59 #elif defined(VITA)
60 
61 #include <psp2/net/net.h>
62 #include <psp2/net/netctl.h>
63 
64 #define sockaddr_in SceNetSockaddrIn
65 #define sockaddr SceNetSockaddr
66 #define sendto sceNetSendto
67 #define recvfrom sceNetRecvfrom
68 #define socket(a,b,c) sceNetSocket("unknown",a,b,c)
69 #define bind sceNetBind
70 #define accept sceNetAccept
71 #define setsockopt sceNetSetsockopt
72 #define connect sceNetConnect
73 #define listen sceNetListen
74 #define send sceNetSend
75 #define recv sceNetRecv
76 #define MSG_DONTWAIT SCE_NET_MSG_DONTWAIT
77 #define AF_INET SCE_NET_AF_INET
78 #define AF_UNSPEC 0
79 #define INADDR_ANY SCE_NET_INADDR_ANY
80 #define INADDR_NONE 0xffffffff
81 #define SOCK_STREAM SCE_NET_SOCK_STREAM
82 #define SOCK_DGRAM SCE_NET_SOCK_DGRAM
83 #define SOL_SOCKET SCE_NET_SOL_SOCKET
84 #define SO_REUSEADDR SCE_NET_SO_REUSEADDR
85 #define SO_SNDBUF SCE_NET_SO_SNDBUF
86 #define SO_SNDTIMEO SCE_NET_SO_SNDTIMEO
87 #define SO_NBIO SCE_NET_SO_NBIO
88 #define htonl sceNetHtonl
89 #define ntohl sceNetNtohl
90 #define htons sceNetHtons
91 #define socklen_t unsigned int
92 
93 struct hostent
94 {
95 	char *h_name;
96 	char **h_aliases;
97 	int  h_addrtype;
98 	int  h_length;
99 	char **h_addr_list;
100 	char *h_addr;
101 };
102 
103 struct SceNetInAddr inet_aton(const char *ip_addr);
104 
105 #else
106 #include <sys/select.h>
107 #include <sys/types.h>
108 #include <sys/socket.h>
109 #include <netinet/in.h>
110 
111 #ifndef __PSL1GHT__
112 #include <netinet/tcp.h>
113 #endif
114 
115 #include <arpa/inet.h>
116 #include <netdb.h>
117 #include <fcntl.h>
118 
119 #if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)
120 #include <cell/sysmodule.h>
121 #include <netex/net.h>
122 #include <netex/libnetctl.h>
123 #include <sys/timer.h>
124 
125 #ifndef EWOULDBLOCK
126 #define EWOULDBLOCK SYS_NET_EWOULDBLOCK
127 #endif
128 
129 #else
130 #include <signal.h>
131 #endif
132 
133 #endif
134 
135 #include <errno.h>
136 
137 #ifdef GEKKO
138 #define sendto(s, msg, len, flags, addr, tolen) net_sendto(s, msg, len, 0, addr, 8)
139 #define socket(domain, type, protocol) net_socket(domain, type, protocol)
140 #define bind(s, name, namelen) net_bind(s, name, namelen)
141 #define listen(s, backlog) net_listen(s, backlog)
142 #define accept(s, addr, addrlen) net_accept(s, addr, addrlen)
143 #define connect(s, addr, addrlen) net_connect(s, addr, addrlen)
144 #define send(s, data, size, flags) net_send(s, data, size, flags)
145 #define recv(s, mem, len, flags) net_recv(s, mem, len, flags)
146 #define recvfrom(s, mem, len, flags, from, fromlen) net_recvfrom(s, mem, len, flags, from, fromlen)
147 #define select(maxfdp1, readset, writeset, exceptset, timeout) net_select(maxfdp1, readset, writeset, exceptset, timeout)
148 #endif
149 
isagain(int bytes)150 static INLINE bool isagain(int bytes)
151 {
152 #if defined(_WIN32)
153    if (bytes != SOCKET_ERROR)
154       return false;
155    if (WSAGetLastError() != WSAEWOULDBLOCK)
156       return false;
157    return true;
158 #elif defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)
159    return (sys_net_errno == SYS_NET_EWOULDBLOCK) || (sys_net_errno == SYS_NET_EAGAIN);//35
160 #elif defined(VITA)
161    return (bytes<0 && (bytes == SCE_NET_ERROR_EAGAIN || bytes == SCE_NET_ERROR_EWOULDBLOCK));
162 #elif defined(WIIU)
163    return (bytes == -1) && ((socketlasterr() == SO_SUCCESS) || (socketlasterr() == SO_EWOULDBLOCK));
164 #else
165    return (bytes < 0 && (errno == EAGAIN || errno == EWOULDBLOCK));
166 #endif
167 }
168 
169 #ifdef _XBOX
170 #define socklen_t int
171 
172 #ifndef h_addr
173 #define h_addr h_addr_list[0] /* for backward compatibility */
174 #endif
175 
176 #ifndef SO_KEEPALIVE
177 #define SO_KEEPALIVE 0 /* verify if correct */
178 #endif
179 #endif
180 
181 #ifndef MSG_NOSIGNAL
182 #define MSG_NOSIGNAL 0
183 #endif
184 
185 #ifndef _WIN32
186 #include <sys/time.h>
187 #include <unistd.h>
188 #endif
189 
190 /* Compatibility layer for legacy or incomplete BSD socket implementations.
191  * Only for IPv4. Mostly useful for the consoles which do not support
192  * anything reasonably modern on the socket API side of things. */
193 
194 #ifdef HAVE_SOCKET_LEGACY
195 
196 #define sockaddr_storage sockaddr_in
197 #define addrinfo addrinfo_retro__
198 
199 struct addrinfo
200 {
201    int ai_flags;
202    int ai_family;
203    int ai_socktype;
204    int ai_protocol;
205    size_t ai_addrlen;
206    struct sockaddr *ai_addr;
207    char *ai_canonname;
208    struct addrinfo *ai_next;
209 };
210 
211 #ifndef AI_PASSIVE
212 #define AI_PASSIVE 1
213 #endif
214 
215 /* gai_strerror() not used, so we skip that. */
216 
217 #endif
218 
219 uint16_t inet_htons(uint16_t hostshort);
220 
221 int inet_ptrton(int af, const char *src, void *dst);
222 
223 int getaddrinfo_retro(const char *node, const char *service,
224       struct addrinfo *hints, struct addrinfo **res);
225 
226 void freeaddrinfo_retro(struct addrinfo *res);
227 
228 /**
229  * network_init:
230  *
231  * Platform specific socket library initialization.
232  *
233  * Returns: true (1) if successful, otherwise false (0).
234  **/
235 bool network_init(void);
236 
237 /**
238  * network_deinit:
239  *
240  * Deinitialize platform specific socket libraries.
241  **/
242 void network_deinit(void);
243 
244 const char *inet_ntop_compat(int af, const void *src, char *dst, socklen_t cnt);
245 
246 bool udp_send_packet(const char *host, uint16_t port, const char *msg);
247 
248 #endif
249