2 * ssld.c: The ircd-ratbox ssl/zlib helper daemon thingy
3 * Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
4 * Copyright (C) 2007 ircd-ratbox development team
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 * $Id: ssld.c 25179 2008-03-30 16:34:57Z androsyn $
33 #define READBUF_SIZE 16384
36 static void setup_signals(void);
38 static inline rb_int32_t
buf_to_int32(char *buf
)
48 static inline void int32_to_buf(char *buf
, rb_int32_t x
)
50 *(buf
) = x
>> 24 & 0xFF;
51 *(++buf
) = x
>> 16 & 0xFF;
52 *(++buf
) = x
>> 8 & 0xFF;
57 static inline rb_uint16_t
buf_to_uint16(char *buf
)
65 static inline void uint16_to_buf(char *buf
, rb_uint16_t x
)
67 *(buf
) = x
>> 8 & 0xFF;
74 static char inbuf
[READBUF_SIZE
];
75 static char outbuf
[READBUF_SIZE
];
77 typedef struct _mod_ctl_buf
82 rb_fde_t
*F
[MAXPASSFD
];
86 typedef struct _mod_ctl
96 static mod_ctl_t
*mod_ctl
;
100 typedef struct _zlib_stream
111 rawbuf_head_t
*modbuf_out
;
112 rawbuf_head_t
*plainbuf_out
;
118 unsigned long long mod_out
;
119 unsigned long long mod_in
;
120 unsigned long long plain_in
;
121 unsigned long long plain_out
;
126 #define FLAG_SSL 0x01
127 #define FLAG_ZIP 0x02
128 #define FLAG_CORK 0x04
129 #define FLAG_DEAD 0x08
132 #define IsSSL(x) ((x)->flags & FLAG_SSL)
133 #define IsZip(x) ((x)->flags & FLAG_ZIP)
134 #define IsCork(x) ((x)->flags & FLAG_CORK)
135 #define IsDead(x) ((x)->flags & FLAG_DEAD)
137 #define SetSSL(x) ((x)->flags |= FLAG_SSL)
138 #define SetZip(x) ((x)->flags |= FLAG_ZIP)
139 #define SetCork(x) ((x)->flags |= FLAG_CORK)
140 #define SetDead(x) ((x)->flags |= FLAG_DEAD)
142 #define ClearSSL(x) ((x)->flags &= ~FLAG_SSL)
143 #define ClearZip(x) ((x)->flags &= ~FLAG_ZIP)
144 #define ClearCork(x) ((x)->flags &= ~FLAG_CORK)
145 #define ClearDead(x) ((x)->flags &= ~FLAG_DEAD)
148 #define WAIT_PLAIN 0x1
150 #define CONN_HASH_SIZE 2000
151 #define connid_hash(x) (&connid_hash_table[(x % CONN_HASH_SIZE)])
153 static rb_dlink_list connid_hash_table
[CONN_HASH_SIZE
];
154 static rb_dlink_list dead_list
;
156 static void conn_mod_write_sendq(rb_fde_t
*, void *data
);
157 static void conn_plain_write_sendq(rb_fde_t
*, void *data
);
158 static void mod_write_ctl(rb_fde_t
*, void *data
);
159 static void conn_plain_read_cb(rb_fde_t
* fd
, void *data
);
160 static void mod_cmd_write_queue(mod_ctl_t
*ctl
, const void *data
, size_t len
);
161 static const char *remote_closed
= "Remote host closed the connection";
164 static int zlib_ok
= 1;
166 static int zlib_ok
= 0;
169 ssld_alloc(void *unused
, size_t count
, size_t size
)
171 return rb_malloc(count
* size
);
175 ssld_free(void *unused
, void *ptr
)
181 conn_find_by_id(rb_int32_t id
)
186 RB_DLINK_FOREACH(ptr
, (connid_hash(id
))->head
)
189 if(conn
->id
== id
&& !IsDead(conn
))
196 conn_add_id_hash(conn_t
* conn
, rb_int32_t id
)
199 rb_dlinkAdd(conn
, &conn
->node
, connid_hash(id
));
203 free_conn(conn_t
* conn
)
205 rb_free_rawbuffer(conn
->modbuf_out
);
206 rb_free_rawbuffer(conn
->plainbuf_out
);
209 zlib_stream_t
*stream
= conn
->stream
;
210 inflateEnd(&stream
->instream
);
211 deflateEnd(&stream
->outstream
);
217 clean_dead_conns(void *unused
)
220 rb_dlink_node
*ptr
, *next
;
221 RB_DLINK_FOREACH_SAFE(ptr
, next
, dead_list
.head
)
226 dead_list
.tail
= dead_list
.head
= NULL
;
231 close_conn(conn_t
* conn
, int wait_plain
, const char *fmt
, ...)
234 char reason
[128]; /* must always be under 250 bytes */
240 rb_rawbuf_flush(conn
->modbuf_out
, conn
->mod_fd
);
241 rb_rawbuf_flush(conn
->plainbuf_out
, conn
->plain_fd
);
242 rb_close(conn
->mod_fd
);
245 if(!wait_plain
|| fmt
== NULL
)
247 rb_close(conn
->plain_fd
);
250 rb_dlinkDelete(&conn
->node
, connid_hash(conn
->id
));
251 rb_dlinkAdd(conn
, &conn
->node
, &dead_list
);
254 rb_setselect(conn
->plain_fd
, RB_SELECT_WRITE
|RB_SELECT_READ
, NULL
, NULL
);
256 rb_vsnprintf(reason
, sizeof(reason
), fmt
, ap
);
260 int32_to_buf(&buf
[1], conn
->id
);
261 strcpy(&buf
[5], reason
);
262 len
= (strlen(reason
) + 1) + 5;
263 mod_cmd_write_queue(conn
->ctl
, buf
, len
);
267 make_conn(mod_ctl_t
*ctl
, rb_fde_t
* mod_fd
, rb_fde_t
* plain_fd
)
269 conn_t
*conn
= rb_malloc(sizeof(conn_t
));
271 conn
->modbuf_out
= rb_new_rawbuffer();
272 conn
->plainbuf_out
= rb_new_rawbuffer();
273 conn
->mod_fd
= mod_fd
;
274 conn
->plain_fd
= plain_fd
;
283 conn_mod_write_sendq(rb_fde_t
* fd
, void *data
)
291 while ((retlen
= rb_rawbuf_flush(conn
->modbuf_out
, fd
)) > 0)
292 conn
->mod_out
+= retlen
;
294 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
297 close_conn(conn
, WAIT_PLAIN
, "%s", remote_closed
);
298 if(IsSSL(conn
) && retlen
== RB_RW_SSL_ERROR
)
299 err
= rb_get_ssl_strerror(conn
->mod_fd
);
301 err
= strerror(errno
);
302 close_conn(conn
, WAIT_PLAIN
, "Write error: %s", err
);
305 if(rb_rawbuf_length(conn
->modbuf_out
) > 0)
307 int flags
= RB_SELECT_WRITE
;
308 if(retlen
== RB_RW_SSL_NEED_READ
)
309 flags
|= RB_SELECT_READ
;
311 rb_setselect(conn
->mod_fd
, flags
, conn_mod_write_sendq
, conn
);
314 rb_setselect(conn
->mod_fd
, RB_SELECT_WRITE
, NULL
, NULL
);
316 if(IsCork(conn
) && rb_rawbuf_length(conn
->modbuf_out
) == 0)
319 conn_plain_read_cb(conn
->plain_fd
, conn
);
325 conn_mod_write(conn_t
* conn
, void *data
, size_t len
)
327 if(IsDead(conn
)) /* no point in queueing to a dead man */
329 rb_rawbuf_append(conn
->modbuf_out
, data
, len
);
333 conn_plain_write(conn_t
* conn
, void *data
, size_t len
)
335 if(IsDead(conn
)) /* again no point in queueing to dead men */
337 rb_rawbuf_append(conn
->plainbuf_out
, data
, len
);
341 mod_cmd_write_queue(mod_ctl_t
* ctl
, const void *data
, size_t len
)
343 mod_ctl_buf_t
*ctl_buf
;
344 ctl_buf
= rb_malloc(sizeof(mod_ctl_buf_t
));
345 ctl_buf
->buf
= rb_malloc(len
);
346 ctl_buf
->buflen
= len
;
347 memcpy(ctl_buf
->buf
, data
, len
);
349 rb_dlinkAddTail(ctl_buf
, &ctl_buf
->node
, &ctl
->writeq
);
350 mod_write_ctl(ctl
->F
, ctl
);
355 common_zlib_deflate(conn_t
* conn
, void *buf
, size_t len
)
358 z_stream
*outstream
= &((zlib_stream_t
*)conn
->stream
)->outstream
;
359 outstream
->next_in
= buf
;
360 outstream
->avail_in
= len
;
361 outstream
->next_out
= (Bytef
*) outbuf
;
362 outstream
->avail_out
= sizeof(outbuf
);
364 ret
= deflate(outstream
, Z_SYNC_FLUSH
);
368 close_conn(conn
, WAIT_PLAIN
, "Deflate failed: %s", zError(ret
));
371 if(outstream
->avail_out
== 0)
373 /* avail_out empty */
374 close_conn(conn
, WAIT_PLAIN
, "error compressing data, avail_out == 0");
377 if(outstream
->avail_in
!= 0)
379 /* avail_in isn't empty...*/
380 close_conn(conn
, WAIT_PLAIN
, "error compressing data, avail_in != 0");
383 have
= sizeof(outbuf
) - outstream
->avail_out
;
384 conn_mod_write(conn
, outbuf
, have
);
388 common_zlib_inflate(conn_t
* conn
, void *buf
, size_t len
)
391 ((zlib_stream_t
*)conn
->stream
)->instream
.next_in
= buf
;
392 ((zlib_stream_t
*)conn
->stream
)->instream
.avail_in
= len
;
393 ((zlib_stream_t
*)conn
->stream
)->instream
.next_out
= (Bytef
*) outbuf
;
394 ((zlib_stream_t
*)conn
->stream
)->instream
.avail_out
= sizeof(outbuf
);
396 while (((zlib_stream_t
*)conn
->stream
)->instream
.avail_in
)
398 ret
= inflate(&((zlib_stream_t
*)conn
->stream
)->instream
, Z_NO_FLUSH
);
401 if(!strncmp("ERROR ", buf
, 6))
403 close_conn(conn
, WAIT_PLAIN
, "Received uncompressed ERROR");
406 close_conn(conn
, WAIT_PLAIN
, "Inflate failed: %s", zError(ret
));
409 have
= sizeof(outbuf
) - ((zlib_stream_t
*)conn
->stream
)->instream
.avail_out
;
411 if(((zlib_stream_t
*)conn
->stream
)->instream
.avail_in
)
413 conn_plain_write(conn
, outbuf
, have
);
415 ((zlib_stream_t
*)conn
->stream
)->instream
.next_out
= (Bytef
*) outbuf
;
416 ((zlib_stream_t
*)conn
->stream
)->instream
.avail_out
= sizeof(outbuf
);
422 conn_plain_write(conn
, outbuf
, have
);
427 plain_check_cork(conn_t
* conn
)
429 if(rb_rawbuf_length(conn
->modbuf_out
) >= 4096)
431 /* if we have over 4k pending outbound, don't read until
432 * we've cleared the queue */
434 rb_setselect(conn
->plain_fd
, RB_SELECT_READ
, NULL
, NULL
);
436 conn_mod_write_sendq(conn
->mod_fd
, conn
);
444 conn_plain_read_cb(rb_fde_t
* fd
, void *data
)
454 if(plain_check_cork(conn
))
462 length
= rb_read(conn
->plain_fd
, inbuf
, sizeof(inbuf
));
464 if(length
== 0 || (length
< 0 && !rb_ignore_errno(errno
)))
466 close_conn(conn
, NO_WAIT
, NULL
);
472 rb_setselect(conn
->plain_fd
, RB_SELECT_READ
, conn_plain_read_cb
, conn
);
473 conn_mod_write_sendq(conn
->mod_fd
, conn
);
476 conn
->plain_in
+= length
;
480 common_zlib_deflate(conn
, inbuf
, length
);
483 conn_mod_write(conn
, inbuf
, length
);
486 if(plain_check_cork(conn
))
492 conn_mod_read_cb(rb_fde_t
* fd
, void *data
)
495 const char *err
= remote_closed
;
507 length
= rb_read(conn
->mod_fd
, inbuf
, sizeof(inbuf
));
509 if(length
== 0 || (length
< 0 && !rb_ignore_errno(errno
)))
512 close_conn(conn
, WAIT_PLAIN
, "%s", remote_closed
);
516 if(IsSSL(conn
) && length
== RB_RW_SSL_ERROR
)
517 err
= rb_get_ssl_strerror(conn
->mod_fd
);
519 err
= strerror(errno
);
520 close_conn(conn
, WAIT_PLAIN
, "Read error: %s", err
);
525 int flags
= RB_SELECT_READ
;
526 if(length
== RB_RW_SSL_NEED_WRITE
)
527 flags
|= RB_SELECT_WRITE
;
529 rb_setselect(conn
->mod_fd
, flags
, conn_mod_read_cb
, conn
);
530 conn_plain_write_sendq(conn
->plain_fd
, conn
);
533 conn
->mod_in
+= length
;
536 common_zlib_inflate(conn
, inbuf
, length
);
539 conn_plain_write(conn
, inbuf
, length
);
544 conn_plain_write_sendq(rb_fde_t
* fd
, void *data
)
552 while ((retlen
= rb_rawbuf_flush(conn
->plainbuf_out
, fd
)) > 0)
554 conn
->plain_out
+= retlen
;
556 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
558 close_conn(data
, NO_WAIT
, NULL
);
563 if(rb_rawbuf_length(conn
->plainbuf_out
) > 0)
564 rb_setselect(conn
->plain_fd
, RB_SELECT_WRITE
, conn_plain_write_sendq
, conn
);
566 rb_setselect(conn
->plain_fd
, RB_SELECT_WRITE
, NULL
, NULL
);
572 #if defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
575 if(!getrlimit(RLIMIT_NOFILE
, &limit
))
577 return limit
.rlim_cur
;
579 #endif /* RLIMIT_FD_MAX */
580 return MAXCONNECTIONS
;
584 ssl_process_accept_cb(rb_fde_t
* F
, int status
, struct sockaddr
*addr
, rb_socklen_t len
, void *data
)
589 conn_mod_read_cb(conn
->mod_fd
, conn
);
590 conn_plain_read_cb(conn
->plain_fd
, conn
);
593 close_conn(conn
, NO_WAIT
, 0);
598 ssl_process_connect_cb(rb_fde_t
* F
, int status
, void *data
)
603 conn_mod_read_cb(conn
->mod_fd
, conn
);
604 conn_plain_read_cb(conn
->plain_fd
, conn
);
607 close_conn(conn
, NO_WAIT
, 0);
613 ssl_process_accept(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
618 conn
= make_conn(ctl
, ctlb
->F
[0], ctlb
->F
[1]);
620 id
= buf_to_int32(&ctlb
->buf
[1]);
623 conn_add_id_hash(conn
, id
);
626 if(rb_get_type(conn
->mod_fd
) & RB_FD_UNKNOWN
)
629 rb_set_type(conn
->mod_fd
, RB_FD_SOCKET
);
631 if(rb_get_type(conn
->mod_fd
) == RB_FD_UNKNOWN
)
632 rb_set_type(conn
->plain_fd
, RB_FD_SOCKET
);
634 rb_ssl_start_accepted(ctlb
->F
[0], ssl_process_accept_cb
, conn
, 10);
638 ssl_process_connect(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
642 conn
= make_conn(ctl
, ctlb
->F
[0], ctlb
->F
[1]);
644 id
= buf_to_int32(&ctlb
->buf
[1]);
647 conn_add_id_hash(conn
, id
);
650 if(rb_get_type(conn
->mod_fd
) == RB_FD_UNKNOWN
)
651 rb_set_type(conn
->mod_fd
, RB_FD_SOCKET
);
653 if(rb_get_type(conn
->mod_fd
) == RB_FD_UNKNOWN
)
654 rb_set_type(conn
->plain_fd
, RB_FD_SOCKET
);
657 rb_ssl_start_connected(ctlb
->F
[0], ssl_process_connect_cb
, conn
, 10);
661 process_stats(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
668 id
= buf_to_int32(&ctlb
->buf
[1]);
673 odata
= &ctlb
->buf
[5];
674 conn
= conn_find_by_id(id
);
679 rb_snprintf(outstat
, sizeof(outstat
), "S %s %llu %llu %llu %llu", odata
,
680 conn
->plain_out
, conn
->mod_in
, conn
->plain_in
, conn
->mod_out
);
685 mod_cmd_write_queue(ctl
, outstat
, strlen(outstat
) + 1); /* +1 is so we send the \0 as well */
690 zlib_send_zip_ready(mod_ctl_t
*ctl
, conn_t
*conn
)
695 int32_to_buf(&buf
[1], conn
->id
);
696 mod_cmd_write_queue(conn
->ctl
, buf
, sizeof(buf
));
700 zlib_process(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
704 size_t hdr
= (sizeof(rb_uint8_t
) * 2) + sizeof(rb_int32_t
);
706 z_stream
*instream
, *outstream
;
710 conn
= make_conn(ctl
, ctlb
->F
[0], ctlb
->F
[1]);
711 if(rb_get_type(conn
->mod_fd
) == RB_FD_UNKNOWN
)
712 rb_set_type(conn
->mod_fd
, RB_FD_SOCKET
);
714 if(rb_get_type(conn
->plain_fd
) == RB_FD_UNKNOWN
)
715 rb_set_type(conn
->plain_fd
, RB_FD_SOCKET
);
717 id
= buf_to_int32(&ctlb
->buf
[1]);
718 conn_add_id_hash(conn
, id
);
720 level
= (rb_uint8_t
) ctlb
->buf
[5];
722 recvqlen
= ctlb
->buflen
- hdr
;
723 recvq_start
= &ctlb
->buf
[6];
726 conn
->stream
= rb_malloc(sizeof(zlib_stream_t
));
727 instream
= &((zlib_stream_t
*)conn
->stream
)->instream
;
728 outstream
= &((zlib_stream_t
*)conn
->stream
)->outstream
;
730 instream
->total_in
= 0;
731 instream
->total_out
= 0;
732 instream
->zalloc
= (alloc_func
) ssld_alloc
;
733 instream
->zfree
= (free_func
) ssld_free
;
734 instream
->data_type
= Z_ASCII
;
735 inflateInit(&((zlib_stream_t
*)conn
->stream
)->instream
);
737 outstream
->total_in
= 0;
738 outstream
->total_out
= 0;
739 outstream
->zalloc
= (alloc_func
) ssld_alloc
;
740 outstream
->zfree
= (free_func
) ssld_free
;
741 outstream
->data_type
= Z_ASCII
;
744 level
= Z_DEFAULT_COMPRESSION
;
746 deflateInit(&((zlib_stream_t
*)conn
->stream
)->outstream
, level
);
748 common_zlib_inflate(conn
, recvq_start
, recvqlen
);
749 zlib_send_zip_ready(ctl
, conn
);
750 conn_mod_read_cb(conn
->mod_fd
, conn
);
751 conn_plain_read_cb(conn
->plain_fd
, conn
);
758 init_prng(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctl_buf
)
761 prng_seed_t seed_type
;
763 seed_type
= (prng_seed_t
)ctl_buf
->buf
[1];
764 path
= &ctl_buf
->buf
[2];
765 rb_init_prng(path
, seed_type
);
770 ssl_new_keys(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctl_buf
)
773 char *cert
, *key
, *dhparam
;
775 buf
= &ctl_buf
->buf
[2];
777 buf
+= strlen(cert
) + 1;
779 buf
+= strlen(key
) + 1;
781 if(strlen(dhparam
) == 0)
784 if(!rb_setup_ssl_server(cert
, key
, dhparam
))
786 const char *invalid
= "I";
787 mod_cmd_write_queue(ctl
, invalid
, strlen(invalid
));
793 send_nossl_support(mod_ctl_t
*ctl
, mod_ctl_buf_t
*ctlb
)
795 static const char *nossl_cmd
= "N";
801 conn
= make_conn(ctl
, ctlb
->F
[0], ctlb
->F
[1]);
802 id
= buf_to_int32(&ctlb
->buf
[1]);
805 conn_add_id_hash(conn
, id
);
806 close_conn(conn
, WAIT_PLAIN
, "libratbox reports no SSL/TLS support");
808 mod_cmd_write_queue(ctl
, nossl_cmd
, strlen(nossl_cmd
));
812 send_i_am_useless(mod_ctl_t
*ctl
)
814 static const char *useless
= "U";
815 mod_cmd_write_queue(ctl
, useless
, strlen(useless
));
819 send_nozlib_support(mod_ctl_t
*ctl
, mod_ctl_buf_t
*ctlb
)
821 static const char *nozlib_cmd
= "z";
826 conn
= make_conn(ctl
, ctlb
->F
[0], ctlb
->F
[1]);
827 id
= buf_to_int32(&ctlb
->buf
[1]);
830 conn_add_id_hash(conn
, id
);
831 close_conn(conn
, WAIT_PLAIN
, "libratbox reports no zlib support");
833 mod_cmd_write_queue(ctl
, nozlib_cmd
, strlen(nozlib_cmd
));
837 mod_process_cmd_recv(mod_ctl_t
* ctl
)
839 rb_dlink_node
*ptr
, *next
;
840 mod_ctl_buf_t
*ctl_buf
;
842 RB_DLINK_FOREACH_SAFE(ptr
, next
, ctl
->readq
.head
)
846 switch (*ctl_buf
->buf
)
852 send_nossl_support(ctl
, ctl_buf
);
855 ssl_process_accept(ctl
, ctl_buf
);
862 send_nossl_support(ctl
, ctl_buf
);
865 ssl_process_connect(ctl
, ctl_buf
);
873 send_nossl_support(ctl
, ctl_buf
);
876 ssl_new_keys(ctl
, ctl_buf
);
880 init_prng(ctl
, ctl_buf
);
884 process_stats(ctl
, ctl_buf
);
891 zlib_process(ctl
, ctl_buf
);
897 send_nozlib_support(ctl
);
903 /* Log unknown commands */
905 rb_dlinkDelete(ptr
, &ctl
->readq
);
906 rb_free(ctl_buf
->buf
);
915 mod_read_ctl(rb_fde_t
* F
, void *data
)
917 mod_ctl_buf_t
*ctl_buf
;
918 mod_ctl_t
*ctl
= data
;
923 ctl_buf
= rb_malloc(sizeof(mod_ctl_buf_t
));
924 ctl_buf
->buf
= rb_malloc(READBUF_SIZE
);
925 ctl_buf
->buflen
= READBUF_SIZE
;
926 retlen
= rb_recv_fd_buf(ctl
->F
, ctl_buf
->buf
, ctl_buf
->buflen
, ctl_buf
->F
,
930 rb_free(ctl_buf
->buf
);
935 ctl_buf
->buflen
= retlen
;
936 rb_dlinkAddTail(ctl_buf
, &ctl_buf
->node
, &ctl
->readq
);
941 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
944 mod_process_cmd_recv(ctl
);
945 rb_setselect(ctl
->F
, RB_SELECT_READ
, mod_read_ctl
, ctl
);
949 mod_write_ctl(rb_fde_t
* F
, void *data
)
951 mod_ctl_t
*ctl
= data
;
952 mod_ctl_buf_t
*ctl_buf
;
953 rb_dlink_node
*ptr
, *next
;
956 RB_DLINK_FOREACH_SAFE(ptr
, next
, ctl
->writeq
.head
)
959 retlen
= rb_send_fd_buf(ctl
->F
, ctl_buf
->F
, ctl_buf
->nfds
, ctl_buf
->buf
,
963 rb_dlinkDelete(ptr
, &ctl
->writeq
);
964 for (x
= 0; x
< ctl_buf
->nfds
; x
++)
965 rb_close(ctl_buf
->F
[x
]);
966 rb_free(ctl_buf
->buf
);
970 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
973 rb_setselect(ctl
->F
, RB_SELECT_WRITE
, mod_write_ctl
, ctl
);
979 read_pipe_ctl(rb_fde_t
* F
, void *data
)
982 while ((retlen
= rb_read(F
, inbuf
, sizeof(inbuf
))) > 0)
984 ;; /* we don't do anything with the pipe really, just care if the other process dies.. */
986 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
988 rb_setselect(F
, RB_SELECT_READ
, read_pipe_ctl
, NULL
);
993 main(int argc
, char **argv
)
995 const char *s_ctlfd
, *s_pipe
;
996 int ctlfd
, pipefd
, x
, maxfd
;
998 s_ctlfd
= getenv("CTL_FD");
999 s_pipe
= getenv("CTL_PIPE");
1001 if(s_ctlfd
== NULL
|| s_pipe
== NULL
)
1003 fprintf(stderr
, "This is ircd-ratbox ssld. You know you aren't supposed to run me directly?\n");
1004 fprintf(stderr
, "You get an Id tag for this: $Id: ssld.c 25179 2008-03-30 16:34:57Z androsyn $\n");
1005 fprintf(stderr
, "Have a nice life\n");
1009 ctlfd
= atoi(s_ctlfd
);
1010 pipefd
= atoi(s_pipe
);
1012 for (x
= 0; x
< maxfd
; x
++)
1014 if(x
!= ctlfd
&& x
!= pipefd
&& x
> 2)
1019 x
= open("/dev/null", O_RDWR
);
1022 if(ctlfd
!= 0 && pipefd
!= 0)
1024 if(ctlfd
!= 1 && pipefd
!= 1)
1026 if(ctlfd
!= 2 && pipefd
!= 2)
1033 rb_lib_init(NULL
, NULL
, NULL
, 0, maxfd
, 1024, 4096);
1034 rb_init_rawbuffers(1024);
1035 ssl_ok
= rb_supports_ssl();
1037 mod_ctl
= rb_malloc(sizeof(mod_ctl_t
));
1038 mod_ctl
->F
= rb_open(ctlfd
, RB_FD_SOCKET
, "ircd control socket");
1039 mod_ctl
->F_pipe
= rb_open(pipefd
, RB_FD_PIPE
, "ircd pipe");
1040 rb_set_nb(mod_ctl
->F
);
1041 rb_set_nb(mod_ctl
->F_pipe
);
1042 rb_event_addish("clean_dead_conns", clean_dead_conns
, NULL
, 10);
1043 read_pipe_ctl(mod_ctl
->F_pipe
, NULL
);
1044 mod_read_ctl(mod_ctl
->F
, mod_ctl
);
1045 if(!zlib_ok
&& !ssl_ok
)
1047 /* this is really useless... */
1048 send_i_am_useless(mod_ctl
);
1049 /* sleep until the ircd kills us */
1055 send_nozlib_support(mod_ctl
, NULL
);
1057 send_nossl_support(mod_ctl
, NULL
);
1065 dummy_handler(int sig
)
1073 struct sigaction act
;
1076 act
.sa_handler
= SIG_IGN
;
1077 sigemptyset(&act
.sa_mask
);
1078 sigaddset(&act
.sa_mask
, SIGPIPE
);
1079 sigaddset(&act
.sa_mask
, SIGALRM
);
1081 sigaddset(&act
.sa_mask
, SIGTRAP
);
1085 sigaddset(&act
.sa_mask
, SIGWINCH
);
1086 sigaction(SIGWINCH
, &act
, 0);
1088 sigaction(SIGPIPE
, &act
, 0);
1090 sigaction(SIGTRAP
, &act
, 0);
1093 act
.sa_handler
= dummy_handler
;
1094 sigaction(SIGALRM
, &act
, 0);