frontlib/nonblocksockets.c
changeset 7162 fe76d24a25d7
parent 7160 c42949cfdd92
child 7166 8d1d6adf5f82
equal deleted inserted replaced
7160:c42949cfdd92 7162:fe76d24a25d7
     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 }