ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hybrid-ircservices-1/sockets.c
Revision: 1209
Committed: Thu Aug 25 19:05:49 2011 UTC (12 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 67033 byte(s)
Log Message:
- run everything thru indent
  "-bli0 -di1 -npcs -nut -cdw -bls -nbbo -bap"

File Contents

# Content
1 /* Socket routines.
2 *
3 * IRC Services is copyright (c) 1996-2009 Andrew Church.
4 * E-mail: <achurch@achurch.org>
5 * Parts written by Andrew Kempe and others.
6 * This program is free but copyrighted software; see the file GPL.txt for
7 * details.
8 */
9
10 /* Define this to trace function calls: */
11 /* #define TRACE_CALLS */
12
13 /* Define this to log warnings on exceeding buffer size: */
14 /* #define WARN_ON_BUFSIZE */
15
16 /* Define this to disable swritemap(). For IRC Services, we disable this
17 * to avoid depending on the presence of munmap(), since we don't use
18 * swritemap() anyway. */
19 #define DISABLE_SWRITEMAP
20
21 #include "services.h"
22 #include <fcntl.h>
23 #include <sys/socket.h>
24 #include <netdb.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27
28 #ifndef DISABLE_SWRITEMAP
29 # include <sys/mman.h> /* for munmap() */
30 #endif
31
32 /*************************************************************************/
33
34 /* For function call tracing: */
35
36 #ifdef TRACE_CALLS
37
38 static int trace_depth = -1;
39
40 #define ENTER(fmt,...) \
41 trace_depth++; \
42 log_debug(1, "sockets: TRACE: %*s%s(" fmt ")", \
43 trace_depth*2, "", __FUNCTION__ , ## __VA_ARGS__)
44 #define ENTER_WITH(retfmt,fmt,...) \
45 const char *__retfmt = (retfmt); \
46 ENTER(fmt , ## __VA_ARGS__)
47 #define RETURN do { \
48 log_debug(1, "sockets: TRACE: %*s%s() -> void", \
49 trace_depth*2, "", __FUNCTION__); \
50 trace_depth--; \
51 return; \
52 } while (0)
53 #define RETURN_WITH(val) do { \
54 typeof(val) __tmp = (val); \
55 if (debug) { \
56 char buf[64]; \
57 snprintf(buf, sizeof(buf), __retfmt, __tmp); \
58 log_debug(1, "sockets: TRACE: %*s%s() -> %s", \
59 trace_depth*2, "", __FUNCTION__, buf); \
60 } \
61 trace_depth--; \
62 return __tmp; \
63 } while (0)
64
65 #else /* !TRACE_CALLS */
66
67 #define ENTER(fmt,...) /* nothing */
68 #define ENTER_WITH(retfmt,fmt,...) /* nothing */
69 #define RETURN return
70 #define RETURN_WITH(val) return(val)
71
72 #endif /* TRACE_CALLS */
73
74 /*************************************************************************/
75
76 /* Socket data structure */
77
78 struct socket_
79 {
80 Socket *next, *prev;
81 int fd; /* Socket's file descriptor */
82 struct sockaddr_in remote; /* Remote address */
83 int flags; /* Status flags (SF_*) */
84
85 SocketCallback cb_connect; /* Connect callback */
86 SocketCallback cb_disconn; /* Disconnect callback */
87 SocketCallback cb_accept; /* Accept callback */
88 SocketCallback cb_read; /* Data-available callback */
89 SocketCallback cb_readline; /* Line-available callback */
90 SocketCallback cb_trigger; /* Write trigger callback */
91
92 int write_timeout; /* Write timeout, in seconds (0 = none) */
93 time_t last_write_time; /* Last time data was successfully sent */
94
95 /* Usage of pointers:
96 * - Xbuf is the buffer base pointer
97 * - Xptr is the address of the next character to store
98 * - Xend is the address of the next character to retrieve
99 * - Xtop is the address of the last byte of the buffer + 1
100 * Xend-Xptr (mod Xbufsize) gives the number of bytes in the buffer.
101 */
102 char *rbuf, *rptr, *rend, *rtop; /* Read buffer and pointers */
103 char *wbuf, *wptr, *wend, *wtop; /* Write buffer and pointers */
104
105 /* List of mapped memory areas to send, earliest first */
106 struct wmapinfo
107 {
108 struct wmapinfo *next;
109 int32 wait; /* # of bytes to write from wbuf first */
110 const char *map; /* Start of mapped area, or trigger data */
111 int32 maplen; /* Length of mapped area (0 = write trigger) */
112 int32 pos; /* Current position */
113 } *writemap, *writemap_tail;
114
115 uint64 total_read; /* Total number of bytes read */
116 uint64 total_written; /* Total number of bytes written */
117 };
118
119 #define SF_SELFCREATED 0x0001 /* We created this socket ourselves */
120 #define SF_BLOCKING 0x0002 /* Writes are blocking */
121 #define SF_LISTENER 0x0004 /* Socket is a listener socket */
122 #define SF_CONNECTING 0x0008 /* Socket is busy connecting */
123 #define SF_CONNECTED 0x0010 /* Socket has connected */
124 #define SF_MUTE 0x0020 /* Socket is muted */
125 #define SF_UNMUTED 0x0040 /* Socket was just unmuted */
126 #define SF_CALLBACK 0x0080 /* Currently calling callbacks */
127 #define SF_WTRIGGER 0x0100 /* A write trigger has been reached */
128 #define SF_WARNED 0x0200 /* Warned about hitting buffer limit */
129 #define SF_DISCONNECT 0x0400 /* Disconnect when writebuf empty */
130 #define SF_DISCONN_REQ 0x0800 /* Disconnect has been requested */
131 #define SF_DISCONNECTING 0x1000 /* Socket is in the middle of disconnecting */
132 #define SF_BROKEN 0x2000 /* Connection was broken while in a callback */
133 #define SF_DELETEME 0x4000 /* Delete socket when convenient */
134
135 /* Used when calling do_disconn() due to SF_DISCONNECT */
136 #define DISCONN_RESUME_FLAG 0x100
137 #define DISCONN_LOCAL_RESUME (void *)((int)DISCONN_LOCAL|DISCONN_RESUME_FLAG)
138 #define DISCONN_REMOTE_RESUME (void *)((int)DISCONN_REMOTE|DISCONN_RESUME_FLAG)
139
140 /* Size of read/write buffers */
141 #define read_buffer_size(s) ((s)->rtop - (s)->rbuf)
142 #define write_buffer_size(s) ((s)->wtop - (s)->wbuf)
143
144 /* Does the socket still have more data that needs to be written? */
145 #define MORE_TO_WRITE(s) (write_buffer_len(s) > 0 || ((s)->writemap))
146
147 /*************************************************************************/
148
149 /* List of all sockets (even unopened ones) */
150 static Socket *allsockets = NULL;
151
152 /* Array of all opened sockets (indexed by FD), dynamically allocated */
153 static Socket **sockets = NULL;
154
155 /* Highest FD number in use plus 1; also length of sockets[] array */
156 static int max_fd;
157
158 /* Set of all connected socket FDs */
159 static fd_set sock_fds;
160
161 /* Set of all FDs that need data written (or are connecting) */
162 static fd_set write_fds;
163
164 /* Total memory used by socket buffers */
165 static uint32 total_bufsize;
166
167 /* Per-connection and total buffer size limits */
168 static uint32 bufsize_limit = 0, total_bufsize_limit = 0;
169
170 /* Global read timeout, in milliseconds */
171 static int read_timeout = -1;
172
173 /*************************************************************************/
174
175 /* Internal routine declarations (definitions at bottom of file) */
176
177 static int do_callback(Socket * s, SocketCallback cb, void *param);
178 static void do_accept(Socket * s);
179 static int fill_read_buffer(Socket * s);
180 static int flush_write_buffer(Socket * s);
181 static uint32 resize_how_much(const Socket * s, uint32 current_size,
182 int *errp);
183 static int resize_rbuf(Socket * s, uint32 size);
184 static int resize_wbuf(Socket * s, uint32 size);
185 static int resize_buf(char **p_buf, char **p_ptr, char **p_end, char **p_top,
186 uint32 newsize);
187 static int reclaim_buffer_space_one(Socket * s);
188 static int reclaim_buffer_space(void);
189 static void next_wmap(Socket * s);
190 static int buffered_write(Socket * s, const char *buf, int len);
191 static int do_disconn(Socket * s, void *code);
192 static void sock_closefd(Socket * s);
193
194 /*************************************************************************/
195 /*************************** Global routines *****************************/
196 /*************************************************************************/
197
198 /* Set the per-connection and total buffer size limits (zero means no
199 * limit). Always successful; both values are silently rounded down to a
200 * multiple of SOCK_MIN_BUFSIZE (if a value is less than SOCK_MIN_BUFSIZE it
201 * is rounded up). Both values default to zero, i.e. unlimited.
202 */
203
204 void
205 sock_set_buflimits(uint32 per_conn, uint32 total)
206 {
207 if (per_conn > 0)
208 {
209 per_conn = per_conn / SOCK_MIN_BUFSIZE * SOCK_MIN_BUFSIZE;
210 if (!per_conn)
211 per_conn = SOCK_MIN_BUFSIZE;
212 }
213 if (total > 0)
214 {
215 total = total / SOCK_MIN_BUFSIZE * SOCK_MIN_BUFSIZE;
216 if (!total)
217 total = SOCK_MIN_BUFSIZE;
218 }
219 bufsize_limit = per_conn;
220 total_bufsize_limit = total;
221 }
222
223 /*************************************************************************/
224
225 /* Set the global read timeout. A value of -1 (default) means no timeout. */
226
227 void
228 sock_set_rto(int msec)
229 {
230 read_timeout = msec;
231 }
232
233 /*************************************************************************/
234
235 /* Create and return a new socket. Returns NULL if unsuccessful (i.e. no
236 * more space for buffers).
237 */
238
239 Socket *
240 sock_new(void)
241 {
242 Socket *s;
243
244 ENTER_WITH("%p", "");
245 if (total_bufsize_limit)
246 {
247 while (total_bufsize + SOCK_MIN_BUFSIZE * 2 > total_bufsize_limit)
248 {
249 if (!reclaim_buffer_space())
250 {
251 log("sockets: sock_new(): out of buffer space! current=%lu,"
252 " limit=%lu", (unsigned long) total_bufsize,
253 (unsigned long) total_bufsize_limit);
254 RETURN_WITH(NULL);
255 }
256 }
257 }
258
259 s = malloc(sizeof(*s));
260 if (!s)
261 {
262 RETURN_WITH(NULL);
263 }
264 s->rbuf = malloc(SOCK_MIN_BUFSIZE);
265 if (!s->rbuf)
266 {
267 int errno_save = errno;
268 free(s);
269 errno = errno_save;
270 RETURN_WITH(NULL);
271 }
272 s->wbuf = malloc(SOCK_MIN_BUFSIZE);
273 if (!s->wbuf)
274 {
275 int errno_save = errno;
276 free(s->rbuf);
277 free(s);
278 errno = errno_save;
279 RETURN_WITH(NULL);
280 }
281
282 s->fd = -1;
283 memset(&s->remote, 0, sizeof(s->remote));
284 s->flags = 0;
285 s->cb_connect = NULL;
286 s->cb_disconn = NULL;
287 s->cb_accept = NULL;
288 s->cb_read = NULL;
289 s->cb_readline = NULL;
290 s->cb_trigger = NULL;
291 s->write_timeout = 0;
292 s->last_write_time = time(NULL);
293 s->rptr = s->rbuf;
294 s->rend = s->rbuf;
295 s->rtop = s->rbuf + SOCK_MIN_BUFSIZE;
296 s->wptr = s->wbuf;
297 s->wend = s->wbuf;
298 s->wtop = s->wbuf + SOCK_MIN_BUFSIZE;
299 s->writemap = NULL;
300 s->writemap_tail = NULL;
301 s->total_read = 0;
302 s->total_written = 0;
303 LIST_INSERT(s, allsockets);
304 total_bufsize += read_buffer_size(s) + write_buffer_size(s);
305 RETURN_WITH(s);
306 }
307
308 /*************************************************************************/
309
310 /* Free a socket, first disconnecting/closing it if necessary. */
311
312 void
313 sock_free(Socket * s)
314 {
315 ENTER("%p", s);
316 if (!s)
317 {
318 log("sockets: sock_free() with NULL socket!");
319 errno = EINVAL;
320 RETURN;
321 }
322 if (s->flags & (SF_CONNECTING | SF_CONNECTED))
323 {
324 s->flags |= SF_DELETEME;
325 do_disconn(s, DISCONN_LOCAL);
326 /* do_disconn() will call us again at the appropriate time */
327 RETURN;
328 }
329 else if (s->flags & SF_LISTENER)
330 {
331 close_listener(s);
332 }
333 LIST_REMOVE(s, allsockets);
334 total_bufsize -= read_buffer_size(s) + write_buffer_size(s);
335 free(s->rbuf);
336 free(s->wbuf);
337 free(s);
338 /* If this was the last socket, free the sockets[] array too */
339 if (!allsockets)
340 {
341 free(sockets);
342 sockets = NULL;
343 }
344 RETURN;
345 }
346
347 /*************************************************************************/
348
349 /* Set a callback on a socket. */
350
351 void
352 sock_setcb(Socket * s, SocketCallbackID which, SocketCallback func)
353 {
354 ENTER("%p,%d,%p", s, which, func);
355 if (!s)
356 {
357 log("sockets: sock_setcb() with NULL socket!");
358 errno = EINVAL;
359 RETURN;
360 }
361 switch (which)
362 {
363 case SCB_CONNECT:
364 s->cb_connect = func;
365 break;
366 case SCB_DISCONNECT:
367 s->cb_disconn = func;
368 break;
369 case SCB_ACCEPT:
370 s->cb_accept = func;
371 break;
372 case SCB_READ:
373 s->cb_read = func;
374 break;
375 case SCB_READLINE:
376 s->cb_readline = func;
377 break;
378 case SCB_TRIGGER:
379 s->cb_trigger = func;
380 break;
381 default:
382 log("sockets: sock_setcb(): invalid callback ID %d", which);
383 break;
384 }
385 RETURN;
386 }
387
388 /*************************************************************************/
389
390 /* Return whether the given socket is currently connected. */
391
392 int
393 sock_isconn(const Socket * s)
394 {
395 ENTER_WITH("%d", "%p", s);
396 if (!s)
397 {
398 log("sockets: sock_isconn() with NULL socket!");
399 errno = EINVAL;
400 RETURN_WITH(0);
401 }
402 RETURN_WITH(s->flags & SF_CONNECTED ? 1 : 0);
403 }
404
405 /*************************************************************************/
406
407 /* Retrieve address of remote end of socket. Functions the same way as
408 * getpeername() (initialize *lenptr to sizeof(sa), address returned in sa,
409 * non-truncated length of address returned in *lenptr). Returns -1 with
410 * errno == EINVAL if a NULL pointer is passed or the given socket is not
411 * connected.
412 */
413
414 int
415 sock_remote(const Socket * s, struct sockaddr *sa, int *lenptr)
416 {
417 ENTER_WITH("%d", "%p,%p,%p", s, sa, lenptr);
418 if (!s || !sa || !lenptr || !(s->flags & SF_CONNECTED))
419 {
420 if (!s || !sa || !lenptr)
421 {
422 log("sockets: sock_remote() with NULL %s!",
423 !s ? "socket" : !sa ? "sockaddr" : "lenptr");
424 }
425 errno = EINVAL;
426 RETURN_WITH(-1);
427 }
428 if (sizeof(s->remote) <= *lenptr)
429 memcpy(sa, &s->remote, sizeof(s->remote));
430 else
431 memcpy(sa, &s->remote, *lenptr);
432 *lenptr = sizeof(s->remote);
433 RETURN_WITH(0);
434 }
435
436 /*************************************************************************/
437
438 /* Set whether socket writes should block (blocking != 0) or not
439 * (blocking == 0).
440 */
441
442 void
443 sock_set_blocking(Socket * s, int blocking)
444 {
445 ENTER("%p,%d", s, blocking);
446 if (!s)
447 {
448 log("sockets: sock_set_blocking() with NULL socket!");
449 errno = EINVAL;
450 RETURN;
451 }
452 if (blocking)
453 s->flags |= SF_BLOCKING;
454 else
455 s->flags &= ~SF_BLOCKING;
456 RETURN;
457 }
458
459 /*************************************************************************/
460
461 /* Return whether socket writes are blocking (return value > 0) or not
462 * (return value == 0). Returns -1 if socket is invalid.
463 */
464
465 int
466 sock_get_blocking(const Socket * s)
467 {
468 ENTER_WITH("%d", "%p", s);
469 if (!s)
470 {
471 log("sockets: sock_get_blocking() with NULL socket!");
472 errno = EINVAL;
473 RETURN_WITH(-1);
474 }
475 RETURN_WITH(s->flags & SF_BLOCKING);
476 }
477
478 /*************************************************************************/
479
480 /* Set (or clear, if seconds==0) the write timeout for a socket. */
481
482 void
483 sock_set_wto(Socket * s, int seconds)
484 {
485 ENTER("%p,%d", s, seconds);
486 if (!s || seconds < 0)
487 {
488 log("sockets: sock_set_wto() with %s!",
489 !s ? "NULL socket" : "negative timeout");
490 errno = EINVAL;
491 RETURN;
492 }
493 s->write_timeout = seconds;
494 RETURN;
495 }
496
497 /*************************************************************************/
498
499 /* Mute a socket. When a socket is muted, no arriving data will be
500 * acknowledged (except to the extent that the operating system
501 * automatically acknowledges and buffers the data), and the read and
502 * accept callbacks will not be called. However, a socket in the
503 * process of conenction will still call the connect or disconnect
504 * callbacks when it completes or fails.
505 */
506
507 void
508 sock_mute(Socket * s)
509 {
510 ENTER("%p", s);
511 if (!s)
512 {
513 log("sockets: sock_mute() with NULL socket!");
514 RETURN;
515 }
516 if (!(s->flags & SF_MUTE))
517 {
518 if (s->fd >= 0)
519 FD_CLR(s->fd, &sock_fds);
520 s->flags |= SF_MUTE;
521 }
522 RETURN;
523 }
524
525 /*************************************************************************/
526
527 /* Unmute a socket. If any data is waiting, it will be acknowledged and
528 * the appropriate callback (read or accept) called during the next call to
529 * check_sockets().
530 */
531
532 void
533 sock_unmute(Socket * s)
534 {
535 ENTER("%p", s);
536 if (!s)
537 {
538 log("sockets: sock_unmute() with NULL socket!");
539 RETURN;
540 }
541 if (s->flags & SF_MUTE)
542 {
543 if (s->fd >= 0)
544 FD_SET(s->fd, &sock_fds);
545 s->flags &= ~SF_MUTE;
546 s->flags |= SF_UNMUTED;
547 }
548 RETURN;
549 }
550
551 /*************************************************************************/
552
553 /* Return amount of data in read buffer. Assumes socket is valid. */
554
555 inline uint32
556 read_buffer_len(const Socket * s)
557 {
558 if (s->rend >= s->rptr)
559 return s->rend - s->rptr;
560 else
561 return (s->rend + read_buffer_size(s)) - s->rptr;
562 }
563
564
565 /*************************************************************************/
566
567 /* Return amount of data in write buffer. Assumes socket is valid. */
568
569 inline uint32
570 write_buffer_len(const Socket * s)
571 {
572 if (s->wend >= s->wptr)
573 return s->wend - s->wptr;
574 else
575 return (s->wend + write_buffer_size(s)) - s->wptr;
576 }
577
578 /*************************************************************************/
579
580 /* Return total number of bytes received and sent on this socket in
581 * *read_ret and *writekb_ret respectively. Sent data count does not
582 * include buffered but unsent data. Returns 0 on success, -1 on error
583 * (invalid socket).
584 */
585
586 int
587 sock_rwstat(const Socket * s, uint64 * read_ret, uint64 * written_ret)
588 {
589 ENTER_WITH("%u", "%p,%p,%p", s, read_ret, written_ret);
590 if (!s)
591 {
592 log("sockets: sock_rwstat() with NULL socket!");
593 errno = EINVAL;
594 RETURN_WITH(-1);
595 }
596 if (read_ret)
597 *read_ret = s->total_read;
598 if (written_ret)
599 *written_ret = s->total_written;
600 RETURN_WITH(0);
601 }
602
603 /*************************************************************************/
604
605 /* Return the larger of (1) the ratio of the given socket's total buffer
606 * size (read and write buffers combined) to bufsize_limit and (2) the
607 * ratio of the amount of memory used by all sockets' buffers to
608 * total_bufsize_limit, as a percentage rounded up to the next integer.
609 * Ratios (1) and (2) are zero if bufsize_limit or total_bufsize_limit,
610 * respectively, are set to zero (unlimited).
611 *
612 * If any of `socksize_ret', `totalsize_ret', `ratio1_ret', and
613 * `ratio2_ret' are non-NULL, they are set respectively to the given
614 * socket's total buffer size, the amount of memory used by all sockets'
615 * buffers, ratio (1) as a percentage, and ratio (2) as a percentage.
616 *
617 * If `s' is NULL, ratio (1) is set to zero, and *socksize_ret is not
618 * modified.
619 */
620
621 int
622 sock_bufstat(const Socket * s, uint32 * socksize_ret,
623 uint32 * totalsize_ret, int *ratio1_ret, int *ratio2_ret)
624 {
625 int ratio1 = 0, ratio2 = 0;
626
627 ENTER_WITH("%d", "%p,%p,%p,%p,%p", s, socksize_ret, totalsize_ret,
628 ratio1_ret, ratio2_ret);
629 if (bufsize_limit && s)
630 {
631 uint32 size = read_buffer_size(s) + write_buffer_size(s);
632 if (bufsize_limit <= 0x7FFFFFFF / 100)
633 ratio1 = (size * 100 + bufsize_limit - 1) / bufsize_limit;
634 else
635 ratio1 = (size + bufsize_limit / 100 - 1) / (bufsize_limit / 100);
636 }
637 if (total_bufsize_limit)
638 {
639 if (bufsize_limit <= 0x7FFFFFFF / 100)
640 ratio2 = (total_bufsize * 100 + total_bufsize_limit - 1)
641 / total_bufsize_limit;
642 else
643 ratio2 = (total_bufsize + total_bufsize_limit / 100 - 1)
644 / (total_bufsize_limit / 100);
645 }
646 if (socksize_ret && s)
647 *socksize_ret = read_buffer_size(s) + write_buffer_size(s);
648 if (totalsize_ret)
649 *totalsize_ret = total_bufsize;
650 if (ratio1_ret)
651 *ratio1_ret = ratio1;
652 if (ratio2_ret)
653 *ratio2_ret = ratio2;
654 if (ratio1 > ratio2)
655 RETURN_WITH(ratio1);
656 else
657 RETURN_WITH(ratio2);
658 }
659
660 /*************************************************************************/
661 /*************************************************************************/
662
663 /* Check all sockets for activity, and call callbacks as necessary.
664 * Returns after activity has been detected on at least one socket.
665 */
666
667 void
668 check_sockets(void)
669 {
670 fd_set rfds, wfds;
671 int i;
672 int32 res;
673 struct timeval tv;
674 time_t now = time(NULL);
675 Socket *s;
676
677 ENTER("");
678 rfds = sock_fds;
679 wfds = write_fds;
680 if (read_timeout < 0)
681 {
682 tv.tv_sec = -1; // flag: use a NULL tv parameter to select()
683 tv.tv_usec = 0;
684 }
685 else
686 {
687 tv.tv_sec = read_timeout / 1000;
688 tv.tv_usec = (read_timeout % 1000) * 1000;
689 }
690 for (i = 0; i < max_fd; i++)
691 {
692 s = sockets[i];
693 if (s && s->write_timeout && MORE_TO_WRITE(s))
694 {
695 int tleft = s->write_timeout - (now - s->last_write_time);
696 if (tleft < 0)
697 tleft = 0;
698 if (tv.tv_sec < 0 || tleft <= tv.tv_sec)
699 {
700 tv.tv_sec = tleft;
701 tv.tv_usec = 0;
702 }
703 }
704 }
705 enable_signals();
706 do
707 {
708 struct timeval thistv = tv;
709 res = select(max_fd, &rfds, &wfds, NULL, tv.tv_sec < 0 ? NULL : &thistv);
710 }
711 while (res < 0 && errno == EINTR);
712 disable_signals();
713 log_debug(3, "sockets: select returned %d", res);
714 if (res < 0)
715 {
716 log_perror("sockets: select()");
717 RETURN;
718 }
719
720 for (i = 0; i < max_fd; i++)
721 {
722 s = sockets[i];
723 if (!s)
724 continue;
725 if (s->fd != i)
726 {
727 log("sockets: BUG: sockets[%d]->fd = %d (should be equal),"
728 " clearing socket from table", i, s->fd);
729 sockets[i] = NULL;
730 continue;
731 }
732
733 if (FD_ISSET(i, &wfds))
734 {
735 log_debug(3, "sockets: write ready on fd %d", i);
736 if (!s)
737 {
738 log("sockets: BUG: got write-ready on fd %d but no socket"
739 " for it!", i);
740 continue;
741 }
742 else if (s->flags & SF_CONNECTING)
743 {
744 /* Connection established (or failed) */
745 int val;
746 socklen_t vallen;
747 vallen = sizeof(val);
748 log_debug(2, "sockets: connect on fd %d returned", i);
749 if (getsockopt(i, SOL_SOCKET, SO_ERROR, &val, &vallen) < 0)
750 {
751 log_perror("sockets: getsockopt(SO_ERROR) for connect (%d"
752 " -> %s:%u)", i, inet_ntoa(s->remote.sin_addr),
753 htons(s->remote.sin_port));
754 do_disconn(s, DISCONN_CONNFAIL);
755 continue;
756 }
757 if (val != 0)
758 {
759 errno = val;
760 log_perror("sockets: connect(%d -> %s:%u)", i,
761 inet_ntoa(s->remote.sin_addr),
762 htons(s->remote.sin_port));
763 do_disconn(s, DISCONN_CONNFAIL);
764 continue;
765 }
766 else
767 {
768 if (!do_callback(s, s->cb_connect, 0))
769 continue;
770 }
771 s->flags &= ~SF_CONNECTING;
772 s->flags |= SF_CONNECTED;
773 FD_CLR(i, &write_fds);
774 if (flush_write_buffer(s) < 0) /* we may have pending data */
775 continue; /* socket is not valid any more */
776 if (!(s->flags & SF_MUTE))
777 FD_SET(i, &sock_fds);
778 }
779 else if (!(s->flags & SF_CONNECTED))
780 {
781 log("sockets: BUG: got write-ready on fd %d but socket not"
782 " connected!", i);
783 }
784 else
785 {
786 if (flush_write_buffer(s) < 0)
787 continue; /* socket is not valid any more */
788 }
789 } /* set in write fds */
790
791 while (s->flags & SF_WTRIGGER)
792 {
793 /* Write trigger reached */
794 void *userdata = (void *) s->writemap->map;
795 next_wmap(s);
796 s->flags &= ~SF_WTRIGGER;
797 do_callback(s, s->cb_trigger, userdata);
798 }
799
800 if (FD_ISSET(i, &rfds) || (s && (s->flags & SF_UNMUTED)))
801 {
802 log_debug(3, "sockets: %s on fd %d",
803 FD_ISSET(i, &rfds) ? "read ready" : "unmute", i);
804 if (!s)
805 {
806 log("sockets: BUG: got data on fd %d but no socket for it!", i);
807 FD_CLR(i, &sock_fds);
808 continue;
809 }
810 if (s->flags & SF_MUTE)
811 {
812 /* Socket was muted by a previous socket's callback */
813 log_debug(3, "sockets: socket %d has been muted", i);
814 continue;
815 }
816 s->flags &= ~SF_UNMUTED;
817 if (FD_ISSET(i, &rfds))
818 {
819 if (s->flags & SF_LISTENER)
820 {
821 /* Connection arrived */
822 do_accept(s);
823 continue;
824 }
825 else if (!(s->flags & SF_CONNECTED))
826 {
827 log("sockets: BUG: got data on fd %d but not connected!", i);
828 FD_CLR(i, &sock_fds);
829 continue;
830 }
831 /* Normal read */
832 if (read_buffer_len(s) >= read_buffer_size(s) - 1)
833 {
834 /* Buffer is full, try to expand it */
835 int newsize = 0;
836 if (read_buffer_size(s) < SOCK_MIN_BUFSIZE)
837 newsize = SOCK_MIN_BUFSIZE;
838 else if (read_buffer_size(s) + SOCK_MIN_BUFSIZE < bufsize_limit)
839 newsize = read_buffer_size(s) + SOCK_MIN_BUFSIZE;
840 if (newsize > 0)
841 resize_rbuf(s, newsize);
842 }
843 res = fill_read_buffer(s);
844 if (res < 0)
845 {
846 /* Connection was closed (or some other error occurred) */
847 if (res < 0)
848 log_perror_debug(1, "sockets: recv(%d)", i);
849 do_disconn(s, DISCONN_REMOTE);
850 continue;
851 }
852 else if (res == 0)
853 {
854 /* Read buffer is full (NOTE: this causes busy waiting
855 * until space is made available) */
856 }
857 }
858 else
859 {
860 res = read_buffer_len(s);
861 }
862 if (res > 0)
863 {
864 uint32 left = read_buffer_len(s), newleft;
865 if (left == 0)
866 {
867 log("sockets: BUG: 0 bytes avail after successful read!");
868 continue;
869 }
870 /* Call read callback(s) in a loop until no more data is
871 * left or neither callback takes any data, or the socket is
872 * disconnected */
873 newleft = left;
874 do
875 {
876 if (!do_callback(s, s->cb_read, (void *) (long) newleft))
877 goto disconnected;
878 if (s->flags & SF_MUTE)
879 break;
880 newleft = read_buffer_len(s);
881 if (s->cb_readline)
882 {
883 char *newline;
884 if (s->rend > s->rptr)
885 {
886 newline = memchr(s->rptr, '\n', newleft);
887 }
888 else
889 {
890 newline = memchr(s->rptr, '\n', s->rtop - s->rptr);
891 if (!newline)
892 newline = memchr(s->rbuf, '\n', s->rend - s->rbuf);
893 }
894 if (newline)
895 {
896 if (!do_callback(s, s->cb_readline, (void *) (long) newleft))
897 goto disconnected;
898 if (s->flags & SF_MUTE)
899 break;
900 newleft = read_buffer_len(s);
901 }
902 }
903 }
904 while (newleft != left && (left = newleft) != 0);
905 reclaim_buffer_space_one(s);
906 }
907 } /* socket ready for reading or unmuted */
908
909 if (s->write_timeout
910 && MORE_TO_WRITE(s) && s->last_write_time + s->write_timeout <= now)
911 {
912 if (s->flags & SF_DISCONNECT)
913 do_disconn(s, DISCONN_LOCAL_RESUME);
914 else
915 do_disconn(s, DISCONN_REMOTE);
916 }
917
918 disconnected:
919 /* at least one statement is required after a label */ ;
920
921 } /* for all sockets */
922
923 RETURN;
924 } /* check_sockets() */
925
926 /*************************************************************************/
927 /*************************************************************************/
928
929 /* Initiate a connection to the given host and port. If an error occurs,
930 * returns -1, else returns 0. The connection is not necessarily complete
931 * even if 0 is returned, and may later fail; use the SCB_CONNECT and
932 * SCB_DISCONNECT callbacks. If this function fails due to inability to
933 * resolve a hostname, errno will be set to the negative of h_errno; pass
934 * the negative of this value to hstrerror() to get an appropriate error
935 * message.
936 *
937 * lhost/lport specify the local side of the connection. If they are not
938 * given (lhost==NULL, lport==0), then they are left to be set by the OS.
939 *
940 * If either host or lhost is not a valid IP address and the gethostbyname()
941 * function is available, this function may block while the hostname is
942 * being resolved.
943 *
944 * This function may be called from a socket's disconnect callback to
945 * establish a new connection using the same socket. It may not be called,
946 * however, if the socket is being freed with sock_free().
947 */
948
949 int
950 conn(Socket * s, const char *host, int port, const char *lhost, int lport)
951 {
952 #if HAVE_GETHOSTBYNAME
953 struct hostent *hp;
954 #endif
955 uint8 *addr;
956 struct sockaddr_in sa, lsa;
957 int fd, i;
958
959 ENTER_WITH("%d", "%p,[%s],%d,[%s],%d", s, host ? host : "(null)", port,
960 lhost ? lhost : "(null)", lport);
961 if (!s || !host || port <= 0 || port > 65535)
962 {
963 if (port <= 0 || port > 65535)
964 log("sockets: conn() with bad port number (%d)!", port);
965 else
966 log("sockets: conn() with NULL %s!", !s ? "socket" : "hostname");
967 errno = EINVAL;
968 RETURN_WITH(-1);
969 }
970 if (s->flags & SF_DELETEME)
971 {
972 log("sockets: conn() called on a freeing socket (%p)", s);
973 errno = EPERM;
974 return -1;
975 }
976 memset(&lsa, 0, sizeof(lsa));
977 lsa.sin_family = AF_INET;
978 if (lhost)
979 {
980 if ((addr = pack_ip(lhost)) != 0)
981 memcpy((char *) &lsa.sin_addr, addr, 4);
982 #if HAVE_GETHOSTBYNAME
983 else if ((hp = gethostbyname(lhost)) != NULL)
984 memcpy((char *) &lsa.sin_addr, hp->h_addr, hp->h_length);
985 #endif
986 else
987 lhost = NULL;
988 }
989 if (lport)
990 lsa.sin_port = htons(lport);
991
992 memset(&sa, 0, sizeof(sa));
993 if ((addr = pack_ip(host)) != 0)
994 {
995 memcpy((char *) &sa.sin_addr, addr, 4);
996 sa.sin_family = AF_INET;
997 }
998 #if HAVE_GETHOSTBYNAME
999 else if ((hp = gethostbyname(host)) != NULL)
1000 {
1001 memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
1002 sa.sin_family = hp->h_addrtype;
1003 }
1004 else
1005 {
1006 errno = -h_errno;
1007 RETURN_WITH(-1);
1008 }
1009 #else
1010 else
1011 {
1012 log("sockets: conn(): `%s' is not a valid IP address", host);
1013 errno = EINVAL;
1014 RETURN_WITH(-1);
1015 }
1016 #endif
1017 sa.sin_port = htons((uint16) port);
1018
1019 if ((fd = socket(sa.sin_family, SOCK_STREAM, 0)) < 0)
1020 RETURN_WITH(-1);
1021
1022 if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
1023 {
1024 int errno_save = errno;
1025 close(fd);
1026 errno = errno_save;
1027 RETURN_WITH(-1);
1028 }
1029
1030 if ((lhost || lport) && bind(fd, (struct sockaddr *) &lsa, sizeof(sa)) < 0)
1031 {
1032 int errno_save = errno;
1033 close(fd);
1034 errno = errno_save;
1035 RETURN_WITH(-1);
1036 }
1037
1038 if ((i = connect(fd, (struct sockaddr *) &sa, sizeof(sa))) < 0
1039 && errno != EINPROGRESS)
1040 {
1041 int errno_save = errno;
1042 close(fd);
1043 errno = errno_save;
1044 RETURN_WITH(-1);
1045 }
1046
1047 if (max_fd < fd + 1)
1048 {
1049 int j;
1050 void *new_sockets = realloc(sockets, (fd + 1) * sizeof(*sockets));
1051 if (!new_sockets)
1052 {
1053 int errno_save = errno;
1054 close(fd);
1055 errno = errno_save;
1056 RETURN_WITH(-1);
1057 }
1058 sockets = new_sockets;
1059 for (j = max_fd; j < fd; j++)
1060 sockets[j] = NULL;
1061 max_fd = fd + 1;
1062 }
1063 sockets[fd] = s;
1064 s->remote = sa;
1065 s->fd = fd;
1066 s->flags &= ~(SF_CONNECTING | SF_CONNECTED);
1067 if (i == 0)
1068 {
1069 s->flags |= SF_CONNECTED;
1070 if (!(s->flags & SF_MUTE))
1071 FD_SET(fd, &sock_fds);
1072 do_callback(s, s->cb_connect, 0);
1073 }
1074 else
1075 {
1076 s->flags |= SF_CONNECTING;
1077 FD_SET(fd, &write_fds);
1078 }
1079 RETURN_WITH(0);
1080 }
1081
1082 /*************************************************************************/
1083
1084 /* Disconnect a socket. Returns 0 on success, -1 on error (s == NULL or
1085 * listener socket). Calling this routine on an already-disconnected
1086 * socket returns success without doing anything. Note that the socket may
1087 * not be disconnected immediately; callers who intend to reuse the socket
1088 * MUST wait until the disconnect callback is called before doing so.
1089 */
1090
1091 int
1092 disconn(Socket * s)
1093 {
1094 ENTER_WITH("%d", "%p", s);
1095 if (!s)
1096 {
1097 log("sockets: disconn() with NULL socket!");
1098 errno = EINVAL;
1099 RETURN_WITH(-1);
1100 }
1101 else if (s->flags & SF_LISTENER)
1102 {
1103 log("sockets: disconn() with listener socket!");
1104 errno = EINVAL;
1105 RETURN_WITH(-1);
1106 }
1107 RETURN_WITH(do_disconn(s, DISCONN_LOCAL));
1108 }
1109
1110 /*************************************************************************/
1111
1112 /* Open a listener socket on the given host and port; returns 0 on success
1113 * (the socket is set up and listening), -1 on error. If `host' has
1114 * multiple addresses, only the first one is used; if `host' is NULL, all
1115 * addresses are bound to. As with conn(), a negative errno value
1116 * indicates a failure to resolve the hostname `host'. `backlog' is the
1117 * backlog limit for incoming connections, and is passed directly to the
1118 * listen() system call.
1119 *
1120 * Note that if the SCB_ACCEPT callback is not set, any connections to the
1121 * socket will be dropped immediately.
1122 *
1123 * If host is not a valid IP address and the gethostbyname() function is
1124 * available, this function may block while the hostname is being resolved.
1125 */
1126
1127 int
1128 open_listener(Socket * s, const char *host, int port, int backlog)
1129 {
1130 #if HAVE_GETHOSTBYNAME
1131 struct hostent *hp;
1132 #endif
1133 uint8 *addr;
1134 struct sockaddr_in sa;
1135 int fd, i;
1136
1137 ENTER_WITH("%d", "%p,[%s],%d,%d", s, host ? host : "(null)", port, backlog);
1138 if (!s || port <= 0 || port > 65535 || backlog < 1)
1139 {
1140 if (port <= 0 || port > 65535)
1141 log("sockets: open_listener() with bad port number (%d)!", port);
1142 else if (backlog < 1)
1143 log("sockets: open_listener() with bad backlog (%d)!", backlog);
1144 else
1145 log("sockets: open_listener() with NULL socket!");
1146 errno = EINVAL;
1147 RETURN_WITH(-1);
1148 }
1149 memset(&sa, 0, sizeof(sa));
1150 if (host)
1151 {
1152 if ((addr = pack_ip(host)) != 0)
1153 {
1154 memcpy((char *) &sa.sin_addr, addr, 4);
1155 sa.sin_family = AF_INET;
1156 }
1157 #if HAVE_GETHOSTBYNAME
1158 else if ((hp = gethostbyname(host)) != NULL)
1159 {
1160 memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
1161 sa.sin_family = hp->h_addrtype;
1162 }
1163 else
1164 {
1165 errno = -h_errno;
1166 RETURN_WITH(-1);
1167 }
1168 #else
1169 else
1170 {
1171 log("sockets: open_listener(): `%s' is not a valid IP address", host);
1172 errno = EINVAL;
1173 RETURN_WITH(-1);
1174 }
1175 #endif
1176 }
1177 else
1178 { /* !host */
1179 sa.sin_family = AF_INET;
1180 sa.sin_addr.s_addr = INADDR_ANY;
1181 }
1182 sa.sin_port = htons((uint16) port);
1183
1184 if ((fd = socket(sa.sin_family, SOCK_STREAM, 0)) < 0)
1185 RETURN_WITH(-1);
1186
1187 i = 1;
1188 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
1189 {
1190 log_perror("sockets: open_listener(): setsockopt(%d, SO_REUSEADDR,"
1191 " 1) failed", fd);
1192 }
1193
1194 if (fcntl(fd, F_SETFL, O_NDELAY) < 0)
1195 {
1196 int errno_save = errno;
1197 close(fd);
1198 errno = errno_save;
1199 RETURN_WITH(-1);
1200 }
1201
1202 if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0)
1203 {
1204 int errno_save = errno;
1205 close(fd);
1206 errno = errno_save;
1207 RETURN_WITH(-1);
1208 }
1209
1210 if (listen(fd, backlog) < 0)
1211 {
1212 int errno_save = errno;
1213 close(fd);
1214 errno = errno_save;
1215 RETURN_WITH(-1);
1216 }
1217
1218 if (max_fd < fd + 1)
1219 {
1220 int j;
1221 void *new_sockets = realloc(sockets, (fd + 1) * sizeof(*sockets));
1222 if (!new_sockets)
1223 {
1224 int errno_save = errno;
1225 close(fd);
1226 errno = errno_save;
1227 RETURN_WITH(-1);
1228 }
1229 sockets = new_sockets;
1230 for (j = max_fd; j < fd; j++)
1231 sockets[j] = NULL;
1232 max_fd = fd + 1;
1233 }
1234 sockets[fd] = s;
1235 if (!(s->flags & SF_MUTE))
1236 FD_SET(fd, &sock_fds);
1237 s->fd = fd;
1238 s->flags |= SF_LISTENER;
1239
1240 /* Listener sockets don't need read/write buffers */
1241 free(s->rbuf);
1242 free(s->wbuf);
1243 s->rbuf = s->rptr = s->rend = s->rtop = NULL;
1244 s->wbuf = s->wptr = s->wend = s->wtop = NULL;
1245
1246 RETURN_WITH(0);
1247 }
1248
1249 /*************************************************************************/
1250
1251 /* Close a listener socket. */
1252
1253 int
1254 close_listener(Socket * s)
1255 {
1256 ENTER_WITH("%d", "%p", s);
1257 if (s == NULL || !(s->flags & SF_LISTENER))
1258 {
1259 if (s)
1260 log("sockets: close_listener() with non-listener socket (%d)!", s->fd);
1261 else
1262 log("sockets: close_listener() with NULL socket!");
1263 errno = EINVAL;
1264 RETURN_WITH(-1);
1265 }
1266 sock_closefd(s);
1267 s->flags &= ~SF_LISTENER;
1268 RETURN_WITH(0);
1269 }
1270
1271 /*************************************************************************/
1272
1273 /* Read raw data from a socket, like read(). Returns number of bytes read,
1274 * or -1 on error. Only reads from the buffer (does not attempt to fetch
1275 * more data from the connection).
1276 */
1277
1278 int32
1279 sread(Socket * s, char *buf, int32 len)
1280 {
1281 int32 nread = 0;
1282
1283 ENTER_WITH("%d", "%p,%p,%d", s, buf, len);
1284 if (!s || !buf || len <= 0)
1285 {
1286 log("sockets: sread() with %s!",
1287 !s ? "NULL socket" : !buf ? "NULL buffer" : "len <= 0");
1288 errno = EINVAL;
1289 RETURN_WITH(-1);
1290 }
1291 if (s->rend < s->rptr)
1292 {
1293 /* Buffer data wraps around */
1294 if (s->rptr + len <= s->rtop)
1295 {
1296 /* Only need to read from end of buffer */
1297 memcpy(buf, s->rptr, len);
1298 s->rptr += len;
1299 if (s->rptr >= s->rtop)
1300 s->rptr -= read_buffer_size(s);
1301 RETURN_WITH(len);
1302 }
1303 else
1304 {
1305 /* Need to read from both end and beginning */
1306 nread = s->rtop - s->rptr;
1307 memcpy(buf, s->rptr, nread);
1308 s->rptr = s->rbuf;
1309 len -= nread;
1310 /* Continue below */
1311 }
1312 }
1313 /* Read data from beginning of buffer */
1314 if (s->rptr < s->rend)
1315 {
1316 if (len > s->rend - s->rptr)
1317 len = s->rend - s->rptr;
1318 memcpy(buf + nread, s->rptr, len);
1319 s->rptr += len;
1320 nread += len;
1321 }
1322 /* Return number of bytes read */
1323 RETURN_WITH(nread);
1324 }
1325
1326 /*************************************************************************/
1327
1328 /* Write raw data to a socket, like write(). Returns number of bytes
1329 * written, or -1 on error.
1330 */
1331
1332 int32
1333 swrite(Socket * s, const char *buf, int32 len)
1334 {
1335 ENTER_WITH("%d", "%p,%p,%d", s, buf, len);
1336 if (!s || !buf || len < 0)
1337 {
1338 log("sockets: swrite() with %s!",
1339 !s ? "NULL socket" : !buf ? "NULL buffer" : "len < 0");
1340 errno = EINVAL;
1341 RETURN_WITH(-1);
1342 }
1343 RETURN_WITH(buffered_write(s, buf, len));
1344 }
1345
1346 /*************************************************************************/
1347
1348 /* Write data from an mmap()ed area to a socket. The area will be
1349 * automatically unmapped when the write completes.
1350 */
1351
1352 int32
1353 swritemap(Socket * s, const char *buf, int32 len)
1354 {
1355 #ifndef DISABLE_SWRITEMAP
1356 struct wmapinfo *info;
1357
1358 ENTER_WITH("%d", "%p,%p,%d", s, buf, len);
1359 if (!s || !buf || len < 0)
1360 {
1361 log("sockets: swritemap() with %s!",
1362 !s ? "NULL socket" : !buf ? "NULL buffer" : "len < 0");
1363 errno = EINVAL;
1364 RETURN_WITH(-1);
1365 }
1366 if (!len)
1367 RETURN_WITH(0);
1368 info = malloc(sizeof(*info));
1369 if (!info)
1370 RETURN_WITH(-1);
1371 info->next = NULL;
1372 info->wait = write_buffer_len(s);
1373 info->map = buf;
1374 info->maplen = len;
1375 info->pos = 0;
1376 if (s->writemap)
1377 {
1378 if (!s->writemap_tail)
1379 {
1380 log("sockets: BUG: socket %d: writemap non-NULL but writemap_tail"
1381 " NULL", s->fd);
1382 s->writemap_tail = s->writemap;
1383 while (s->writemap_tail->next)
1384 s->writemap_tail = s->writemap_tail->next;
1385 }
1386 s->writemap_tail->next = info;
1387 }
1388 else
1389 {
1390 if (s->writemap_tail)
1391 {
1392 log("sockets: BUG: socket %d: writemap NULL but writemap_tail"
1393 " non-NULL", s->fd);
1394 }
1395 s->writemap = info;
1396 }
1397 s->writemap_tail = info;
1398 flush_write_buffer(s); /* to ensure FD is set in write_fds if needed */
1399 RETURN_WITH(len);
1400 #else /* DISABLE_SWRITEMAP */
1401 errno = ENOSYS;
1402 RETURN_WITH(-1);
1403 #endif
1404 }
1405
1406 /*************************************************************************/
1407
1408 /* Add a write trigger to the socket. The `data' parameter will be passed
1409 * to the callback when the trigger is reached. Returns 0 on success, -1
1410 * on failure.
1411 */
1412
1413 int
1414 swrite_trigger(Socket * s, void *data)
1415 {
1416 struct wmapinfo *info;
1417
1418 ENTER_WITH("%d", "%p,%p", s, data);
1419 if (!s)
1420 {
1421 log("sockets: swrite_trigger() with NULL socket!");
1422 errno = EINVAL;
1423 RETURN_WITH(-1);
1424 }
1425 info = malloc(sizeof(*info));
1426 if (!info)
1427 RETURN_WITH(-1);
1428 info->next = NULL;
1429 info->wait = write_buffer_len(s);
1430 info->map = (const char *) data;
1431 info->maplen = 0;
1432 info->pos = 0;
1433 if (s->writemap)
1434 {
1435 if (!s->writemap_tail)
1436 {
1437 log("sockets: BUG: socket %d: writemap non-NULL but writemap_tail"
1438 " NULL", s->fd);
1439 s->writemap_tail = s->writemap;
1440 while (s->writemap_tail->next)
1441 s->writemap_tail = s->writemap_tail->next;
1442 }
1443 s->writemap_tail->next = info;
1444 }
1445 else
1446 {
1447 if (s->writemap_tail)
1448 {
1449 log("sockets: BUG: socket %d: writemap NULL but writemap_tail"
1450 " non-NULL", s->fd);
1451 }
1452 s->writemap = info;
1453 }
1454 s->writemap_tail = info;
1455 flush_write_buffer(s); /* to ensure FD is set in write_fds if needed */
1456 RETURN_WITH(0);
1457 }
1458
1459 /*************************************************************************/
1460 /*************************************************************************/
1461
1462 /* Read a character from a socket, like fgetc(). Returns EOF if no data
1463 * is available in the socket buffer. Assumes the socket is valid.
1464 */
1465
1466 int
1467 sgetc(Socket * s)
1468 {
1469 int c;
1470
1471 ENTER_WITH("%d", "%p", s);
1472 /* No paranoia check here, to save time */
1473 if (s->rptr == s->rend)
1474 RETURN_WITH(EOF);
1475 c = *s->rptr++;
1476 if (s->rptr >= s->rtop)
1477 s->rptr -= read_buffer_size(s);
1478 RETURN_WITH(c);
1479 }
1480
1481 /*************************************************************************/
1482
1483 /* Read a line from a socket, like fgets(). If not enough buffered data
1484 * is available to fill a complete line, or another error occurs, returns
1485 * NULL.
1486 */
1487
1488 char *
1489 sgets(char *buf, int32 len, Socket * s)
1490 {
1491 char *ptr = s->rptr, *eol;
1492 int32 to_top = s->rtop - ptr; /* used for efficiency */
1493
1494 ENTER_WITH("%p", "%p,%d,%p", buf, len, s);
1495 if (!s || !buf || len <= 0)
1496 {
1497 log("sockets: sgets[2]() with %s!",
1498 !s ? "NULL socket" : !buf ? "NULL buffer" : "len <= 0");
1499 RETURN_WITH(NULL);
1500 }
1501
1502 /* Find end of line */
1503 if (s->rend > s->rptr)
1504 {
1505 eol = memchr(s->rptr, '\n', s->rend - s->rptr);
1506 }
1507 else
1508 {
1509 eol = memchr(s->rptr, '\n', to_top);
1510 if (!eol)
1511 eol = memchr(s->rbuf, '\n', s->rend - s->rbuf);
1512 }
1513 if (!eol)
1514 RETURN_WITH(NULL);
1515 eol++; /* Point 1 byte after \n */
1516
1517 /* Set rptr now; old value is in ptr variable */
1518 s->rptr = eol;
1519 if (s->rptr >= s->rtop) /* >rtop is impossible, but just in case */
1520 s->rptr = s->rbuf;
1521
1522 /* Note: The greatest possible value for eol is s->rend, so as long as
1523 * we ensure that rend doesn't wrap around and reach rptr (i.e. always
1524 * leave at least 1 byte in the buffer unused), we can never have
1525 * eol == ptr here. */
1526
1527 /* Trim eol to <len bytes */
1528 if (eol > ptr)
1529 {
1530 if (eol - ptr >= len)
1531 eol = ptr + len - 1;
1532 }
1533 else
1534 {
1535 if (to_top >= len - 1) /* we don't mind eol == rtop */
1536 eol = ptr + len - 1;
1537 else if (to_top + (eol - s->rbuf) >= len)
1538 eol = s->rbuf + (len - 1 - to_top);
1539 }
1540
1541 /* Actually copy to buffer and return */
1542 if (eol > ptr)
1543 {
1544 memcpy(buf, ptr, eol - ptr);
1545 buf[eol - ptr] = 0;
1546 }
1547 else
1548 {
1549 memcpy(buf, ptr, to_top);
1550 memcpy(buf + to_top, s->rbuf, eol - s->rbuf);
1551 buf[to_top + (eol - s->rbuf)] = 0;
1552 }
1553 RETURN_WITH(buf);
1554 }
1555
1556 /*************************************************************************/
1557
1558 /* Reads a line of text from a socket, and strips newline and carriage
1559 * return characters from the end of the line.
1560 */
1561
1562 char *
1563 sgets2(char *buf, int32 len, Socket * s)
1564 {
1565 char *str;
1566
1567 ENTER_WITH("%p", "%p,%d,%p", buf, len, s);
1568 str = sgets(buf, len, s);
1569 if (!str)
1570 RETURN_WITH(str);
1571 str = buf + strlen(buf) - 1;
1572 if (*str == '\n')
1573 *str-- = 0;
1574 if (*str == '\r')
1575 *str = 0;
1576 RETURN_WITH(buf);
1577 }
1578
1579 /*************************************************************************/
1580
1581 /* Write a string to a socket, like fputs(). Returns the number of bytes
1582 * written.
1583 */
1584
1585 int
1586 sputs(const char *str, Socket * s)
1587 {
1588 ENTER_WITH("%d", "[%s],%p", str ? str : "(null)", s);
1589 if (!str || !s)
1590 {
1591 log("sockets: sputs() with %s!", !s ? "NULL socket" : "NULL string");
1592 errno = EINVAL;
1593 RETURN_WITH(-1);
1594 }
1595 RETURN_WITH(buffered_write(s, str, strlen(str)));
1596 }
1597
1598 /*************************************************************************/
1599
1600 /* Write to a socket a la [v]printf(). Returns the number of bytes written;
1601 * in no case will more than 65535 bytes be written (if the output would be
1602 * be longer than this, it will be truncated).
1603 */
1604
1605 int
1606 sockprintf(Socket * s, const char *fmt, ...)
1607 {
1608 va_list args;
1609 int ret;
1610
1611 ENTER_WITH("%d", "%p,[%s],...", s, fmt ? fmt : "(null)");
1612 va_start(args, fmt);
1613 ret = vsockprintf(s, fmt, args);
1614 va_end(args);
1615 RETURN_WITH(ret);
1616 }
1617
1618 int
1619 vsockprintf(Socket * s, const char *fmt, va_list args)
1620 {
1621 char buf[65536];
1622
1623 ENTER_WITH("%d", "%p,[%s],%p", s, fmt ? fmt : "(null)", args);
1624 if (!s || !fmt)
1625 {
1626 log("sockets: [v]sockprintf() with %s!",
1627 !s ? "NULL socket" : "NULL format string");
1628 errno = EINVAL;
1629 RETURN_WITH(-1);
1630 }
1631 RETURN_WITH(buffered_write(s, buf, vsnprintf(buf, sizeof(buf), fmt, args)));
1632 }
1633
1634 /*************************************************************************/
1635 /************************** Internal routines ****************************/
1636 /*************************************************************************/
1637
1638 /* Call a callback on the given socket. Handles setting and clearing
1639 * SF_CALLBACK, and checking for remote disconnects after the callback
1640 * completes. Returns 0 if the socket has been disconnected, 1 otherwise.
1641 * If 0 is returned, the socket should be considered no longer valid; if it
1642 * was an automatically-created socket, the socket itself will have been
1643 * freed.
1644 *
1645 * `s' or `cb' may be NULL, in which case this routine does nothing and
1646 * returns 1.
1647 */
1648
1649 static int
1650 do_callback(Socket * s, SocketCallback cb, void *param)
1651 {
1652 ENTER_WITH("%d", "%p,%p,%p", s, cb, param);
1653 if (s && cb)
1654 {
1655 /* Check whether the SF_CALLBACK flag was set; if it is, then this
1656 * is a nested callback, so don't clear the flag or disconnect the
1657 * socket afterwards. */
1658 int was_set = s->flags & SF_CALLBACK;
1659
1660 if (!was_set)
1661 s->flags |= SF_CALLBACK;
1662 log_debug(3, "sockets: callback(%d,%p,%p)", s->fd, cb, param);
1663 cb(s, param);
1664 log_debug(3, "sockets: ...cbret(%d,%p,%p)", s->fd, cb, param);
1665 if (!was_set)
1666 {
1667 s->flags &= ~SF_CALLBACK;
1668 if (s->flags & SF_BROKEN)
1669 {
1670 log_debug(3, "sockets: ...broken");
1671 do_disconn(s, DISCONN_REMOTE_RESUME);
1672 RETURN_WITH(0);
1673 }
1674 if (s->flags & SF_DELETEME)
1675 {
1676 log_debug(3, "sockets: ...deleteme");
1677 sock_free(s);
1678 RETURN_WITH(0);
1679 }
1680 if ((s->flags & SF_DISCONNECT) || s->fd < 0)
1681 {
1682 log_debug(3, "sockets: ...disconnect");
1683 RETURN_WITH(0);
1684 }
1685 log_debug(3, "sockets: ...normalret");
1686 }
1687 else
1688 { /* SF_CALLBACK was already set */
1689 log_debug(3, "sockets: ...nestedret");
1690 }
1691 }
1692 RETURN_WITH(1);
1693 }
1694
1695 /*************************************************************************/
1696
1697 /* Accept a connection on the given socket. Called from check_sockets(). */
1698
1699 static void
1700 do_accept(Socket * s)
1701 {
1702 int i;
1703 struct sockaddr_in sin;
1704 socklen_t sin_len = sizeof(sin);
1705 int newfd;
1706
1707 ENTER("%p", s);
1708 newfd = accept(s->fd, (struct sockaddr *) &sin, &sin_len);
1709 if (newfd < 0)
1710 {
1711 if (errno != ECONNRESET)
1712 log_perror("sockets: accept(%d)", s->fd);
1713 }
1714 else if (!s->cb_accept)
1715 {
1716 /* No accept callback, so just throw the connection away */
1717 close(newfd);
1718 }
1719 else if (fcntl(newfd, F_SETFL, O_NDELAY) < 0)
1720 {
1721 log_perror("sockets: fcntl(NDELAY) on accept(%d)", s->fd);
1722 close(newfd);
1723 }
1724 else
1725 {
1726 Socket *news = sock_new();
1727 if (!news)
1728 {
1729 log("sockets: accept(%d): Unable to create socket structure"
1730 " (out of buffer space?)", s->fd);
1731 }
1732 else
1733 {
1734 news->fd = newfd;
1735 news->flags |= SF_SELFCREATED | SF_CONNECTED;
1736 memcpy(&news->remote, &sin, sin_len);
1737 for (i = newfd; i < max_fd; i++);
1738 if (max_fd < newfd + 1)
1739 {
1740 void *new_sockets = realloc(sockets, (newfd + 1) * sizeof(*sockets));
1741 if (!new_sockets)
1742 {
1743 sock_free(news);
1744 close(newfd);
1745 RETURN;
1746 }
1747 sockets = new_sockets;
1748 for (i = max_fd; i < newfd; i++)
1749 sockets[i] = NULL;
1750 max_fd = newfd + 1;
1751 }
1752 sockets[newfd] = news;
1753 if (!(news->flags & SF_MUTE))
1754 FD_SET(newfd, &sock_fds);
1755 do_callback(s, s->cb_accept, news);
1756 }
1757 }
1758 RETURN;
1759 }
1760
1761 /*************************************************************************/
1762
1763 /* Fill up the read buffer of a socket with any data that may have arrived.
1764 * Returns the number of bytes read (nonzero), or -1 on error; errno is set
1765 * by recv() calls but is otherwise preserved.
1766 */
1767
1768 static int
1769 fill_read_buffer(Socket * s)
1770 {
1771 int nread = 0;
1772 int errno_save = errno;
1773
1774 ENTER_WITH("%d", "%p", s);
1775 if (s->fd < 0)
1776 {
1777 errno = EBADF;
1778 RETURN_WITH(-1);
1779 }
1780 for (;;)
1781 {
1782 int maxread, res;
1783 if (read_buffer_len(s) >= read_buffer_size(s) - 1)
1784 {
1785 /* Read buffer is full; try to expand the buffer. */
1786 int over;
1787 int32 more = resize_how_much(s, read_buffer_size(s), &over);
1788 if (more)
1789 {
1790 if (!resize_rbuf(s, read_buffer_size(s) + more))
1791 {
1792 log("sockets: attempt to expand socket %d read buffer"
1793 " failed (out of memory?)", s->fd);
1794 errno_save = EAGAIN;
1795 if (nread == 0)
1796 nread = -1;
1797 break;
1798 }
1799 }
1800 else
1801 {
1802 #ifdef WARN_ON_BUFSIZE
1803 if (!(s->flags & SF_WARNED))
1804 {
1805 log("sockets: socket %d exceeded %s buffer size limit"
1806 " (%d)", s->fd, over ? "per-connection" : "total",
1807 over ? bufsize_limit : total_bufsize_limit);
1808 s->flags |= SF_WARNED;
1809 }
1810 #endif
1811 errno_save = EAGAIN;
1812 if (nread == 0)
1813 nread = -1;
1814 break;
1815 }
1816 }
1817 if (s->rend < s->rptr) /* wrapped around? */
1818 maxread = (s->rptr - 1) - s->rend;
1819 else if (s->rptr == s->rbuf)
1820 maxread = s->rtop - s->rend - 1;
1821 else
1822 maxread = s->rtop - s->rend;
1823 do
1824 {
1825 errno = 0;
1826 res = recv(s->fd, s->rend, maxread, 0);
1827 if (res <= 0 && errno == 0)
1828 errno = ECONNRESET; /* make a guess */
1829 }
1830 while (res <= 0 && errno == EINTR);
1831 errno_save = errno;
1832 log_debug(3, "sockets: fill_read_buffer wanted %d, got %d",
1833 maxread, nread);
1834 if (res <= 0)
1835 {
1836 if (nread == 0)
1837 nread = -1;
1838 break;
1839 }
1840 nread += res;
1841 s->total_read += res;
1842 s->rend += res;
1843 if (s->rend == s->rtop)
1844 s->rend = s->rbuf;
1845 }
1846 if (nread == 0)
1847 {
1848 nread = -1;
1849 errno = ENOBUFS;
1850 }
1851 else
1852 {
1853 errno = errno_save;
1854 }
1855 RETURN_WITH(nread);
1856 }
1857
1858 /*************************************************************************/
1859
1860 /* Try and write up to one chunk of data from the buffer to the socket.
1861 * Return -1 on error, -2 if a socket waiting for disconnection was closed,
1862 * or else how many bytes were written. (Note that a return value of zero
1863 * should not be considered an error.)
1864 */
1865
1866 static int
1867 flush_write_buffer(Socket * s)
1868 {
1869 int32 maxwrite, nwritten;
1870
1871 ENTER_WITH("%d", "%p", s);
1872 if (s->fd < 0)
1873 {
1874 errno = EBADF;
1875 RETURN_WITH(-1);
1876 }
1877 if (!sock_isconn(s)) /* not yet connected */
1878 RETURN_WITH(0);
1879 if (s->flags & SF_WTRIGGER)
1880 {
1881 /* Write trigger is still pending on this socket, don't do anything */
1882 nwritten = 0;
1883 goto check_result;
1884 }
1885 /* "while" instead of "if" to handle the case of:
1886 * s->writemap->wait == 0
1887 * s->writemap->pos == s->writemap->maplen (should be impossible here)
1888 * s->writemap->next->wait == 0
1889 */
1890 while (s->writemap && s->writemap->wait <= 0)
1891 {
1892 /* Write data from the map instead of the buffer */
1893 if (!s->writemap->maplen)
1894 {
1895 /* It's a trigger, stop here. We don't skip to the next wmap
1896 * yet in case we're called again before the trigger callback
1897 * is called. */
1898 s->flags |= SF_WTRIGGER;
1899 nwritten = 0; /* return value */
1900 goto check_result;
1901 }
1902 maxwrite = s->writemap->maplen - s->writemap->pos;
1903 if (maxwrite > 0)
1904 {
1905 nwritten = send(s->fd, s->writemap->map + s->writemap->pos,
1906 maxwrite, 0);
1907 log_debug(3, "sockets: flush_write_buffer/map wanted %d, got %d",
1908 maxwrite, nwritten);
1909 if (nwritten > 0)
1910 {
1911 s->writemap->pos += nwritten;
1912 if (s->writemap->pos >= s->writemap->maplen)
1913 next_wmap(s);
1914 }
1915 goto check_result;
1916 }
1917 else
1918 {
1919 next_wmap(s);
1920 }
1921 }
1922 nwritten = 0;
1923 if (s->wend != s->wptr)
1924 {
1925 if (s->wptr > s->wend) /* wrapped around? */
1926 maxwrite = s->wtop - s->wptr;
1927 else
1928 maxwrite = s->wend - s->wptr;
1929 if (s->writemap && maxwrite > s->writemap->wait)
1930 {
1931 maxwrite = s->writemap->wait;
1932 if (maxwrite <= 0)
1933 {
1934 /* paranoia: this is impossible from the while() above */
1935 log("sockets: BUG: flush_write_buffer(%d): writemap wait 0"
1936 " after while", s->fd);
1937 do_disconn(s, DISCONN_REMOTE);
1938 RETURN_WITH(-1);
1939 }
1940 }
1941 nwritten = send(s->fd, s->wptr, maxwrite, 0);
1942 log_debug(3, "sockets: flush_write_buffer wanted %d, got %d",
1943 maxwrite, nwritten);
1944 if (nwritten > 0)
1945 {
1946 struct wmapinfo *info;
1947 for (info = s->writemap; info; info = info->next)
1948 {
1949 info->wait -= nwritten;
1950 }
1951 s->wptr += nwritten;
1952 if (s->wptr >= s->wtop)
1953 s->wptr = s->wbuf;
1954 }
1955 check_result:
1956 if (nwritten < 0 && errno != EAGAIN && errno != EINTR)
1957 {
1958 int errno_save = errno;
1959 if (errno != ECONNRESET && errno != EPIPE)
1960 log_perror("sockets: flush_write_buffer(%d)", s->fd);
1961 do_disconn(s, DISCONN_REMOTE);
1962 errno = errno_save;
1963 RETURN_WITH(-1);
1964 }
1965 if (nwritten > 0)
1966 {
1967 s->last_write_time = time(NULL);
1968 s->flags &= ~SF_WARNED;
1969 s->total_written += nwritten;
1970 }
1971 else
1972 {
1973 nwritten = 0; /* return value */
1974 }
1975 }
1976 if ((s->flags & SF_CALLBACK) || MORE_TO_WRITE(s))
1977 {
1978 FD_SET(s->fd, &write_fds);
1979 }
1980 else
1981 {
1982 FD_CLR(s->fd, &write_fds);
1983 if (s->flags & SF_DISCONNECT)
1984 {
1985 s->flags &= ~SF_DISCONNECT;
1986 do_disconn(s, DISCONN_LOCAL_RESUME);
1987 RETURN_WITH(-2);
1988 }
1989 else
1990 {
1991 reclaim_buffer_space_one(s);
1992 }
1993 }
1994 RETURN_WITH(nwritten);
1995 }
1996
1997 /*************************************************************************/
1998
1999 /* Return the amount by which a socket's read or write buffer should be
2000 * expanded. Return zero if the per-connection or total network buffer
2001 * size limits have been reached and the buffer cannot be expanded; in
2002 * this case, set *errp to 1 if the per-connection buffer size limit was
2003 * exceeded, 0 if the total buffer size limit was exceeded.
2004 */
2005
2006 static uint32
2007 resize_how_much(const Socket * s, uint32 current_size, int *errp)
2008 {
2009 uint32 socktotal = read_buffer_size(s) + write_buffer_size(s);
2010 int32 more;
2011 int over = 0, over_total = 0;
2012
2013 /* Check current size against limits */
2014 if (bufsize_limit && socktotal >= bufsize_limit)
2015 over = 1;
2016 if (total_bufsize_limit && total_bufsize >= total_bufsize_limit)
2017 over_total = 1;
2018 if (over || over_total)
2019 {
2020 if (over)
2021 *errp = 1;
2022 else
2023 *errp = 0;
2024 return 0;
2025 }
2026
2027 /* Expand by 10%, rounded up to a multiple of SOCK_MIN_BUFSIZE */
2028 more = current_size / 10;
2029 more = (more + SOCK_MIN_BUFSIZE - 1) / SOCK_MIN_BUFSIZE * SOCK_MIN_BUFSIZE;
2030
2031 /* Make sure new size doesn't exceed limits */
2032 if (bufsize_limit && socktotal + more >= bufsize_limit)
2033 more = bufsize_limit - socktotal;
2034 if (total_bufsize_limit && total_bufsize + more >= total_bufsize_limit)
2035 more = total_bufsize_limit - total_bufsize;
2036 if (more < 0)
2037 {
2038 more = 0;
2039 /* This shouldn't be possible; assume it's the total buffer size */
2040 *errp = 0;
2041 }
2042
2043 /* Return it */
2044 return more;
2045 }
2046
2047
2048 /* Resize a socket's read or write buffer. */
2049
2050 static int
2051 resize_rbuf(Socket * s, uint32 size)
2052 {
2053 ENTER("%p,%u", s, size);
2054 if (size <= read_buffer_len(s))
2055 {
2056 log("sockets: BUG: resize_rbuf(%d): size (%d) <= rlen (%d)"
2057 " (cursize %ld)", s->fd, size, read_buffer_len(s),
2058 (long) (s->rtop - s->rbuf));
2059 RETURN_WITH(0);
2060 }
2061 RETURN_WITH(resize_buf(&s->rbuf, &s->rptr, &s->rend, &s->rtop, size));
2062 }
2063
2064
2065 static int
2066 resize_wbuf(Socket * s, uint32 size)
2067 {
2068 ENTER("%p,%u", s, size);
2069 if (size <= write_buffer_len(s))
2070 {
2071 log("sockets: BUG: resize_wbuf(%d): size (%d) <= wlen (%d)"
2072 " (cursize %ld)", s->fd, size, write_buffer_len(s),
2073 (long) (s->wtop - s->wbuf));
2074 RETURN_WITH(0);
2075 }
2076 RETURN_WITH(resize_buf(&s->wbuf, &s->wptr, &s->wend, &s->wtop, size));
2077 }
2078
2079 /* Routine that does the actual resizing. Assumes that newsize >= current
2080 * size. Returns nonzero on success, zero on failure (out of memory). */
2081 static int
2082 resize_buf(char **p_buf, char **p_ptr, char **p_end, char **p_top,
2083 uint32 newsize)
2084 {
2085 uint32 size = *p_top - *p_buf;
2086 char *newbuf;
2087 uint32 len = 0;
2088
2089 ENTER_WITH("%d", "%p,%p,%p,%p,%u", p_buf, p_ptr, p_end, p_top, newsize);
2090 if (newsize <= size)
2091 RETURN_WITH(1);
2092 newbuf = malloc(newsize);
2093 if (!newbuf)
2094 RETURN_WITH(0);
2095 total_bufsize -= size;
2096 total_bufsize += newsize;
2097 /* Copy old data to new buffer, if any */
2098 if (*p_end < *p_ptr)
2099 {
2100 len = *p_top - *p_ptr;
2101 memcpy(newbuf, *p_ptr, len);
2102 *p_ptr = *p_buf;
2103 }
2104 if (*p_end > *p_ptr)
2105 {
2106 memcpy(newbuf + len, *p_ptr, *p_end - *p_ptr);
2107 len += *p_end - *p_ptr;
2108 }
2109 free(*p_buf);
2110 *p_buf = newbuf;
2111 *p_ptr = newbuf;
2112 *p_end = newbuf + len;
2113 *p_top = newbuf + newsize;
2114 RETURN_WITH(1);
2115 }
2116
2117 /*************************************************************************/
2118
2119 /* Try to reclaim unused buffer space. Return 1 if some buffer space was
2120 * freed, 0 if not.
2121 */
2122
2123 static int
2124 reclaim_buffer_space_one(Socket * s)
2125 {
2126 uint32 rlen = read_buffer_len(s), wlen = write_buffer_len(s);
2127 int retval = 0;
2128
2129 ENTER_WITH("%d", "%p", s);
2130 if (read_buffer_size(s) > SOCK_MIN_BUFSIZE
2131 && rlen < read_buffer_size(s) - SOCK_MIN_BUFSIZE)
2132 {
2133 if (rlen < SOCK_MIN_BUFSIZE)
2134 {
2135 rlen = SOCK_MIN_BUFSIZE;
2136 }
2137 else
2138 {
2139 /* Round up to the next multiple of SOCK_MIN_BUFSIZE, leaving
2140 * at least one byte available */
2141 rlen += SOCK_MIN_BUFSIZE;
2142 rlen /= SOCK_MIN_BUFSIZE;
2143 rlen *= SOCK_MIN_BUFSIZE;
2144 }
2145 resize_rbuf(s, rlen);
2146 retval = 1;
2147 }
2148 if (write_buffer_size(s) > SOCK_MIN_BUFSIZE
2149 && wlen < write_buffer_size(s) - SOCK_MIN_BUFSIZE)
2150 {
2151 if (wlen < SOCK_MIN_BUFSIZE)
2152 {
2153 wlen = SOCK_MIN_BUFSIZE;
2154 }
2155 else
2156 {
2157 wlen += SOCK_MIN_BUFSIZE;
2158 wlen /= SOCK_MIN_BUFSIZE;
2159 wlen *= SOCK_MIN_BUFSIZE;
2160 }
2161 resize_wbuf(s, wlen);
2162 retval = 1;
2163 }
2164 RETURN_WITH(retval);
2165 }
2166
2167
2168 static int
2169 reclaim_buffer_space(void)
2170 {
2171 Socket *s;
2172 int retval = 0;
2173
2174 ENTER_WITH("%d", "");
2175 LIST_FOREACH(s, allsockets)
2176 {
2177 retval |= reclaim_buffer_space_one(s);
2178 }
2179 RETURN_WITH(retval);
2180 }
2181
2182 /*************************************************************************/
2183
2184 /* Free the first map on the socket's writemap list. */
2185
2186 static void
2187 next_wmap(Socket * s)
2188 {
2189 struct wmapinfo *next;
2190
2191 ENTER("%p", s);
2192 if (!s || !s->writemap)
2193 {
2194 log("sockets: BUG: next_wmap() with NULL %s!", s ? "writemap" : "socket");
2195 RETURN;
2196 }
2197 if (s->writemap->map)
2198 {
2199 #ifdef DISABLE_SWRITEMAP
2200 log("sockets: BUG: DISABLE_SWRITEMAP but non-NULL map %p for socket"
2201 " %p", s->writemap->map, s);
2202 #else
2203 munmap((void *) s->writemap->map, s->writemap->maplen);
2204 #endif
2205 }
2206 next = s->writemap->next;
2207 free(s->writemap);
2208 if (next)
2209 {
2210 s->writemap = next;
2211 }
2212 else
2213 {
2214 s->writemap = s->writemap_tail = NULL;
2215 }
2216 RETURN;
2217 }
2218
2219 /*************************************************************************/
2220
2221 /* Write data to a socket with buffering. */
2222
2223 static int
2224 buffered_write(Socket * s, const char *buf, int len)
2225 {
2226 int nwritten, left = len;
2227 int errno_save = errno;
2228
2229 ENTER_WITH("%d", "%p,%p,%d", s, buf, len);
2230 if (s->fd < 0)
2231 {
2232 errno = EBADF;
2233 RETURN_WITH(-1);
2234 }
2235
2236 /* Reset the write timeout if the buffer is currently empty and we're
2237 * not busy writing a mapped buffer. */
2238 if (!MORE_TO_WRITE(s))
2239 s->last_write_time = time(NULL);
2240
2241 while (left > 0)
2242 {
2243
2244 /* Fill up to the current buffer size. */
2245 if (write_buffer_len(s) < write_buffer_size(s) - 1)
2246 {
2247 int maxwrite;
2248 /* If buffer is empty, reset pointers to beginning for efficiency */
2249 if (write_buffer_len(s) == 0)
2250 s->wptr = s->wend = s->wbuf;
2251 if (s->wptr == s->wbuf)
2252 {
2253 /* Buffer not wrapped */
2254 maxwrite = s->wtop - s->wend - 1;
2255 }
2256 else
2257 {
2258 /* Buffer is wrapped. If this write would reach to or past
2259 * the end of the buffer, write it first and reset the end
2260 * pointer to the beginning of the buffer. */
2261 if (s->wend + left >= s->wtop && s->wptr <= s->wend)
2262 {
2263 nwritten = s->wtop - s->wend;
2264 memcpy(s->wend, buf, nwritten);
2265 buf += nwritten;
2266 left -= nwritten;
2267 s->wend = s->wbuf;
2268 }
2269 /* Now we can copy a single chunk to wend. */
2270 if (s->wptr > s->wend)
2271 maxwrite = s->wptr - s->wend - 1;
2272 else
2273 maxwrite = left; /* guaranteed to fit from above code */
2274 }
2275 if (left > maxwrite)
2276 nwritten = maxwrite;
2277 else
2278 nwritten = left;
2279 if (nwritten)
2280 {
2281 memcpy(s->wend, buf, nwritten);
2282 buf += nwritten;
2283 left -= nwritten;
2284 s->wend += nwritten;
2285 }
2286 }
2287
2288 /* Now write to the socket as much as we can. */
2289 if (flush_write_buffer(s) < 0)
2290 RETURN_WITH(len - left); /* socket is not valid any more */
2291 errno_save = errno;
2292 if (write_buffer_len(s) >= write_buffer_size(s) - 1)
2293 {
2294 /* Write failed on full buffer; try to expand the buffer. */
2295 int over;
2296 uint32 more = resize_how_much(s, write_buffer_size(s), &over);
2297 if (more)
2298 {
2299 if (!resize_wbuf(s, write_buffer_size(s) + more))
2300 {
2301 /* It would be proper to block here, but if we ran out
2302 * of memory the program's probably about to abort
2303 * anyway, so just error out */
2304 log("sockets: attempt to expand socket %d read buffer"
2305 " failed (out of memory?)", s->fd);
2306 errno_save = EAGAIN;
2307 break;
2308 }
2309 }
2310 else
2311 {
2312 if ((s->flags & SF_BLOCKING) && !(s->flags & SF_WTRIGGER))
2313 {
2314 fd_set fds;
2315 FD_ZERO(&fds);
2316 FD_SET(s->fd, &fds);
2317 if (select(s->fd + 1, NULL, &fds, NULL, NULL) < 0)
2318 {
2319 log("sockets: waiting on blocking socket %d: %s",
2320 s->fd, strerror(errno));
2321 break;
2322 }
2323 continue; /* don't expand the buffer, since it's at max */
2324 }
2325 else
2326 {
2327 #ifdef WARN_ON_BUFSIZE
2328 if (!(s->flags & SF_WARNED))
2329 {
2330 log("sockets: socket %d exceeded %s buffer size"
2331 " limit (%d)", s->fd,
2332 over ? "per-connection" : "total",
2333 over ? bufsize_limit : total_bufsize_limit);
2334 s->flags |= SF_WARNED;
2335 }
2336 #endif
2337 errno_save = EAGAIN;
2338 break;
2339 }
2340 }
2341 }
2342
2343 } /* while (left > 0) */
2344
2345 errno = errno_save;
2346 RETURN_WITH(len - left);
2347 }
2348
2349 /*************************************************************************/
2350
2351 /* Internal version of disconn(), used to pass a specific code to the
2352 * disconnect callback. If code == DISCONN_LOCAL, attempt to first write
2353 * out any data left in the write buffer, and delay disconnection if we
2354 * can't.
2355 */
2356
2357 static int
2358 do_disconn(Socket * s, void *code)
2359 {
2360 int errno_save = errno; /* for passing to the callback */
2361
2362 ENTER_WITH("%d", "%p,%p", s, code);
2363 if (s == NULL || (s->flags & SF_LISTENER))
2364 {
2365 if (s)
2366 log("sockets: BUG: do_disconn(%d) with listener socket (%d)!",
2367 (int) (long) code, s->fd);
2368 else
2369 log("sockets: BUG: do_disconn(%d) with NULL socket!",
2370 (int) (long) code);
2371 errno = EINVAL;
2372 RETURN_WITH(-1);
2373 }
2374 if ((s->flags & SF_DISCONNECTING) && !((int) code & DISCONN_RESUME_FLAG))
2375 RETURN_WITH(0);
2376 if ((s->flags & SF_DISCONN_REQ) && code == DISCONN_LOCAL)
2377 RETURN_WITH(0);
2378 if (!(s->flags & (SF_CONNECTING | SF_CONNECTED)))
2379 RETURN_WITH(0);
2380 s->flags |= SF_DISCONN_REQ;
2381 FD_CLR(s->fd, &sock_fds);
2382 if (code == DISCONN_LOCAL && MORE_TO_WRITE(s))
2383 {
2384 /* Write out any buffered data */
2385 if (flush_write_buffer(s) >= 0 && MORE_TO_WRITE(s))
2386 {
2387 /* Some data is still buffered; request disconnect after it
2388 * goes out */
2389 s->flags |= SF_DISCONNECT;
2390 /* It's not technically disconnected yet, but it will (should)
2391 * succeed eventually */
2392 RETURN_WITH(0);
2393 }
2394 }
2395 s->flags |= SF_DISCONNECTING;
2396 if (code == DISCONN_REMOTE && (s->flags & SF_CALLBACK))
2397 {
2398 /* Socket was closed while a callback was doing something; wait
2399 * until the callback finishes to actually close the socket */
2400 s->flags |= SF_BROKEN;
2401 RETURN_WITH(0);
2402 }
2403 shutdown(s->fd, 2);
2404 sock_closefd(s);
2405 while (s->writemap)
2406 next_wmap(s);
2407 s->writemap_tail = NULL;
2408 if (s->cb_disconn)
2409 {
2410 /* The disconnect callback doesn't need to check for disconnection,
2411 * so we just call it directly */
2412 errno = errno_save;
2413 s->cb_disconn(s, (void *) ((int) code & ~DISCONN_RESUME_FLAG));
2414 }
2415 s->flags &= ~SF_DISCONNECTING;
2416 if (s->fd >= 0)
2417 {
2418 /* The socket was reconnected */
2419 return 0;
2420 }
2421 s->flags &= ~(SF_CONNECTING | SF_CONNECTED);
2422 if (s->flags & (SF_SELFCREATED | SF_DELETEME))
2423 {
2424 if (s->flags & SF_CALLBACK)
2425 s->flags |= SF_DELETEME;
2426 else
2427 sock_free(s);
2428 }
2429 else
2430 {
2431 reclaim_buffer_space_one(s);
2432 }
2433 RETURN_WITH(0);
2434 }
2435
2436 /*************************************************************************/
2437
2438 /* Close a socket's file descriptor, and clear it from all associated
2439 * structures (s->fd, sockets[], sock_fds, write_fds).
2440 */
2441
2442 static void
2443 sock_closefd(Socket * s)
2444 {
2445 ENTER("%p", s);
2446 /* FIXME: apparently it's possible to come here twice for the same
2447 * connection; under what circumstances can that happen? */
2448 if (s->fd >= 0)
2449 {
2450 close(s->fd);
2451 FD_CLR(s->fd, &sock_fds);
2452 FD_CLR(s->fd, &write_fds);
2453 sockets[s->fd] = NULL;
2454 s->fd = -1;
2455 }
2456 RETURN;
2457 }
2458
2459 /*************************************************************************/
2460
2461 /*
2462 * Local variables:
2463 * c-file-style: "stroustrup"
2464 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
2465 * indent-tabs-mode: nil
2466 * End:
2467 *
2468 * vim: expandtab shiftwidth=4:
2469 */