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