1bf215546Sopenharmony_ci 2bf215546Sopenharmony_ci#include "pipe/p_compiler.h" 3bf215546Sopenharmony_ci#include "util/u_network.h" 4bf215546Sopenharmony_ci#include "util/u_debug.h" 5bf215546Sopenharmony_ci#include "util/u_string.h" 6bf215546Sopenharmony_ci 7bf215546Sopenharmony_ci#include <stdio.h> 8bf215546Sopenharmony_ci#if defined(PIPE_OS_WINDOWS) 9bf215546Sopenharmony_ci# include <winsock2.h> 10bf215546Sopenharmony_ci# include <windows.h> 11bf215546Sopenharmony_ci# include <ws2tcpip.h> 12bf215546Sopenharmony_ci#elif defined(PIPE_OS_UNIX) 13bf215546Sopenharmony_ci# include <sys/socket.h> 14bf215546Sopenharmony_ci# include <netinet/in.h> 15bf215546Sopenharmony_ci# include <unistd.h> 16bf215546Sopenharmony_ci# include <fcntl.h> 17bf215546Sopenharmony_ci# include <netdb.h> 18bf215546Sopenharmony_ci#else 19bf215546Sopenharmony_ci# warning "No socket implementation" 20bf215546Sopenharmony_ci#endif 21bf215546Sopenharmony_ci 22bf215546Sopenharmony_ciboolean 23bf215546Sopenharmony_ciu_socket_init(void) 24bf215546Sopenharmony_ci{ 25bf215546Sopenharmony_ci#if defined(PIPE_OS_WINDOWS) 26bf215546Sopenharmony_ci WORD wVersionRequested; 27bf215546Sopenharmony_ci WSADATA wsaData; 28bf215546Sopenharmony_ci int err; 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ 31bf215546Sopenharmony_ci wVersionRequested = MAKEWORD(1, 1); 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci err = WSAStartup(wVersionRequested, &wsaData); 34bf215546Sopenharmony_ci if (err != 0) { 35bf215546Sopenharmony_ci debug_printf("WSAStartup failed with error: %d\n", err); 36bf215546Sopenharmony_ci return FALSE; 37bf215546Sopenharmony_ci } 38bf215546Sopenharmony_ci return TRUE; 39bf215546Sopenharmony_ci#elif defined(PIPE_HAVE_SOCKETS) 40bf215546Sopenharmony_ci return TRUE; 41bf215546Sopenharmony_ci#else 42bf215546Sopenharmony_ci return FALSE; 43bf215546Sopenharmony_ci#endif 44bf215546Sopenharmony_ci} 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_civoid 47bf215546Sopenharmony_ciu_socket_stop(void) 48bf215546Sopenharmony_ci{ 49bf215546Sopenharmony_ci#if defined(PIPE_OS_WINDOWS) 50bf215546Sopenharmony_ci WSACleanup(); 51bf215546Sopenharmony_ci#endif 52bf215546Sopenharmony_ci} 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_civoid 55bf215546Sopenharmony_ciu_socket_close(int s) 56bf215546Sopenharmony_ci{ 57bf215546Sopenharmony_ci if (s < 0) 58bf215546Sopenharmony_ci return; 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci#if defined(PIPE_OS_UNIX) 61bf215546Sopenharmony_ci shutdown(s, SHUT_RDWR); 62bf215546Sopenharmony_ci close(s); 63bf215546Sopenharmony_ci#elif defined(PIPE_OS_WINDOWS) 64bf215546Sopenharmony_ci shutdown(s, SD_BOTH); 65bf215546Sopenharmony_ci closesocket(s); 66bf215546Sopenharmony_ci#else 67bf215546Sopenharmony_ci assert(0); 68bf215546Sopenharmony_ci#endif 69bf215546Sopenharmony_ci} 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ciint u_socket_accept(int s) 72bf215546Sopenharmony_ci{ 73bf215546Sopenharmony_ci#if defined(PIPE_HAVE_SOCKETS) 74bf215546Sopenharmony_ci return accept(s, NULL, NULL); 75bf215546Sopenharmony_ci#else 76bf215546Sopenharmony_ci return -1; 77bf215546Sopenharmony_ci#endif 78bf215546Sopenharmony_ci} 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ciint 81bf215546Sopenharmony_ciu_socket_send(int s, void *data, size_t size) 82bf215546Sopenharmony_ci{ 83bf215546Sopenharmony_ci#if defined(PIPE_HAVE_SOCKETS) 84bf215546Sopenharmony_ci return send(s, data, size, 0); 85bf215546Sopenharmony_ci#else 86bf215546Sopenharmony_ci return -1; 87bf215546Sopenharmony_ci#endif 88bf215546Sopenharmony_ci} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ciint 91bf215546Sopenharmony_ciu_socket_peek(int s, void *data, size_t size) 92bf215546Sopenharmony_ci{ 93bf215546Sopenharmony_ci#if defined(PIPE_HAVE_SOCKETS) 94bf215546Sopenharmony_ci return recv(s, data, size, MSG_PEEK); 95bf215546Sopenharmony_ci#else 96bf215546Sopenharmony_ci return -1; 97bf215546Sopenharmony_ci#endif 98bf215546Sopenharmony_ci} 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ciint 101bf215546Sopenharmony_ciu_socket_recv(int s, void *data, size_t size) 102bf215546Sopenharmony_ci{ 103bf215546Sopenharmony_ci#if defined(PIPE_HAVE_SOCKETS) 104bf215546Sopenharmony_ci return recv(s, data, size, 0); 105bf215546Sopenharmony_ci#else 106bf215546Sopenharmony_ci return -1; 107bf215546Sopenharmony_ci#endif 108bf215546Sopenharmony_ci} 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ciint 111bf215546Sopenharmony_ciu_socket_connect(const char *hostname, uint16_t port) 112bf215546Sopenharmony_ci{ 113bf215546Sopenharmony_ci#if defined(PIPE_HAVE_SOCKETS) 114bf215546Sopenharmony_ci int s, r; 115bf215546Sopenharmony_ci struct addrinfo hints, *addr; 116bf215546Sopenharmony_ci char portString[20]; 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci memset(&hints, 0, sizeof hints); 119bf215546Sopenharmony_ci hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version 120bf215546Sopenharmony_ci hints.ai_socktype = SOCK_STREAM; 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci snprintf(portString, sizeof(portString), "%d", port); 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci r = getaddrinfo(hostname, portString, NULL, &addr); 125bf215546Sopenharmony_ci if (r != 0) { 126bf215546Sopenharmony_ci return -1; 127bf215546Sopenharmony_ci } 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci s = socket(addr->ai_family, SOCK_STREAM, IPPROTO_TCP); 130bf215546Sopenharmony_ci if (s < 0) { 131bf215546Sopenharmony_ci freeaddrinfo(addr); 132bf215546Sopenharmony_ci return -1; 133bf215546Sopenharmony_ci } 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci if (connect(s, addr->ai_addr, (int) addr->ai_addrlen)) { 136bf215546Sopenharmony_ci u_socket_close(s); 137bf215546Sopenharmony_ci freeaddrinfo(addr); 138bf215546Sopenharmony_ci return -1; 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci freeaddrinfo(addr); 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci return s; 144bf215546Sopenharmony_ci#else 145bf215546Sopenharmony_ci assert(0); 146bf215546Sopenharmony_ci return -1; 147bf215546Sopenharmony_ci#endif 148bf215546Sopenharmony_ci} 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ciint 151bf215546Sopenharmony_ciu_socket_listen_on_port(uint16_t portnum) 152bf215546Sopenharmony_ci{ 153bf215546Sopenharmony_ci#if defined(PIPE_HAVE_SOCKETS) 154bf215546Sopenharmony_ci int s; 155bf215546Sopenharmony_ci struct sockaddr_in sa; 156bf215546Sopenharmony_ci memset(&sa, 0, sizeof(struct sockaddr_in)); 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci sa.sin_family = AF_INET; 159bf215546Sopenharmony_ci sa.sin_port = htons(portnum); 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 162bf215546Sopenharmony_ci if (s < 0) 163bf215546Sopenharmony_ci return -1; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) { 166bf215546Sopenharmony_ci u_socket_close(s); 167bf215546Sopenharmony_ci return -1; 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci listen(s, 1); 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci return s; 173bf215546Sopenharmony_ci#else 174bf215546Sopenharmony_ci assert(0); 175bf215546Sopenharmony_ci return -1; 176bf215546Sopenharmony_ci#endif 177bf215546Sopenharmony_ci} 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_civoid 180bf215546Sopenharmony_ciu_socket_block(int s, boolean block) 181bf215546Sopenharmony_ci{ 182bf215546Sopenharmony_ci#if defined(PIPE_OS_UNIX) 183bf215546Sopenharmony_ci int old = fcntl(s, F_GETFL, 0); 184bf215546Sopenharmony_ci if (old == -1) 185bf215546Sopenharmony_ci return; 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci /* TODO obey block */ 188bf215546Sopenharmony_ci if (block) 189bf215546Sopenharmony_ci fcntl(s, F_SETFL, old & ~O_NONBLOCK); 190bf215546Sopenharmony_ci else 191bf215546Sopenharmony_ci fcntl(s, F_SETFL, old | O_NONBLOCK); 192bf215546Sopenharmony_ci#elif defined(PIPE_OS_WINDOWS) 193bf215546Sopenharmony_ci u_long iMode = block ? 0 : 1; 194bf215546Sopenharmony_ci ioctlsocket(s, FIONBIO, &iMode); 195bf215546Sopenharmony_ci#else 196bf215546Sopenharmony_ci assert(0); 197bf215546Sopenharmony_ci#endif 198bf215546Sopenharmony_ci} 199