1 #include "nonblocksockets.h" |
|
2 #include "logging.h" |
|
3 #include <stdlib.h> |
|
4 |
|
5 static uint32_t get_peer_ip(TCPsocket sock) { |
|
6 IPaddress *addr = SDLNet_TCP_GetPeerAddress(sock); |
|
7 return SDLNet_Read32(&addr->host); |
|
8 } |
|
9 |
|
10 static bool connection_is_local(TCPsocket sock) { |
|
11 return get_peer_ip(sock) == (uint32_t)((127UL<<24)+1); // 127.0.0.1 |
|
12 } |
|
13 |
|
14 void flib_nbsocket_close(NonBlockSocket *nbsockptr) { |
|
15 NonBlockSocket nbsock = *nbsockptr; |
|
16 if(nbsock!=NULL) { |
|
17 SDLNet_DelSocket(nbsock->sockset, (SDLNet_GenericSocket)nbsock->sock); |
|
18 SDLNet_TCP_Close(nbsock->sock); |
|
19 SDLNet_FreeSocketSet(nbsock->sockset); |
|
20 } |
|
21 free(nbsock); |
|
22 *nbsockptr = NULL; |
|
23 } |
|
24 |
|
25 NonBlockSocket flib_nbsocket_accept(TCPsocket listensocket, bool localOnly) { |
|
26 NonBlockSocket result = NULL; |
|
27 if(!listensocket) { |
|
28 flib_log_e("Attempt to accept a connection on a NULL socket."); |
|
29 return NULL; |
|
30 } |
|
31 while(result==NULL) { |
|
32 TCPsocket sock = SDLNet_TCP_Accept(listensocket); |
|
33 if(!sock) { |
|
34 // No incoming connections |
|
35 return NULL; |
|
36 } |
|
37 if(localOnly && !connection_is_local(sock)) { |
|
38 flib_log_i("Rejected nonlocal connection attempt from %s", flib_format_ip(get_peer_ip(sock))); |
|
39 SDLNet_TCP_Close(sock); |
|
40 } else { |
|
41 result = malloc(sizeof(_NonBlockSocket)); |
|
42 if(result==NULL) { |
|
43 flib_log_e("Out of memory!"); |
|
44 SDLNet_TCP_Close(sock); |
|
45 return NULL; |
|
46 } |
|
47 result->sock = sock; |
|
48 result->sockset = SDLNet_AllocSocketSet(1); |
|
49 if(result->sockset==NULL) { |
|
50 flib_log_e("Out of memory!"); |
|
51 SDLNet_TCP_Close(sock); |
|
52 free(result); |
|
53 return NULL; |
|
54 } |
|
55 SDLNet_AddSocket(result->sockset, (SDLNet_GenericSocket)result->sock); |
|
56 } |
|
57 } |
|
58 return result; |
|
59 } |
|
60 |
|
61 int flib_nbsocket_recv(NonBlockSocket sock, void *data, int maxlen) { |
|
62 if(!sock) { |
|
63 flib_log_e("Attempt to receive on a NULL socket."); |
|
64 return -1; |
|
65 } |
|
66 int readySockets = SDLNet_CheckSockets(sock->sockset, 0); |
|
67 if(readySockets>0) { |
|
68 int size = SDLNet_TCP_Recv(sock->sock, data, maxlen); |
|
69 return size>0 ? size : -1; |
|
70 } else if(readySockets==0) { |
|
71 return 0; |
|
72 } else { |
|
73 flib_log_e("Error in select system call: %s", SDLNet_GetError()); |
|
74 return -1; |
|
75 } |
|
76 } |
|