|
|
|
@@ -0,0 +1,188 @@ |
|
|
|
|
|
|
|
#include "pipe/p_compiler.h" |
|
|
|
#include "util/u_network.h" |
|
|
|
#include "util/u_debug.h" |
|
|
|
|
|
|
|
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
|
|
|
# include <windows.h> |
|
|
|
# include <winsock.h> |
|
|
|
#elif defined(PIPE_OS_LINUX) |
|
|
|
# include <sys/socket.h> |
|
|
|
# include <netinet/in.h> |
|
|
|
# include <unistd.h> |
|
|
|
# include <fcntl.h> |
|
|
|
# include <netdb.h> |
|
|
|
#else |
|
|
|
# warning "No socket implementation" |
|
|
|
#endif |
|
|
|
|
|
|
|
boolean |
|
|
|
u_socket_init() |
|
|
|
{ |
|
|
|
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
|
|
|
WORD wVersionRequested; |
|
|
|
WSADATA wsaData; |
|
|
|
int err; |
|
|
|
|
|
|
|
/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ |
|
|
|
wVersionRequested = MAKEWORD(1, 1); |
|
|
|
|
|
|
|
err = WSAStartup(wVersionRequested, &wsaData); |
|
|
|
if (err != 0) { |
|
|
|
debug_printf("WSAStartup failed with error: %d\n", err); |
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
return TRUE; |
|
|
|
#elif defined(PIPE_HAVE_SOCKETS) |
|
|
|
return TRUE; |
|
|
|
#else |
|
|
|
return FALSE; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
u_socket_stop() |
|
|
|
{ |
|
|
|
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
|
|
|
WSACleanup(); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
u_socket_close(int s) |
|
|
|
{ |
|
|
|
if (s < 0) |
|
|
|
return; |
|
|
|
|
|
|
|
#if defined(PIPE_OS_LINUX) |
|
|
|
shutdown(s, SHUT_RDWR); |
|
|
|
close(s); |
|
|
|
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
|
|
|
shutdown(s, SD_BOTH); |
|
|
|
closesocket(s); |
|
|
|
#else |
|
|
|
assert(0); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int u_socket_accept(int s) |
|
|
|
{ |
|
|
|
#if defined(PIPE_HAVE_SOCKETS) |
|
|
|
return accept(s, NULL, NULL); |
|
|
|
#else |
|
|
|
return -1; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
u_socket_send(int s, void *data, size_t size) |
|
|
|
{ |
|
|
|
#if defined(PIPE_HAVE_SOCKETS) |
|
|
|
return send(s, data, size, 0); |
|
|
|
#else |
|
|
|
return -1; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
u_socket_peek(int s, void *data, size_t size) |
|
|
|
{ |
|
|
|
#if defined(PIPE_HAVE_SOCKETS) |
|
|
|
return recv(s, data, size, MSG_PEEK); |
|
|
|
#else |
|
|
|
return -1; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
u_socket_recv(int s, void *data, size_t size) |
|
|
|
{ |
|
|
|
#if defined(PIPE_HAVE_SOCKETS) |
|
|
|
return recv(s, data, size, 0); |
|
|
|
#else |
|
|
|
return -1; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
u_socket_connect(const char *hostname, uint16_t port) |
|
|
|
{ |
|
|
|
#if defined(PIPE_HAVE_SOCKETS) |
|
|
|
int s; |
|
|
|
struct sockaddr_in sa; |
|
|
|
struct hostent *host = NULL; |
|
|
|
|
|
|
|
memset(&sa, 0, sizeof(struct sockaddr_in)); |
|
|
|
host = gethostbyname(hostname); |
|
|
|
if (!host) |
|
|
|
return -1; |
|
|
|
|
|
|
|
memcpy((char *)&sa.sin_addr,host->h_addr,host->h_length); |
|
|
|
sa.sin_family= host->h_addrtype; |
|
|
|
sa.sin_port = htons(port); |
|
|
|
|
|
|
|
s = socket(host->h_addrtype, SOCK_STREAM, IPPROTO_TCP); |
|
|
|
if (s < 0) |
|
|
|
return -1; |
|
|
|
|
|
|
|
if (connect(s, (struct sockaddr *)&sa, sizeof(sa))) { |
|
|
|
u_socket_close(s); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
return s; |
|
|
|
#else |
|
|
|
assert(0); |
|
|
|
return -1; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
u_socket_listen_on_port(uint16_t portnum) |
|
|
|
{ |
|
|
|
#if defined(PIPE_HAVE_SOCKETS) |
|
|
|
int s; |
|
|
|
struct sockaddr_in sa; |
|
|
|
memset(&sa, 0, sizeof(struct sockaddr_in)); |
|
|
|
|
|
|
|
sa.sin_family = AF_INET; |
|
|
|
sa.sin_port = htons(portnum); |
|
|
|
|
|
|
|
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
|
|
|
if (s < 0) |
|
|
|
return -1; |
|
|
|
|
|
|
|
if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) { |
|
|
|
u_socket_close(s); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
listen(s, 0); |
|
|
|
|
|
|
|
return s; |
|
|
|
#else |
|
|
|
assert(0); |
|
|
|
return -1; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
u_socket_block(int s, boolean block) |
|
|
|
{ |
|
|
|
#if defined(PIPE_OS_LINUX) |
|
|
|
int old = fcntl(s, F_GETFL, 0); |
|
|
|
if (old == -1) |
|
|
|
return; |
|
|
|
|
|
|
|
/* TODO obey block */ |
|
|
|
if (block) |
|
|
|
fcntl(s, F_SETFL, old & ~O_NONBLOCK); |
|
|
|
else |
|
|
|
fcntl(s, F_SETFL, old | O_NONBLOCK); |
|
|
|
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
|
|
|
u_long iMode = block ? 0 : 1; |
|
|
|
ioctlsocket(s, FIONBIO, &iMode); |
|
|
|
#else |
|
|
|
assert(0); |
|
|
|
#endif |
|
|
|
} |