1aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 2aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#include "pipe/p_compiler.h" 3aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#include "util/u_network.h" 4aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#include "util/u_debug.h" 5aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 6aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) 7b04470b0bce6a24a74a0ec8cf16d9d3f03aff5f2Michal Krol# include <winsock2.h> 8aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz# include <windows.h> 968657183b0e42093777034460e0a93624b7ba501Alan Coopersmith#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || \ 1068657183b0e42093777034460e0a93624b7ba501Alan Coopersmith defined(PIPE_OS_APPLE) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS) 11aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz# include <sys/socket.h> 12aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz# include <netinet/in.h> 13aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz# include <unistd.h> 14aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz# include <fcntl.h> 15aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz# include <netdb.h> 16aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 17aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz# warning "No socket implementation" 18aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 19aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 20aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzboolean 21aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_init() 22aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 23aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) 24aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz WORD wVersionRequested; 25aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz WSADATA wsaData; 26aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz int err; 27aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 28aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ 29aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz wVersionRequested = MAKEWORD(1, 1); 30aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 31aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz err = WSAStartup(wVersionRequested, &wsaData); 32aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz if (err != 0) { 33aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz debug_printf("WSAStartup failed with error: %d\n", err); 34aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return FALSE; 35aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz } 36aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return TRUE; 37aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#elif defined(PIPE_HAVE_SOCKETS) 38aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return TRUE; 39aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 40aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return FALSE; 41aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 42aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 43aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 44aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzvoid 45aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_stop() 46aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 47aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) 48aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz WSACleanup(); 49aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 50aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 51aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 52aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzvoid 53aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_close(int s) 54aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 55aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz if (s < 0) 56aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return; 57aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 5868657183b0e42093777034460e0a93624b7ba501Alan Coopersmith#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \ 5968657183b0e42093777034460e0a93624b7ba501Alan Coopersmith || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS) 60aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz shutdown(s, SHUT_RDWR); 61aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz close(s); 62aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) 63aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz shutdown(s, SD_BOTH); 64aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz closesocket(s); 65aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 66aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz assert(0); 67aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 68aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 69aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 70aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint u_socket_accept(int s) 71aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 72aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS) 73aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return accept(s, NULL, NULL); 74aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 75aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 76aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 77aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 78aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 79aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint 80aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_send(int s, void *data, size_t size) 81aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 82aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS) 83aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return send(s, data, size, 0); 84aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 85aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 86aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 87aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 88aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 89aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint 90aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_peek(int s, void *data, size_t size) 91aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 92aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS) 93aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return recv(s, data, size, MSG_PEEK); 94aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 95aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 96aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 97aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 98aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 99aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint 100aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_recv(int s, void *data, size_t size) 101aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 102aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS) 103aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return recv(s, data, size, 0); 104aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 105aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 106aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 107aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 108aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 109aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint 110aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_connect(const char *hostname, uint16_t port) 111aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 112aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS) 113aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz int s; 114aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz struct sockaddr_in sa; 115aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz struct hostent *host = NULL; 116aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 117aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz memset(&sa, 0, sizeof(struct sockaddr_in)); 118aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz host = gethostbyname(hostname); 119aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz if (!host) 120aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 121aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 1227df06e7e9d5d5ac0a5a2fa0af11afa7f5241c5a4Vinson Lee memcpy((char *)&sa.sin_addr,host->h_addr_list[0],host->h_length); 123aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz sa.sin_family= host->h_addrtype; 124aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz sa.sin_port = htons(port); 125aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 126aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz s = socket(host->h_addrtype, SOCK_STREAM, IPPROTO_TCP); 127aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz if (s < 0) 128aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 129aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 130aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz if (connect(s, (struct sockaddr *)&sa, sizeof(sa))) { 131aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz u_socket_close(s); 132aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 133aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz } 134aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 135aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return s; 136aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 137aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz assert(0); 138aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 139aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 140aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 141aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 142aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint 143aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_listen_on_port(uint16_t portnum) 144aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 145aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS) 146aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz int s; 147aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz struct sockaddr_in sa; 148aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz memset(&sa, 0, sizeof(struct sockaddr_in)); 149aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 150aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz sa.sin_family = AF_INET; 151aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz sa.sin_port = htons(portnum); 152aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 153aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 154aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz if (s < 0) 155aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 156aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 157aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) { 158aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz u_socket_close(s); 159aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 160aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz } 161aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 162aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz listen(s, 0); 163aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 164aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return s; 165aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 166aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz assert(0); 167aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return -1; 168aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 169aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 170aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 171aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzvoid 172aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_block(int s, boolean block) 173aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{ 17468657183b0e42093777034460e0a93624b7ba501Alan Coopersmith#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \ 17568657183b0e42093777034460e0a93624b7ba501Alan Coopersmith || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS) 176aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz int old = fcntl(s, F_GETFL, 0); 177aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz if (old == -1) 178aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz return; 179aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz 180aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz /* TODO obey block */ 181aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz if (block) 182aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz fcntl(s, F_SETFL, old & ~O_NONBLOCK); 183aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz else 184aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz fcntl(s, F_SETFL, old | O_NONBLOCK); 185aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) 186aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz u_long iMode = block ? 0 : 1; 187aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz ioctlsocket(s, FIONBIO, &iMode); 188aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else 189aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz assert(0); 190aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif 191aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz} 192