aboutsummaryrefslogtreecommitdiff
path: root/src/util/network.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-11-01 20:47:52 +0000
committerChristian Grothoff <christian@grothoff.org>2009-11-01 20:47:52 +0000
commit652e89b59ed2207c2c12172fdabcd6e659995c81 (patch)
treef054c819d483c1056e18c1099afd4c7fcd2582a0 /src/util/network.c
parent5e4113e83368849500792e57946c3d8dd9e548d8 (diff)
downloadgnunet-652e89b59ed2207c2c12172fdabcd6e659995c81.tar.gz
gnunet-652e89b59ed2207c2c12172fdabcd6e659995c81.zip
fixing bio testcase and a bug in bio.c, also indenting
Diffstat (limited to 'src/util/network.c')
-rw-r--r--src/util/network.c1600
1 files changed, 827 insertions, 773 deletions
diff --git a/src/util/network.c b/src/util/network.c
index 071b18cc6..df3c90c81 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -16,90 +16,94 @@
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21/** 21/**
22 * @file util/network.c 22 * @file util/network.c
23 * @brief basic, low-level networking interface 23 * @brief basic, low-level networking interface
24 * @author Nils Durner 24 * @author Nils Durner
25 */ 25 */
26 26
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_disk_lib.h" 28#include "gnunet_disk_lib.h"
29#include "disk.h" 29#include "disk.h"
30#include "gnunet_container_lib.h" 30#include "gnunet_container_lib.h"
31 31
32#define DEBUG_NETWORK GNUNET_NO 32#define DEBUG_NETWORK GNUNET_NO
33 33
34#ifndef INVALID_SOCKET 34#ifndef INVALID_SOCKET
35#define INVALID_SOCKET -1 35#define INVALID_SOCKET -1
36#endif 36#endif /* */
37 37 struct GNUNET_NETWORK_Handle
38struct GNUNET_NETWORK_Handle 38{
39{ 39 int fd;
40 int fd; 40 };
41}; 41 struct GNUNET_NETWORK_FDSet
42 42{
43struct GNUNET_NETWORK_FDSet 43
44{ 44 /* socket descriptors */
45 /* socket descriptors */ 45 int nsds;
46 int nsds; 46 fd_set sds;
47 fd_set sds; 47
48#ifdef WINDOWS 48#ifdef WINDOWS
49 /* handles */ 49 /* handles */
50 struct GNUNET_CONTAINER_SList *handles; 50 struct GNUNET_CONTAINER_SList *handles;
51#endif 51
52}; 52#endif /* */
53 53};
54
54#ifndef FD_COPY 55#ifndef FD_COPY
55#define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set))) 56#define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set)))
56#endif 57#endif /* */
57 58
58
59
60/** 59/**
61 * Set if a socket should use blocking or non-blocking IO. 60 * Set if a socket should use blocking or non-blocking IO.
62 * @param fd socket 61 * @param fd socket
63 * @param doBlock blocking mode 62 * @param doBlock blocking mode
64 * @return GNUNET_OK on success, GNUNET_SYSERR on error 63 * @return GNUNET_OK on success, GNUNET_SYSERR on error
65 */ 64 */
66static int 65static int
67socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, 66socket_set_blocking (struct GNUNET_NETWORK_Handle *fd, int doBlock)
68 int doBlock) 67{
69{ 68
70#if MINGW 69#if MINGW
71 u_long mode; 70 u_long mode;
72 mode = !doBlock; 71 mode = !doBlock;
73 if (ioctlsocket (fd->fd, FIONBIO, &mode) == SOCKET_ERROR) 72 if (ioctlsocket (fd->fd, FIONBIO, &mode) == SOCKET_ERROR)
74 { 73
75 SetErrnoFromWinsockError (WSAGetLastError ()); 74 {
76 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket"); 75 SetErrnoFromWinsockError (WSAGetLastError ());
77 return GNUNET_SYSERR; 76 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket");
78 } 77 return GNUNET_SYSERR;
79 return GNUNET_OK; 78 }
80 79 return GNUNET_OK;
81#else 80
82 /* not MINGW */ 81#else /* */
83 int flags = fcntl (fd->fd, F_GETFL); 82 /* not MINGW */
84 if (flags == -1) 83 int flags = fcntl (fd->fd, F_GETFL);
85 { 84 if (flags == -1)
86 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl"); 85
87 return GNUNET_SYSERR; 86 {
88 } 87 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");
89 if (doBlock) 88 return GNUNET_SYSERR;
90 flags &= ~O_NONBLOCK; 89 }
91 else 90 if (doBlock)
92 flags |= O_NONBLOCK; 91 flags &= ~O_NONBLOCK;
93 if (0 != fcntl (fd->fd, F_SETFL, flags)) 92
94 { 93 else
95 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl"); 94 flags |= O_NONBLOCK;
96 return GNUNET_SYSERR; 95 if (0 != fcntl (fd->fd, F_SETFL, flags))
97 } 96
98 return GNUNET_OK; 97 {
99#endif 98 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");
100} 99 return GNUNET_SYSERR;
101 100 }
102 101 return GNUNET_OK;
102
103#endif /* */
104}
105
106
103#ifndef MINGW 107#ifndef MINGW
104/** 108/**
105 * Make a socket non-inheritable to child processes 109 * Make a socket non-inheritable to child processes
@@ -107,62 +111,56 @@ socket_set_blocking (struct GNUNET_NETWORK_Handle *fd,
107 * @param h the socket to make non-inheritable 111 * @param h the socket to make non-inheritable
108 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 112 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
109 * @warning Not implemented on Windows 113 * @warning Not implemented on Windows
110 */ 114 */
111static int 115static int
112socket_set_inheritable (const struct GNUNET_NETWORK_Handle 116socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h)
113 *h) 117{
114{ 118 int i;
115 int i; 119 i = fcntl (h->fd, F_GETFD);
116 120 if (i == (i | FD_CLOEXEC))
117 i = fcntl (h->fd, F_GETFD); 121 return GNUNET_OK;
118 if (i == (i | FD_CLOEXEC)) 122 return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0)
119 return GNUNET_OK; 123 ? GNUNET_OK : GNUNET_SYSERR;
120 return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0) 124 }
121 ? GNUNET_OK : GNUNET_SYSERR; 125
122} 126
123#endif 127#endif /* */
124 128
125
126
127#ifdef DARWIN 129#ifdef DARWIN
128/** 130/**
129 * The MSG_NOSIGNAL equivalent on Mac OS X 131 * The MSG_NOSIGNAL equivalent on Mac OS X
130 * 132 *
131 * @param h the socket to make non-delaying 133 * @param h the socket to make non-delaying
132 */ 134 */
133static void 135static void
134socket_set_nosigpipe (const struct GNUNET_NETWORK_Handle 136socket_set_nosigpipe (const struct GNUNET_NETWORK_Handle *h)
135 *h) 137{
136{ 138 int value = 1;
137 int value = 1; 139 if (0 !=
138 if (0 != setsockopt (h->fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value))) 140 setsockopt (h->fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof (value)))
139 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 141 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
140 "setsockopt"); 142 }
141} 143
142#endif 144
143 145#endif /* */
144 146
145
146/** 147/**
147 * Disable delays when sending data via the socket. 148 * Disable delays when sending data via the socket.
148 * (GNUnet makes sure that messages are as big as 149 * (GNUnet makes sure that messages are as big as
149 * possible already). 150 * possible already).
150 * 151 *
151 * @param h the socket to make non-delaying 152 * @param h the socket to make non-delaying
152 */ 153 */
153static void 154static void
154socket_set_nodelay (const struct GNUNET_NETWORK_Handle 155socket_set_nodelay (const struct GNUNET_NETWORK_Handle *h)
155 *h) 156{
156{ 157 int value = 1;
157 int value = 1; 158 if (0 !=
158 if (0 != setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value))) 159 setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof (value)))
159 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 160 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
160 "setsockopt"); 161 }
161 162
162} 163
163
164
165
166/** 164/**
167 * accept a new connection on a socket 165 * accept a new connection on a socket
168 * 166 *
@@ -170,124 +168,142 @@ socket_set_nodelay (const struct GNUNET_NETWORK_Handle
170 * @param address address of the connecting peer, may be NULL 168 * @param address address of the connecting peer, may be NULL
171 * @param address_len length of address 169 * @param address_len length of address
172 * @return client socket 170 * @return client socket
173 */ 171 */
174struct GNUNET_NETWORK_Handle * 172struct GNUNET_NETWORK_Handle *
175GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc, 173GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc,
176 struct sockaddr *address, 174 struct sockaddr *address,
177 socklen_t * address_len) 175 socklen_t * address_len)
178{ 176{
179 struct GNUNET_NETWORK_Handle *ret; 177 struct GNUNET_NETWORK_Handle *ret;
180 178 ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
181 ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); 179 ret->fd = accept (desc->fd, address, address_len);
182 ret->fd = accept (desc->fd, address, address_len); 180 if (ret->fd == INVALID_SOCKET)
183 if (ret->fd == INVALID_SOCKET) 181
184 { 182 {
183
185#ifdef MINGW 184#ifdef MINGW
186 SetErrnoFromWinsockError (WSAGetLastError ()); 185 SetErrnoFromWinsockError (WSAGetLastError ());
187#endif 186
188 GNUNET_free (ret); 187#endif /* */
189 return NULL; 188 GNUNET_free (ret);
190 } 189 return NULL;
190 }
191
191#ifndef MINGW 192#ifndef MINGW
192 if (ret->fd >= FD_SETSIZE) 193 if (ret->fd >= FD_SETSIZE)
193 { 194
194 GNUNET_break (0 == close (ret->fd)); 195 {
195 GNUNET_free (ret); 196 GNUNET_break (0 == close (ret->fd));
196 errno = EMFILE; 197 GNUNET_free (ret);
197 return NULL; 198 errno = EMFILE;
198 } 199 return NULL;
199#endif 200 }
200 if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO)) 201
201 { 202#endif /* */
202 /* we might want to treat this one as fatal... */ 203 if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO))
203 GNUNET_break (0); 204
204 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret)); 205 {
205 return NULL; 206
206 } 207 /* we might want to treat this one as fatal... */
208 GNUNET_break (0);
209 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret));
210 return NULL;
211 }
212
207#ifndef MINGW 213#ifndef MINGW
208 if (GNUNET_OK != socket_set_inheritable (ret)) 214 if (GNUNET_OK != socket_set_inheritable (ret))
209 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 215 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
210 "socket_set_inheritable"); 216 "socket_set_inheritable");
211#endif 217
218#endif /* */
212#ifdef DARWIN 219#ifdef DARWIN
213 socket_set_nosigpipe (ret); 220 socket_set_nosigpipe (ret);
214#endif 221
215 socket_set_nodelay (ret); 222#endif /* */
216 return ret; 223 socket_set_nodelay (ret);
217} 224 return ret;
218 225 }
226
227
219/** 228/**
220 * Bind to a connected socket 229 * Bind to a connected socket
221 * @param desc socket 230 * @param desc socket
222 * @param address address to be bound 231 * @param address address to be bound
223 * @param address_len length of address 232 * @param address_len length of address
224 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 233 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
225 */ 234 */
226int 235int
227GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc, 236GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
228 const struct sockaddr *address, 237 const struct sockaddr *address,
229 socklen_t address_len) 238 socklen_t address_len)
230{ 239{
231 int ret; 240 int ret;
232 241 ret = bind (desc->fd, address, address_len);
233 ret = bind (desc->fd, address, address_len); 242
234#ifdef MINGW 243#ifdef MINGW
235 if (SOCKET_ERROR == ret) 244 if (SOCKET_ERROR == ret)
236 SetErrnoFromWinsockError (WSAGetLastError ()); 245 SetErrnoFromWinsockError (WSAGetLastError ());
237#endif 246
238 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; 247#endif /* */
239} 248 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
240 249 }
241 250
251
242/** 252/**
243 * Close a socket 253 * Close a socket
244 * @param desc socket 254 * @param desc socket
245 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 255 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
246 */ 256 */
247int 257int
248GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc) 258GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)
249{ 259{
250 int ret; 260 int ret;
251 int eno; 261 int eno;
252 262
253#ifdef MINGW 263#ifdef MINGW
254 ret = closesocket (desc->fd); 264 ret = closesocket (desc->fd);
255 SetErrnoFromWinsockError (WSAGetLastError ()); 265 SetErrnoFromWinsockError (WSAGetLastError ());
256#else 266
257 ret = close (desc->fd); 267#else /* */
258#endif 268 ret = close (desc->fd);
259 eno = errno; 269
260 GNUNET_free (desc); 270#endif /* */
261 errno = eno; 271 eno = errno;
262 return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR; 272 GNUNET_free (desc);
263} 273 errno = eno;
264 274 return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR;
275 }
276
277
265/** 278/**
266 * Connect a socket 279 * Connect a socket
267 * @param desc socket 280 * @param desc socket
268 * @param address peer address 281 * @param address peer address
269 * @param address_len length of address 282 * @param address_len length of address
270 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 283 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
271 */ 284 */
272int 285int
273GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Handle *desc, 286GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Handle *desc,
274 const struct sockaddr *address, 287 const struct sockaddr *address,
275 socklen_t address_len) 288 socklen_t address_len)
276{ 289{
277 int ret; 290 int ret;
278 291 ret = connect (desc->fd, address, address_len);
279 ret = connect (desc->fd, address, address_len); 292
280#ifdef MINGW 293#ifdef MINGW
281 if (SOCKET_ERROR == ret) 294 if (SOCKET_ERROR == ret)
282 { 295
283 SetErrnoFromWinsockError (WSAGetLastError ()); 296 {
284 if (errno == EWOULDBLOCK) 297 SetErrnoFromWinsockError (WSAGetLastError ());
285 errno = EINPROGRESS; 298 if (errno == EWOULDBLOCK)
286 } 299 errno = EINPROGRESS;
287#endif 300 }
288 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; 301
289} 302#endif /* */
290 303 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
304 }
305
306
291/** 307/**
292 * Get socket options 308 * Get socket options
293 * 309 *
@@ -297,71 +313,78 @@ GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Handle *desc,
297 * @param optval options 313 * @param optval options
298 * @param optlen length of optval 314 * @param optlen length of optval
299 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 315 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
300 */ 316 */
301int 317int
302GNUNET_NETWORK_socket_getsockopt (const struct GNUNET_NETWORK_Handle *desc, 318GNUNET_NETWORK_socket_getsockopt (const struct GNUNET_NETWORK_Handle *desc,
303 int level, int optname, void *optval, 319 int level, int optname, void *optval,
304 socklen_t * optlen) 320 socklen_t * optlen)
305{ 321{
306 int ret; 322 int ret;
307 323 ret = getsockopt (desc->fd, level, optname, optval, optlen);
308 ret = getsockopt (desc->fd, level, optname, optval, optlen); 324
309#ifdef MINGW 325#ifdef MINGW
310 if (ret == 0 && level == SOL_SOCKET && optname == SO_ERROR) 326 if (ret == 0 && level == SOL_SOCKET && optname == SO_ERROR)
311 *((int *) optval) = GetErrnoFromWinsockError (*((int *) optval)); 327 *((int *) optval) = GetErrnoFromWinsockError (*((int *) optval));
312 else if (SOCKET_ERROR == ret) 328
313 SetErrnoFromWinsockError (WSAGetLastError ()); 329 else if (SOCKET_ERROR == ret)
314#endif 330 SetErrnoFromWinsockError (WSAGetLastError ());
315 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; 331
316} 332#endif /* */
317 333 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
334 }
335
336
318/** 337/**
319 * Listen on a socket 338 * Listen on a socket
320 * @param desc socket 339 * @param desc socket
321 * @param backlog length of the listen queue 340 * @param backlog length of the listen queue
322 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 341 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
323 */ 342 */
324int 343int
325GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Handle *desc, 344GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Handle *desc,
326 int backlog) 345 int backlog)
327{ 346{
328 int ret; 347 int ret;
329 348 ret = listen (desc->fd, backlog);
330 ret = listen (desc->fd, backlog); 349
331#ifdef MINGW 350#ifdef MINGW
332 if (SOCKET_ERROR == ret) 351 if (SOCKET_ERROR == ret)
333 SetErrnoFromWinsockError (WSAGetLastError ()); 352 SetErrnoFromWinsockError (WSAGetLastError ());
334#endif 353
335 354#endif /* */
336 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; 355 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
337} 356 }
338 357
358
339/** 359/**
340 * Read data from a connected socket (always non-blocking). 360 * Read data from a connected socket (always non-blocking).
341 * @param desc socket 361 * @param desc socket
342 * @param buffer buffer 362 * @param buffer buffer
343 * @param length length of buffer 363 * @param length length of buffer
344 */ 364 */
345ssize_t 365 ssize_t
346GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc, 366GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc,
347 void *buffer, size_t length) 367 void *buffer, size_t length)
348{ 368{
349 int ret; 369 int ret;
350 int flags; 370 int flags;
351 371 flags = 0;
352 flags = 0; 372
353#ifdef MSG_DONTWAIT 373#ifdef MSG_DONTWAIT
354 flags |= MSG_DONTWAIT; 374 flags |= MSG_DONTWAIT;
355#endif 375
356 ret = recv (desc->fd, buffer, length, flags); 376#endif /* */
377 ret = recv (desc->fd, buffer, length, flags);
378
357#ifdef MINGW 379#ifdef MINGW
358 if (SOCKET_ERROR == ret) 380 if (SOCKET_ERROR == ret)
359 SetErrnoFromWinsockError (WSAGetLastError ()); 381 SetErrnoFromWinsockError (WSAGetLastError ());
360#endif 382
361 383#endif /* */
362 return ret; 384 return ret;
363} 385 }
364 386
387
365/** 388/**
366 * Send data (always non-blocking). 389 * Send data (always non-blocking).
367 * 390 *
@@ -369,31 +392,34 @@ GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc,
369 * @param buffer data to send 392 * @param buffer data to send
370 * @param length size of the buffer 393 * @param length size of the buffer
371 * @return number of bytes sent, GNUNET_SYSERR on error 394 * @return number of bytes sent, GNUNET_SYSERR on error
372 */ 395 */
373ssize_t 396 ssize_t
374GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle * desc, 397GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle * desc,
375 const void *buffer, size_t length) 398 const void *buffer, size_t length)
376{ 399{
377 int ret; 400 int ret;
378 int flags; 401 int flags;
379 402 flags = 0;
380 flags = 0; 403
381#ifdef MSG_DONTWAIT 404#ifdef MSG_DONTWAIT
382 flags |= MSG_DONTWAIT; 405 flags |= MSG_DONTWAIT;
383#endif 406
407#endif /* */
384#ifdef MSG_NOSIGNAL 408#ifdef MSG_NOSIGNAL
385 flags |= MSG_NOSIGNAL; 409 flags |= MSG_NOSIGNAL;
386#endif 410
387 ret = send (desc->fd, buffer, length, flags); 411#endif /* */
412 ret = send (desc->fd, buffer, length, flags);
413
388#ifdef MINGW 414#ifdef MINGW
389 if (SOCKET_ERROR == ret) 415 if (SOCKET_ERROR == ret)
390 SetErrnoFromWinsockError (WSAGetLastError ()); 416 SetErrnoFromWinsockError (WSAGetLastError ());
391#endif 417
392 418#endif /* */
393 return ret; 419 return ret;
394} 420 }
395 421
396 422
397/** 423/**
398 * Send data to a particular destination (always non-blocking). 424 * Send data to a particular destination (always non-blocking).
399 * This function only works for UDP sockets. 425 * This function only works for UDP sockets.
@@ -404,32 +430,36 @@ GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle * desc,
404 * @param dest_addr destination address 430 * @param dest_addr destination address
405 * @param dest_len length of address 431 * @param dest_len length of address
406 * @return number of bytes sent, GNUNET_SYSERR on error 432 * @return number of bytes sent, GNUNET_SYSERR on error
407 */ 433 */
408ssize_t 434 ssize_t
409GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle * desc, 435GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle * desc,
410 const void *message, size_t length, 436 const void *message, size_t length,
411 const struct sockaddr * dest_addr, 437 const struct sockaddr * dest_addr,
412 socklen_t dest_len) 438 socklen_t dest_len)
413{ 439{
414 int ret; 440 int ret;
415 int flags; 441 int flags;
416 442 flags = 0;
417 flags = 0; 443
418#ifdef MSG_DONTWAIT 444#ifdef MSG_DONTWAIT
419 flags |= MSG_DONTWAIT; 445 flags |= MSG_DONTWAIT;
420#endif 446
447#endif /* */
421#ifdef MSG_NOSIGNAL 448#ifdef MSG_NOSIGNAL
422 flags |= MSG_NOSIGNAL; 449 flags |= MSG_NOSIGNAL;
423#endif 450
424 ret = sendto (desc->fd, message, length, flags, dest_addr, dest_len); 451#endif /* */
452 ret = sendto (desc->fd, message, length, flags, dest_addr, dest_len);
453
425#ifdef MINGW 454#ifdef MINGW
426 if (SOCKET_ERROR == ret) 455 if (SOCKET_ERROR == ret)
427 SetErrnoFromWinsockError (WSAGetLastError ()); 456 SetErrnoFromWinsockError (WSAGetLastError ());
428#endif 457
429 458#endif /* */
430 return ret; 459 return ret;
431} 460 }
432 461
462
433/** 463/**
434 * Set socket option 464 * Set socket option
435 * @param fd socket 465 * @param fd socket
@@ -438,26 +468,25 @@ GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle * desc,
438 * @param option_value value to set 468 * @param option_value value to set
439 * @param option_len size of option_value 469 * @param option_len size of option_value
440 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 470 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
441 */ 471 */
442int 472int
443GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, 473GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd,
444 int level, int option_name, 474 int level, int option_name,
445 const void *option_value, 475 const void *option_value,
446 socklen_t option_len) 476 socklen_t option_len)
447{ 477{
448 int ret; 478 int ret;
449 479 ret = setsockopt (fd->fd, level, option_name, option_value, option_len);
450 ret = setsockopt (fd->fd, level, option_name, option_value, option_len); 480
451#ifdef MINGW 481#ifdef MINGW
452 if (SOCKET_ERROR == ret) 482 if (SOCKET_ERROR == ret)
453 SetErrnoFromWinsockError (WSAGetLastError ()); 483 SetErrnoFromWinsockError (WSAGetLastError ());
454#endif 484
455 485#endif /* */
456 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; 486 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
457} 487 }
458 488
459 489
460
461/** 490/**
462 * Create a new socket. Configure it for non-blocking IO and 491 * Create a new socket. Configure it for non-blocking IO and
463 * mark it as non-inheritable to child processes (set the 492 * mark it as non-inheritable to child processes (set the
@@ -467,282 +496,297 @@ GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd,
467 * @param type socket type 496 * @param type socket type
468 * @param protocol network protocol 497 * @param protocol network protocol
469 * @return new socket, NULL on error 498 * @return new socket, NULL on error
470 */ 499 */
471struct GNUNET_NETWORK_Handle * 500struct GNUNET_NETWORK_Handle *
472GNUNET_NETWORK_socket_create (int domain, int type, int protocol) 501GNUNET_NETWORK_socket_create (int domain, int type, int protocol)
473{ 502{
474 struct GNUNET_NETWORK_Handle *ret; 503 struct GNUNET_NETWORK_Handle *ret;
475 504 ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
476 ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); 505 ret->fd = socket (domain, type, protocol);
477 ret->fd = socket (domain, type, protocol); 506 if (INVALID_SOCKET == ret->fd)
478 if (INVALID_SOCKET == ret->fd) 507
479 { 508 {
509
480#ifdef MINGW 510#ifdef MINGW
481 SetErrnoFromWinsockError (WSAGetLastError ()); 511 SetErrnoFromWinsockError (WSAGetLastError ());
482#endif 512
483 GNUNET_free (ret); 513#endif /* */
484 return NULL; 514 GNUNET_free (ret);
485 } 515 return NULL;
516 }
517
486#ifndef MINGW 518#ifndef MINGW
487 if (ret->fd >= FD_SETSIZE) 519 if (ret->fd >= FD_SETSIZE)
488 { 520
489 GNUNET_break (0 == close (ret->fd)); 521 {
490 GNUNET_free (ret); 522 GNUNET_break (0 == close (ret->fd));
491 errno = EMFILE; 523 GNUNET_free (ret);
492 return NULL; 524 errno = EMFILE;
493 } 525 return NULL;
494#endif 526 }
495 527
496 if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO)) 528#endif /* */
497 { 529 if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO))
498 /* we might want to treat this one as fatal... */ 530
499 GNUNET_break (0); 531 {
500 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret)); 532
501 return NULL; 533 /* we might want to treat this one as fatal... */
502 } 534 GNUNET_break (0);
535 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret));
536 return NULL;
537 }
538
503#ifndef MINGW 539#ifndef MINGW
504 if (GNUNET_OK != socket_set_inheritable (ret)) 540 if (GNUNET_OK != socket_set_inheritable (ret))
505 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 541 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
506 "socket_set_inheritable"); 542 "socket_set_inheritable");
507#endif 543
544#endif /* */
508#ifdef DARWIN 545#ifdef DARWIN
509 socket_set_nosigpipe (ret); 546 socket_set_nosigpipe (ret);
510#endif 547
511 if (type == SOCK_STREAM) 548#endif /* */
512 socket_set_nodelay (ret); 549 if (type == SOCK_STREAM)
513 550 socket_set_nodelay (ret);
514 return ret; 551 return ret;
515} 552 }
516 553
554
517/** 555/**
518 * Shut down socket operations 556 * Shut down socket operations
519 * @param desc socket 557 * @param desc socket
520 * @param how type of shutdown 558 * @param how type of shutdown
521 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 559 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
522 */ 560 */
523int 561int
524GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, 562GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc,
525 int how) 563 int how)
526{ 564{
527 int ret; 565 int ret;
528 566 ret = shutdown (desc->fd, how);
529 ret = shutdown (desc->fd, how); 567
530#ifdef MINGW 568#ifdef MINGW
531 if (ret != 0) 569 if (ret != 0)
532 SetErrnoFromWinsockError (WSAGetLastError ()); 570 SetErrnoFromWinsockError (WSAGetLastError ());
533#endif 571
534 572#endif /* */
535 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; 573 return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
536} 574 }
537 575
538 576
539/** 577/**
540 * Reset FD set 578 * Reset FD set
541 * @param fds fd set 579 * @param fds fd set
542 */ 580 */
543void 581void
544GNUNET_NETWORK_fdset_zero (struct GNUNET_NETWORK_FDSet *fds) 582GNUNET_NETWORK_fdset_zero (struct GNUNET_NETWORK_FDSet *fds)
545{ 583{
546 FD_ZERO (&fds->sds); 584 FD_ZERO (&fds->sds);
547 fds->nsds = 0; 585 fds->nsds = 0;
586
548#ifdef MINGW 587#ifdef MINGW
549 GNUNET_CONTAINER_slist_clear (fds->handles); 588 GNUNET_CONTAINER_slist_clear (fds->handles);
550#endif 589
551} 590#endif /* */
552 591}
553 592
554/** 593/**
555 * Add a socket to the FD set 594 * Add a socket to the FD set
556 * @param fds fd set 595 * @param fds fd set
557 * @param desc socket to add 596 * @param desc socket to add
558 */ 597 */
559void 598void
560GNUNET_NETWORK_fdset_set (struct GNUNET_NETWORK_FDSet *fds, 599GNUNET_NETWORK_fdset_set (struct GNUNET_NETWORK_FDSet *fds,
561 const struct GNUNET_NETWORK_Handle *desc) 600 const struct GNUNET_NETWORK_Handle *desc)
562{ 601{
563 FD_SET (desc->fd, &fds->sds); 602 FD_SET (desc->fd, &fds->sds);
564 603 if (desc->fd + 1 > fds->nsds)
565 if (desc->fd + 1 > fds->nsds) 604 fds->nsds = desc->fd + 1;
566 fds->nsds = desc->fd + 1; 605 }
567} 606
568 607
569
570/** 608/**
571 * Check whether a socket is part of the fd set 609 * Check whether a socket is part of the fd set
572 * @param fds fd set 610 * @param fds fd set
573 * @param desc socket 611 * @param desc socket
574 * @return 0 if the FD is not set 612 * @return 0 if the FD is not set
575 */ 613 */
576int 614int
577GNUNET_NETWORK_fdset_isset (const struct GNUNET_NETWORK_FDSet *fds, 615GNUNET_NETWORK_fdset_isset (const struct GNUNET_NETWORK_FDSet *fds,
578 const struct GNUNET_NETWORK_Handle *desc) 616 const struct GNUNET_NETWORK_Handle *desc)
579{ 617{
580 return FD_ISSET (desc->fd, &fds->sds); 618 return FD_ISSET (desc->fd, &fds->sds);
581} 619 }
582 620
583 621
584/** 622/**
585 * Add one fd set to another 623 * Add one fd set to another
586 * @param dst the fd set to add to 624 * @param dst the fd set to add to
587 * @param src the fd set to add from 625 * @param src the fd set to add from
588 */ 626 */
589void 627void
590GNUNET_NETWORK_fdset_add (struct GNUNET_NETWORK_FDSet *dst, 628GNUNET_NETWORK_fdset_add (struct GNUNET_NETWORK_FDSet *dst,
591 const struct GNUNET_NETWORK_FDSet *src) 629 const struct GNUNET_NETWORK_FDSet *src)
592{ 630{
593 int nfds; 631 int nfds;
594 632 for (nfds = src->nsds; nfds > 0; nfds--)
595 for (nfds = src->nsds; nfds > 0; nfds--) 633 if (FD_ISSET (nfds, &src->sds))
596 if (FD_ISSET (nfds, &src->sds)) 634
597 { 635 {
598 FD_SET (nfds, &dst->sds); 636 FD_SET (nfds, &dst->sds);
599 if (nfds + 1 > dst->nsds) 637 if (nfds + 1 > dst->nsds)
600 dst->nsds = nfds + 1; 638 dst->nsds = nfds + 1;
601 } 639 }
602} 640 }
603 641
604 642
605/** 643/**
606 * Copy one fd set to another 644 * Copy one fd set to another
607 * @param to destination 645 * @param to destination
608 * @param from source 646 * @param from source
609 */ 647 */
610void 648void
611GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to, 649GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to,
612 const struct GNUNET_NETWORK_FDSet *from) 650 const struct GNUNET_NETWORK_FDSet *from)
613{ 651{
614 FD_COPY (&from->sds, &to->sds); 652 FD_COPY (&from->sds, &to->sds);
615 to->nsds = from->nsds; 653 to->nsds = from->nsds;
654
616#ifdef MINGW 655#ifdef MINGW
617 struct GNUNET_CONTAINER_SList_Iterator *iter; 656 struct GNUNET_CONTAINER_SList_Iterator *iter;
618 657 GNUNET_CONTAINER_slist_clear (to->handles);
619 658 for (iter = GNUNET_CONTAINER_slist_begin (from->handles);
620 GNUNET_CONTAINER_slist_clear (to->handles); 659 GNUNET_CONTAINER_slist_end (iter) != GNUNET_YES;
621 660 GNUNET_CONTAINER_slist_next (iter))
622 for (iter = GNUNET_CONTAINER_slist_begin (from->handles); 661
623 GNUNET_CONTAINER_slist_end (iter) != GNUNET_YES; GNUNET_CONTAINER_slist_next (iter)) 662 {
624 { 663 void *handle;
625 void *handle; 664 size_t len;
626 size_t len; 665 handle = GNUNET_CONTAINER_slist_get (iter, &len);
627 666 GNUNET_CONTAINER_slist_add (to->handles,
628 handle = GNUNET_CONTAINER_slist_get (iter, &len); 667 GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
629 GNUNET_CONTAINER_slist_add (to->handles, GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, handle, len); 668 handle, len);
630 } 669 }
631#endif 670#endif /* */
632} 671}
633 672
634
635/** 673/**
636 * Copy a native fd set 674 * Copy a native fd set
637 * @param to destination 675 * @param to destination
638 * @param from native source set 676 * @param from native source set
639 * @param nfds the biggest socket number in from + 1 677 * @param nfds the biggest socket number in from + 1
640 */ 678 */
641void 679void
642GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to, 680GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to,
643 const fd_set * from, int nfds) 681 const fd_set * from, int nfds)
644{ 682{
645 FD_COPY (from, &to->sds); 683 FD_COPY (from, &to->sds);
646 to->nsds = nfds; 684 to->nsds = nfds;
647} 685 }
648 686
649
650/** 687/**
651 * Add a file handle to the fd set 688 * Add a file handle to the fd set
652 * @param fds fd set 689 * @param fds fd set
653 * @param h the file handle to add 690 * @param h the file handle to add
654 */ 691 */
655void 692void
656GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds, 693GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,
657 const struct GNUNET_DISK_FileHandle *h) 694 const struct GNUNET_DISK_FileHandle *h)
658{ 695{
696
659#ifdef MINGW 697#ifdef MINGW
660 HANDLE hw; 698 HANDLE hw;
661 699 GNUNET_DISK_internal_file_handle_ (h, &hw, sizeof (HANDLE));
662 GNUNET_DISK_internal_file_handle_ (h, &hw, sizeof (HANDLE)); 700 GNUNET_CONTAINER_slist_add (fds->handles, GNUNET_NO, &hw, sizeof (HANDLE));
663 GNUNET_CONTAINER_slist_add (fds->handles, GNUNET_NO, &hw, sizeof (HANDLE)); 701
664#else 702#else /* */
665 int fd; 703 int fd;
666 704 GNUNET_DISK_internal_file_handle_ (h, &fd, sizeof (int));
667 GNUNET_DISK_internal_file_handle_ (h, &fd, sizeof (int)); 705 FD_SET (fd, &fds->sds);
668 FD_SET (fd, &fds->sds); 706 if (fd + 1 > fds->nsds)
669 if (fd + 1 > fds->nsds) 707 fds->nsds = fd + 1;
670 fds->nsds = fd + 1; 708
671#endif 709#endif /* */
672} 710}
673 711
712
674/** 713/**
675 * Check if a file handle is part of an fd set 714 * Check if a file handle is part of an fd set
676 * @param fds fd set 715 * @param fds fd set
677 * @param h file handle 716 * @param h file handle
678 * @return GNUNET_YES if the file handle is part of the set 717 * @return GNUNET_YES if the file handle is part of the set
679 */ 718 */
680int 719int
681GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds, 720GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds,
682 const struct GNUNET_DISK_FileHandle *h) 721 const struct GNUNET_DISK_FileHandle *h)
683{ 722{
723
684#ifdef MINGW 724#ifdef MINGW
685 return GNUNET_CONTAINER_slist_contains (fds->handles, h->h, sizeof (HANDLE)); 725 return GNUNET_CONTAINER_slist_contains (fds->handles, h->h,
686#else 726 sizeof (HANDLE));
687 return FD_ISSET (h->fd, &fds->sds); 727
688#endif 728#else /* */
689} 729 return FD_ISSET (h->fd, &fds->sds);
690 730
731#endif /* */
732}
733
734
691/** 735/**
692 * Checks if two fd sets overlap 736 * Checks if two fd sets overlap
693 * @param fds1 first fd set 737 * @param fds1 first fd set
694 * @param fds2 second fd set 738 * @param fds2 second fd set
695 * @return GNUNET_YES if they do overlap, GNUNET_NO otherwise 739 * @return GNUNET_YES if they do overlap, GNUNET_NO otherwise
696 */ 740 */
697int 741int
698GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1, 742GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1,
699 const struct GNUNET_NETWORK_FDSet *fds2) 743 const struct GNUNET_NETWORK_FDSet *fds2)
700{ 744{
701 int nfds; 745 int nfds;
702 746 nfds = fds1->nsds;
703 nfds = fds1->nsds; 747 if (nfds < fds2->nsds)
704 if (nfds < fds2->nsds) 748 nfds = fds2->nsds;
705 nfds = fds2->nsds; 749 for (; nfds >= 0; nfds--)
706 750 if (FD_ISSET (nfds, &fds1->sds) && FD_ISSET (nfds, &fds2->sds))
707 for (; nfds >= 0; nfds--) 751 return GNUNET_YES;
708 if (FD_ISSET (nfds, &fds1->sds) && FD_ISSET (nfds, &fds2->sds)) 752 return GNUNET_NO;
709 return GNUNET_YES; 753 }
710 754
711 return GNUNET_NO; 755
712}
713
714/** 756/**
715 * Creates an fd set 757 * Creates an fd set
716 * @return a new fd set 758 * @return a new fd set
717 */ 759 */
718struct GNUNET_NETWORK_FDSet * 760struct GNUNET_NETWORK_FDSet *
719GNUNET_NETWORK_fdset_create () 761GNUNET_NETWORK_fdset_create ()
720{ 762{
721 struct GNUNET_NETWORK_FDSet *fds; 763 struct GNUNET_NETWORK_FDSet *fds;
722 764 fds = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_FDSet));
723 fds = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_FDSet)); 765
724#ifdef MINGW 766#ifdef MINGW
725 fds->handles = GNUNET_CONTAINER_slist_create (); 767 fds->handles = GNUNET_CONTAINER_slist_create ();
726#endif 768
727 GNUNET_NETWORK_fdset_zero (fds); 769#endif /* */
728 return fds; 770 GNUNET_NETWORK_fdset_zero (fds);
729} 771 return fds;
730 772 }
731 773
774
732/** 775/**
733 * Releases the associated memory of an fd set 776 * Releases the associated memory of an fd set
734 * @param fds fd set 777 * @param fds fd set
735 */ 778 */
736void 779void
737GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds) 780GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds)
738{ 781{
782
739#ifdef MINGW 783#ifdef MINGW
740 GNUNET_CONTAINER_slist_destroy (fds->handles); 784 GNUNET_CONTAINER_slist_destroy (fds->handles);
741#endif 785
742 GNUNET_free (fds); 786#endif /* */
743} 787 GNUNET_free (fds);
744 788 }
745 789
746/** 790/**
747 * Check if sockets meet certain conditions 791 * Check if sockets meet certain conditions
748 * @param rfds set of sockets to be checked for readability 792 * @param rfds set of sockets to be checked for readability
@@ -750,249 +794,259 @@ GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds)
750 * @param efds set of sockets to be checked for exceptions 794 * @param efds set of sockets to be checked for exceptions
751 * @param timeout relative value when to return 795 * @param timeout relative value when to return
752 * @return number of selected sockets, GNUNET_SYSERR on error 796 * @return number of selected sockets, GNUNET_SYSERR on error
753 */ 797 */
754int 798int
755GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, 799GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
756 struct GNUNET_NETWORK_FDSet *wfds, 800 struct GNUNET_NETWORK_FDSet *wfds,
757 struct GNUNET_NETWORK_FDSet *efds, 801 struct GNUNET_NETWORK_FDSet *efds,
758 const struct GNUNET_TIME_Relative timeout) 802 const struct GNUNET_TIME_Relative timeout)
759{ 803{
760 int nfds; 804 int nfds;
761 805 nfds = 0;
762 nfds = 0; 806 if (NULL != rfds)
763 if (NULL != rfds) 807 nfds = rfds->nsds;
764 nfds = rfds->nsds; 808 if (NULL != wfds)
765 if (NULL != wfds) 809 nfds = GNUNET_MAX (nfds, wfds->nsds);
766 nfds = GNUNET_MAX (nfds, wfds->nsds); 810 if (NULL != efds)
767 if (NULL != efds) 811 nfds = GNUNET_MAX (nfds, efds->nsds);
768 nfds = GNUNET_MAX (nfds, efds->nsds); 812
769
770#ifndef MINGW 813#ifndef MINGW
771 struct timeval tv; 814 struct timeval tv;
772 815 tv.tv_sec = timeout.value / GNUNET_TIME_UNIT_SECONDS.value;
773 tv.tv_sec = timeout.value / GNUNET_TIME_UNIT_SECONDS.value; 816 tv.tv_usec =
774 tv.tv_usec = 1000 * (timeout.value - (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.value)); 817 1000 * (timeout.value - (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.value));
775 if ( (nfds == 0) && 818 if ((nfds == 0) && (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value))
776 (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value) ) 819
777 { 820 {
778 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 821 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
779 _("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"), 822 _
780 "select"); 823 ("Fatal internal logic error, process hangs in `%s' (abort with CTRL-C)!\n"),
781 GNUNET_break (0); 824 "select");
782 } 825 GNUNET_break (0);
783 return select (nfds + 1, 826 }
784 (rfds != NULL) ? &rfds->sds : NULL, 827 return select (nfds + 1,
785 (wfds != NULL) ? &wfds->sds : NULL, 828 (rfds != NULL) ? &rfds->sds : NULL,
786 (efds != NULL) ? &efds->sds : NULL, 829 (wfds != NULL) ? &wfds->sds : NULL,
787 (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value) 830 (efds != NULL) ? &efds->sds : NULL,
788 ? NULL 831 (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value)
789 : &tv); 832 ? NULL : &tv);
790#else 833
791 DWORD limit; 834#else /* */
792 fd_set sock_read, sock_write, sock_except; 835 DWORD limit;
793 fd_set aread, awrite, aexcept; 836 fd_set sock_read, sock_write, sock_except;
794 int i; 837 fd_set aread, awrite, aexcept;
795 struct timeval tvslice; 838 int i;
796 int retcode; 839 struct timeval tvslice;
797 DWORD ms_total; 840 int retcode;
798 841 DWORD ms_total;
842
799#define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set)) 843#define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set))
800 844
801 /* calculate how long we need to wait in milliseconds */ 845 /* calculate how long we need to wait in milliseconds */
802 if (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value) 846 if (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value)
803 ms_total = INFINITE; 847 ms_total = INFINITE;
804 else 848
805 ms_total = timeout.value / GNUNET_TIME_UNIT_MILLISECONDS.value; 849 else
806 850 ms_total = timeout.value / GNUNET_TIME_UNIT_MILLISECONDS.value;
807 /* select() may be used as a portable way to sleep */ 851
808 if (!(rfds || wfds || efds)) 852 /* select() may be used as a portable way to sleep */
809 { 853 if (!(rfds || wfds || efds))
810 Sleep (ms_total); 854
811 return 0; 855 {
812 } 856 Sleep (ms_total);
813 857 return 0;
814 if (rfds) 858 }
815 sock_read = rfds->sds; 859 if (rfds)
816 else 860 sock_read = rfds->sds;
817 FD_ZERO(&sock_read); 861
818 862 else
819 if (wfds) 863 FD_ZERO (&sock_read);
820 sock_write = wfds->sds; 864 if (wfds)
821 else 865 sock_write = wfds->sds;
822 FD_ZERO(&sock_write); 866
823 867 else
824 if (efds) 868 FD_ZERO (&sock_write);
825 sock_except = efds->sds; 869 if (efds)
826 else 870 sock_except = efds->sds;
827 FD_ZERO(&sock_except); 871
828 872 else
829 /* multiplex between winsock select() and waiting on the handles */ 873 FD_ZERO (&sock_except);
830 874
831 FD_ZERO (&aread); 875 /* multiplex between winsock select() and waiting on the handles */
832 FD_ZERO (&awrite); 876 FD_ZERO (&aread);
833 FD_ZERO (&aexcept); 877 FD_ZERO (&awrite);
834 878 FD_ZERO (&aexcept);
835 limit = GetTickCount () + ms_total; 879 limit = GetTickCount () + ms_total;
836 do 880
837 { 881 do
838 retcode = 0; 882
839 883 {
840 if (nfds > 0) 884 retcode = 0;
841 { 885 if (nfds > 0)
842 /* overwrite the zero'd sets here; the select call 886
843 * will clear those that are not active */ 887 {
844 888
845 FD_COPY (&sock_read, &aread); 889 /* overwrite the zero'd sets here; the select call
846 FD_COPY (&sock_write, &awrite); 890 * will clear those that are not active */
847 FD_COPY (&sock_except, &aexcept); 891 FD_COPY (&sock_read, &aread);
848 892 FD_COPY (&sock_write, &awrite);
849 tvslice.tv_sec = 0; 893 FD_COPY (&sock_except, &aexcept);
850 tvslice.tv_usec = 100000; 894 tvslice.tv_sec = 0;
851 895 tvslice.tv_usec = 100000;
852 if ((retcode = 896 if ((retcode =
853 select (nfds + 1, &aread, &awrite, &aexcept, 897 select (nfds + 1, &aread, &awrite, &aexcept,
854 &tvslice)) == SOCKET_ERROR) 898 &tvslice)) == SOCKET_ERROR)
855 { 899
856 SetErrnoFromWinsockError (WSAGetLastError ()); 900 {
857 if (errno == ENOTSOCK) 901 SetErrnoFromWinsockError (WSAGetLastError ());
858 errno = EBADF; 902 if (errno == ENOTSOCK)
859 903 errno = EBADF;
904
860#if DEBUG_NETWORK 905#if DEBUG_NETWORK
861 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select"); 906 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select");
862#endif 907
863 908#endif /* */
864 goto select_loop_end; 909 goto select_loop_end;
865 } 910 }
866 } 911 }
867 912
868 /* Poll read pipes */ 913 /* Poll read pipes */
869 if (rfds) 914 if (rfds)
870 { 915
871 struct GNUNET_CONTAINER_SList_Iterator *i; 916 {
872 int on_next; 917 struct GNUNET_CONTAINER_SList_Iterator *i;
873 918 int on_next;
874 on_next = GNUNET_NO; 919 on_next = GNUNET_NO;
875 for (i = GNUNET_CONTAINER_slist_begin (rfds->handles); 920 for (i = GNUNET_CONTAINER_slist_begin (rfds->handles);
876 GNUNET_CONTAINER_slist_end (i) != GNUNET_YES; 921 GNUNET_CONTAINER_slist_end (i) != GNUNET_YES;
877 on_next || GNUNET_CONTAINER_slist_next (i)) 922 on_next || GNUNET_CONTAINER_slist_next (i))
878 { 923
879 HANDLE h; 924 {
880 DWORD dwBytes; 925 HANDLE h;
881 926 DWORD dwBytes;
882 h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL); 927 h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL);
883 on_next = GNUNET_NO; 928 on_next = GNUNET_NO;
884 929 if (!PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL))
885 if (!PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL)) 930
886 { 931 {
887 GNUNET_CONTAINER_slist_erase (i); 932 GNUNET_CONTAINER_slist_erase (i);
888 on_next = GNUNET_YES; 933 on_next = GNUNET_YES;
889 934 retcode = -1;
890 retcode = -1; 935 SetErrnoFromWinError (GetLastError ());
891 SetErrnoFromWinError (GetLastError ()); 936
892#if DEBUG_NETWORK 937#if DEBUG_NETWORK
893 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "PeekNamedPipe"); 938 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
894#endif 939 "PeekNamedPipe");
895 goto select_loop_end; 940
896 } 941#endif /* */
897 else if (dwBytes) 942 goto select_loop_end;
898 { 943 }
899 retcode++; 944
900 } 945 else if (dwBytes)
901 else 946
902 { 947 {
903 GNUNET_CONTAINER_slist_erase (i); 948 retcode++;
904 on_next = GNUNET_YES; 949 }
905 } 950
906 } 951 else
907 } 952
908 953 {
909 /* Poll for faulty pipes */ 954 GNUNET_CONTAINER_slist_erase (i);
910 if (efds) 955 on_next = GNUNET_YES;
911 { 956 }
912 struct GNUNET_CONTAINER_SList_Iterator *i; 957 }
913 int on_next; 958 }
914 959
915 on_next = GNUNET_NO; 960 /* Poll for faulty pipes */
916 for (i = GNUNET_CONTAINER_slist_begin (efds->handles); 961 if (efds)
917 GNUNET_CONTAINER_slist_end (i) != GNUNET_YES; 962
918 on_next || GNUNET_CONTAINER_slist_next (i)) 963 {
919 { 964 struct GNUNET_CONTAINER_SList_Iterator *i;
920 HANDLE h; 965 int on_next;
921 DWORD dwBytes; 966 on_next = GNUNET_NO;
922 967 for (i = GNUNET_CONTAINER_slist_begin (efds->handles);
923 h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL); 968 GNUNET_CONTAINER_slist_end (i) != GNUNET_YES;
924 969 on_next || GNUNET_CONTAINER_slist_next (i))
925 if (PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL)) 970
926 { 971 {
927 GNUNET_CONTAINER_slist_erase (i); 972 HANDLE h;
928 on_next = GNUNET_YES; 973 DWORD dwBytes;
929 974 h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL);
930 retcode++; 975 if (PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL))
931 } 976
932 else 977 {
933 on_next = GNUNET_NO; 978 GNUNET_CONTAINER_slist_erase (i);
934 } 979 on_next = GNUNET_YES;
935 } 980 retcode++;
936 981 }
937 /* FIXME */ 982
938 if (wfds) 983 else
939 GNUNET_assert (GNUNET_CONTAINER_slist_count (wfds->handles) == 0); 984 on_next = GNUNET_NO;
940 985 }
941 /* Check for closed sockets */ 986 }
942 for (i = 0; i < nfds; i++) 987
943 { 988 /* FIXME */
944 if (SAFE_FD_ISSET (i, &sock_read)) 989 if (wfds)
945 { 990 GNUNET_assert (GNUNET_CONTAINER_slist_count (wfds->handles) == 0);
946 struct sockaddr addr; 991
947 int len; 992 /* Check for closed sockets */
948 993 for (i = 0; i < nfds; i++)
949 if (getpeername (i, &addr, &len) == SOCKET_ERROR) 994
950 { 995 {
951 int err, len; 996 if (SAFE_FD_ISSET (i, &sock_read))
952 997
953 len = sizeof (err); 998 {
954 if (getsockopt 999 struct sockaddr addr;
955 (i, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == 0 1000 int len;
956 && err == WSAENOTCONN) 1001 if (getpeername (i, &addr, &len) == SOCKET_ERROR)
957 { 1002
958 if (!SAFE_FD_ISSET (i, &aread)) 1003 {
959 { 1004 int err, len;
960 FD_SET (i, &aread); 1005 len = sizeof (err);
961 retcode++; 1006 if (getsockopt
962 } 1007 (i, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == 0
963 } 1008 &&err == WSAENOTCONN)
964 } 1009
965 } 1010 {
966 } 1011 if (!SAFE_FD_ISSET (i, &aread))
967 1012
968 select_loop_end:; 1013 {
969 } 1014 FD_SET (i, &aread);
970 while (retcode == 0 && (ms_total == INFINITE || GetTickCount () < limit)); 1015 retcode++;
971 1016 }
972 if (retcode != -1) 1017 }
973 { 1018 }
974 if (rfds) 1019 }
975 { 1020 }
976 GNUNET_NETWORK_fdset_zero (rfds); 1021 select_loop_end:;
977 GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode); 1022 }
978 } 1023 while (retcode == 0 && (ms_total == INFINITE || GetTickCount () < limit));
979 1024 if (retcode != -1)
980 if (wfds) 1025
981 { 1026 {
982 GNUNET_NETWORK_fdset_zero (wfds); 1027 if (rfds)
983 GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode); 1028
984 } 1029 {
985 1030 GNUNET_NETWORK_fdset_zero (rfds);
986 if (efds) 1031 GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode);
987 { 1032 }
988 GNUNET_NETWORK_fdset_zero (efds); 1033 if (wfds)
989 GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode); 1034
990 } 1035 {
991 } 1036 GNUNET_NETWORK_fdset_zero (wfds);
992 1037 GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode);
993 return retcode; 1038 }
994#endif 1039 if (efds)
995} 1040
996 1041 {
997 1042 GNUNET_NETWORK_fdset_zero (efds);
998/* end of network.c */ 1043 GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode);
1044 }
1045 }
1046 return retcode;
1047
1048#endif /* */
1049}
1050
1051
1052/* end of network.c */