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
27 #define READBUF_SIZE 16384
30 static void setup_signals(void);
33 static inline uint32_t
34 buf_to_uint32(uint8_t *buf
)
37 memcpy(&x
, buf
, sizeof(x
));
42 uint32_to_buf(uint8_t *buf
, uint32_t x
)
44 memcpy(buf
, &x
, sizeof(x
));
48 typedef struct _mod_ctl_buf
53 rb_fde_t
*F
[MAXPASSFD
];
57 typedef struct _mod_ctl
67 static mod_ctl_t
*mod_ctl
;
73 rawbuf_head_t
*modbuf_out
;
74 rawbuf_head_t
*plainbuf_out
;
90 #define FLAG_CORK 0x04
91 #define FLAG_DEAD 0x08
92 #define FLAG_SSL_W_WANTS_R 0x10 /* output needs to wait until input possible */
93 #define FLAG_SSL_R_WANTS_W 0x20 /* input needs to wait until output possible */
94 #define FLAG_ZIPSSL 0x40
96 #define IsSSL(x) ((x)->flags & FLAG_SSL)
97 #define IsZip(x) ((x)->flags & FLAG_ZIP)
98 #define IsCork(x) ((x)->flags & FLAG_CORK)
99 #define IsDead(x) ((x)->flags & FLAG_DEAD)
100 #define IsSSLWWantsR(x) ((x)->flags & FLAG_SSL_W_WANTS_R)
101 #define IsSSLRWantsW(x) ((x)->flags & FLAG_SSL_R_WANTS_W)
102 #define IsZipSSL(x) ((x)->flags & FLAG_ZIPSSL)
104 #define SetSSL(x) ((x)->flags |= FLAG_SSL)
105 #define SetZip(x) ((x)->flags |= FLAG_ZIP)
106 #define SetCork(x) ((x)->flags |= FLAG_CORK)
107 #define SetDead(x) ((x)->flags |= FLAG_DEAD)
108 #define SetSSLWWantsR(x) ((x)->flags |= FLAG_SSL_W_WANTS_R)
109 #define SetSSLRWantsW(x) ((x)->flags |= FLAG_SSL_R_WANTS_W)
111 #define ClearCork(x) ((x)->flags &= ~FLAG_CORK)
112 #define ClearSSLWWantsR(x) ((x)->flags &= ~FLAG_SSL_W_WANTS_R)
113 #define ClearSSLRWantsW(x) ((x)->flags &= ~FLAG_SSL_R_WANTS_W)
116 #define WAIT_PLAIN 0x1
118 #define HASH_WALK_SAFE(i, max, ptr, next, table) for(i = 0; i < max; i++) { RB_DLINK_FOREACH_SAFE(ptr, next, table[i].head)
119 #define HASH_WALK_END }
120 #define CONN_HASH_SIZE 2000
121 #define connid_hash(x) (&connid_hash_table[(x % CONN_HASH_SIZE)])
125 static rb_dlink_list connid_hash_table
[CONN_HASH_SIZE
];
126 static rb_dlink_list dead_list
;
128 static void conn_mod_read_cb(rb_fde_t
*fd
, void *data
);
129 static void conn_mod_write_sendq(rb_fde_t
*, void *data
);
130 static void conn_plain_write_sendq(rb_fde_t
*, void *data
);
131 static void mod_write_ctl(rb_fde_t
*, void *data
);
132 static void conn_plain_read_cb(rb_fde_t
*fd
, void *data
);
133 static void conn_plain_read_shutdown_cb(rb_fde_t
*fd
, void *data
);
134 static void mod_cmd_write_queue(mod_ctl_t
* ctl
, const void *data
, size_t len
);
135 static const char *remote_closed
= "Remote host closed the connection";
136 static bool ssld_ssl_ok
;
137 static int certfp_method
= RB_SSL_CERTFP_METH_CERT_SHA1
;
141 conn_find_by_id(uint32_t id
)
146 RB_DLINK_FOREACH(ptr
, (connid_hash(id
))->head
)
149 if(conn
->id
== id
&& !IsDead(conn
))
156 conn_add_id_hash(conn_t
* conn
, uint32_t id
)
159 rb_dlinkAdd(conn
, &conn
->node
, connid_hash(id
));
163 free_conn(conn_t
* conn
)
165 rb_free_rawbuffer(conn
->modbuf_out
);
166 rb_free_rawbuffer(conn
->plainbuf_out
);
171 clean_dead_conns(void *unused
)
174 rb_dlink_node
*ptr
, *next
;
175 RB_DLINK_FOREACH_SAFE(ptr
, next
, dead_list
.head
)
180 dead_list
.tail
= dead_list
.head
= NULL
;
185 close_conn(conn_t
* conn
, int wait_plain
, const char *fmt
, ...)
188 char reason
[128]; /* must always be under 250 bytes */
194 rb_rawbuf_flush(conn
->modbuf_out
, conn
->mod_fd
);
195 rb_rawbuf_flush(conn
->plainbuf_out
, conn
->plain_fd
);
196 rb_close(conn
->mod_fd
);
200 rb_dlinkDelete(&conn
->node
, connid_hash(conn
->id
));
202 if(!wait_plain
|| fmt
== NULL
)
204 rb_close(conn
->plain_fd
);
205 rb_dlinkAdd(conn
, &conn
->node
, &dead_list
);
208 rb_setselect(conn
->plain_fd
, RB_SELECT_READ
, conn_plain_read_shutdown_cb
, conn
);
209 rb_setselect(conn
->plain_fd
, RB_SELECT_WRITE
, NULL
, NULL
);
211 vsnprintf(reason
, sizeof(reason
), fmt
, ap
);
215 uint32_to_buf(&buf
[1], conn
->id
);
216 rb_strlcpy((char *) &buf
[5], reason
, sizeof(buf
) - 5);
217 len
= (strlen(reason
) + 1) + 5;
218 mod_cmd_write_queue(conn
->ctl
, buf
, len
);
222 make_conn(mod_ctl_t
* ctl
, rb_fde_t
*mod_fd
, rb_fde_t
*plain_fd
)
224 conn_t
*conn
= rb_malloc(sizeof(conn_t
));
226 conn
->modbuf_out
= rb_new_rawbuffer();
227 conn
->plainbuf_out
= rb_new_rawbuffer();
228 conn
->mod_fd
= mod_fd
;
229 conn
->plain_fd
= plain_fd
;
238 check_handshake_flood(void *unused
)
241 rb_dlink_node
*ptr
, *next
;
244 HASH_WALK_SAFE(i
, CONN_HASH_SIZE
, ptr
, next
, connid_hash_table
)
250 count
= rb_ssl_handshake_count(conn
->mod_fd
);
251 /* nothing needs to do this more than twice in ten seconds i don't think */
253 close_conn(conn
, WAIT_PLAIN
, "Handshake flooding");
255 rb_ssl_clear_handshake_count(conn
->mod_fd
);
260 conn_mod_write_sendq(rb_fde_t
*fd
, void *data
)
268 if(IsSSLWWantsR(conn
))
270 ClearSSLWWantsR(conn
);
271 conn_mod_read_cb(conn
->mod_fd
, conn
);
276 while((retlen
= rb_rawbuf_flush(conn
->modbuf_out
, fd
)) > 0)
277 conn
->mod_out
+= retlen
;
279 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
282 close_conn(conn
, WAIT_PLAIN
, "%s", remote_closed
);
283 if(IsSSL(conn
) && retlen
== RB_RW_SSL_ERROR
)
284 err
= rb_get_ssl_strerror(conn
->mod_fd
);
286 err
= strerror(errno
);
287 close_conn(conn
, WAIT_PLAIN
, "Write error: %s", err
);
290 if(rb_rawbuf_length(conn
->modbuf_out
) > 0)
292 if(retlen
!= RB_RW_SSL_NEED_READ
)
293 rb_setselect(conn
->mod_fd
, RB_SELECT_WRITE
, conn_mod_write_sendq
, conn
);
296 rb_setselect(conn
->mod_fd
, RB_SELECT_READ
, conn_mod_write_sendq
, conn
);
297 rb_setselect(conn
->mod_fd
, RB_SELECT_WRITE
, NULL
, NULL
);
302 rb_setselect(conn
->mod_fd
, RB_SELECT_WRITE
, NULL
, NULL
);
304 if(IsCork(conn
) && rb_rawbuf_length(conn
->modbuf_out
) == 0)
307 conn_plain_read_cb(conn
->plain_fd
, conn
);
313 conn_mod_write(conn_t
* conn
, void *data
, size_t len
)
315 if(IsDead(conn
)) /* no point in queueing to a dead man */
317 rb_rawbuf_append(conn
->modbuf_out
, data
, len
);
321 conn_plain_write(conn_t
* conn
, void *data
, size_t len
)
323 if(IsDead(conn
)) /* again no point in queueing to dead men */
325 rb_rawbuf_append(conn
->plainbuf_out
, data
, len
);
329 mod_cmd_write_queue(mod_ctl_t
* ctl
, const void *data
, size_t len
)
331 mod_ctl_buf_t
*ctl_buf
;
332 ctl_buf
= rb_malloc(sizeof(mod_ctl_buf_t
));
333 ctl_buf
->buf
= rb_malloc(len
);
334 ctl_buf
->buflen
= len
;
335 memcpy(ctl_buf
->buf
, data
, len
);
337 rb_dlinkAddTail(ctl_buf
, &ctl_buf
->node
, &ctl
->writeq
);
338 mod_write_ctl(ctl
->F
, ctl
);
342 plain_check_cork(conn_t
* conn
)
344 if(rb_rawbuf_length(conn
->modbuf_out
) >= 4096)
346 /* if we have over 4k pending outbound, don't read until
347 * we've cleared the queue */
349 rb_setselect(conn
->plain_fd
, RB_SELECT_READ
, NULL
, NULL
);
351 conn_mod_write_sendq(conn
->mod_fd
, conn
);
359 conn_plain_read_cb(rb_fde_t
*fd
, void *data
)
361 char inbuf
[READBUF_SIZE
];
370 if(plain_check_cork(conn
))
378 length
= rb_read(conn
->plain_fd
, inbuf
, sizeof(inbuf
));
380 if(length
== 0 || (length
< 0 && !rb_ignore_errno(errno
)))
382 close_conn(conn
, NO_WAIT
, NULL
);
388 rb_setselect(conn
->plain_fd
, RB_SELECT_READ
, conn_plain_read_cb
, conn
);
389 conn_mod_write_sendq(conn
->mod_fd
, conn
);
392 conn
->plain_in
+= length
;
394 conn_mod_write(conn
, inbuf
, length
);
397 if(plain_check_cork(conn
))
403 conn_plain_read_shutdown_cb(rb_fde_t
*fd
, void *data
)
405 char inbuf
[READBUF_SIZE
];
414 length
= rb_read(conn
->plain_fd
, inbuf
, sizeof(inbuf
));
416 if(length
== 0 || (length
< 0 && !rb_ignore_errno(errno
)))
418 rb_close(conn
->plain_fd
);
419 rb_dlinkAdd(conn
, &conn
->node
, &dead_list
);
425 rb_setselect(conn
->plain_fd
, RB_SELECT_READ
, conn_plain_read_shutdown_cb
, conn
);
432 conn_mod_read_cb(rb_fde_t
*fd
, void *data
)
434 char inbuf
[READBUF_SIZE
];
442 if(IsSSLRWantsW(conn
))
444 ClearSSLRWantsW(conn
);
445 conn_mod_write_sendq(conn
->mod_fd
, conn
);
455 length
= rb_read(conn
->mod_fd
, inbuf
, sizeof(inbuf
));
457 if(length
== 0 || (length
< 0 && !rb_ignore_errno(errno
)))
461 close_conn(conn
, WAIT_PLAIN
, "%s", remote_closed
);
466 if(IsSSL(conn
) && length
== RB_RW_SSL_ERROR
)
467 err
= rb_get_ssl_strerror(conn
->mod_fd
);
469 err
= strerror(errno
);
470 close_conn(conn
, WAIT_PLAIN
, "Read error: %s", err
);
475 if(length
!= RB_RW_SSL_NEED_WRITE
)
476 rb_setselect(conn
->mod_fd
, RB_SELECT_READ
, conn_mod_read_cb
, conn
);
479 rb_setselect(conn
->mod_fd
, RB_SELECT_READ
, NULL
, NULL
);
480 rb_setselect(conn
->mod_fd
, RB_SELECT_WRITE
, conn_mod_read_cb
, conn
);
483 conn_plain_write_sendq(conn
->plain_fd
, conn
);
486 conn
->mod_in
+= length
;
487 conn_plain_write(conn
, inbuf
, length
);
492 conn_plain_write_sendq(rb_fde_t
*fd
, void *data
)
500 while((retlen
= rb_rawbuf_flush(conn
->plainbuf_out
, fd
)) > 0)
502 conn
->plain_out
+= retlen
;
504 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
506 close_conn(data
, NO_WAIT
, NULL
);
511 if(rb_rawbuf_length(conn
->plainbuf_out
) > 0)
512 rb_setselect(conn
->plain_fd
, RB_SELECT_WRITE
, conn_plain_write_sendq
, conn
);
514 rb_setselect(conn
->plain_fd
, RB_SELECT_WRITE
, NULL
, NULL
);
522 if(!getrlimit(RLIMIT_NOFILE
, &limit
))
524 return limit
.rlim_cur
;
526 return MAXCONNECTIONS
;
530 ssl_send_cipher(conn_t
*conn
)
539 p
= rb_ssl_get_cipher(conn
->mod_fd
);
544 rb_strlcpy(cstring
, p
, sizeof(cstring
));
547 uint32_to_buf(&buf
[1], conn
->id
);
548 strcpy((char *) &buf
[5], cstring
);
549 len
= (strlen(cstring
) + 1) + 5;
550 mod_cmd_write_queue(conn
->ctl
, buf
, len
);
554 ssl_send_certfp(conn_t
*conn
)
556 uint8_t buf
[13 + RB_SSL_CERTFP_LEN
];
558 int len
= rb_get_ssl_certfp(conn
->mod_fd
, &buf
[13], certfp_method
);
562 lrb_assert(len
<= RB_SSL_CERTFP_LEN
);
564 uint32_to_buf(&buf
[1], conn
->id
);
565 uint32_to_buf(&buf
[5], certfp_method
);
566 uint32_to_buf(&buf
[9], len
);
567 mod_cmd_write_queue(conn
->ctl
, buf
, 13 + len
);
571 ssl_send_open(conn_t
*conn
)
576 uint32_to_buf(&buf
[1], conn
->id
);
577 mod_cmd_write_queue(conn
->ctl
, buf
, 5);
581 ssl_process_accept_cb(rb_fde_t
*F
, int status
, struct sockaddr
*addr
, rb_socklen_t len
, void *data
)
587 ssl_send_cipher(conn
);
588 ssl_send_certfp(conn
);
590 conn_mod_read_cb(conn
->mod_fd
, conn
);
591 conn_plain_read_cb(conn
->plain_fd
, conn
);
594 /* ircd doesn't care about the reason for this */
595 close_conn(conn
, NO_WAIT
, 0);
600 ssl_process_connect_cb(rb_fde_t
*F
, int status
, void *data
)
606 ssl_send_cipher(conn
);
607 ssl_send_certfp(conn
);
609 conn_mod_read_cb(conn
->mod_fd
, conn
);
610 conn_plain_read_cb(conn
->plain_fd
, conn
);
612 else if(status
== RB_ERR_TIMEOUT
)
613 close_conn(conn
, WAIT_PLAIN
, "SSL handshake timed out");
614 else if(status
== RB_ERROR_SSL
)
615 close_conn(conn
, WAIT_PLAIN
, "%s", rb_get_ssl_strerror(conn
->mod_fd
));
617 close_conn(conn
, WAIT_PLAIN
, "SSL handshake failed");
622 cleanup_bad_message(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
626 /* XXX should log this somehow */
627 for (i
= 0; i
< ctlb
->nfds
; i
++)
628 rb_close(ctlb
->F
[i
]);
632 ssl_process_accept(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
637 conn
= make_conn(ctl
, ctlb
->F
[0], ctlb
->F
[1]);
639 id
= buf_to_uint32(&ctlb
->buf
[1]);
640 conn_add_id_hash(conn
, id
);
643 if(rb_get_type(conn
->mod_fd
) & RB_FD_UNKNOWN
)
644 rb_set_type(conn
->mod_fd
, RB_FD_SOCKET
);
646 if(rb_get_type(conn
->plain_fd
) == RB_FD_UNKNOWN
)
647 rb_set_type(conn
->plain_fd
, RB_FD_SOCKET
);
649 rb_ssl_start_accepted(ctlb
->F
[0], ssl_process_accept_cb
, conn
, 10);
653 ssl_change_certfp_method(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
655 certfp_method
= buf_to_uint32(&ctlb
->buf
[1]);
659 ssl_process_connect(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
663 conn
= make_conn(ctl
, ctlb
->F
[0], ctlb
->F
[1]);
665 id
= buf_to_uint32(&ctlb
->buf
[1]);
666 conn_add_id_hash(conn
, id
);
669 if(rb_get_type(conn
->mod_fd
) == RB_FD_UNKNOWN
)
670 rb_set_type(conn
->mod_fd
, RB_FD_SOCKET
);
672 if(rb_get_type(conn
->plain_fd
) == RB_FD_UNKNOWN
)
673 rb_set_type(conn
->plain_fd
, RB_FD_SOCKET
);
676 rb_ssl_start_connected(ctlb
->F
[0], ssl_process_connect_cb
, conn
, 10);
680 process_stats(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
687 id
= buf_to_uint32(&ctlb
->buf
[1]);
689 odata
= &ctlb
->buf
[5];
690 conn
= conn_find_by_id(id
);
695 snprintf(outstat
, sizeof(outstat
), "S %s %llu %llu %llu %llu", odata
,
696 (unsigned long long)conn
->plain_out
,
697 (unsigned long long)conn
->mod_in
,
698 (unsigned long long)conn
->plain_in
,
699 (unsigned long long)conn
->mod_out
);
704 mod_cmd_write_queue(ctl
, outstat
, strlen(outstat
) + 1); /* +1 is so we send the \0 as well */
708 ssl_new_keys(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctl_buf
)
711 char *cert
, *key
, *dhparam
, *cipher_list
;
713 buf
= (char *) &ctl_buf
->buf
[2];
715 buf
+= strlen(cert
) + 1;
717 buf
+= strlen(key
) + 1;
719 buf
+= strlen(dhparam
) + 1;
723 if(strlen(dhparam
) == 0)
725 if(strlen(cipher_list
) == 0)
728 if(!rb_setup_ssl_server(cert
, key
, dhparam
, cipher_list
))
730 const char *invalid
= "I";
731 mod_cmd_write_queue(ctl
, invalid
, strlen(invalid
));
737 send_nossl_support(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
739 static const char *nossl_cmd
= "N";
745 conn
= make_conn(ctl
, ctlb
->F
[0], ctlb
->F
[1]);
746 id
= buf_to_uint32(&ctlb
->buf
[1]);
747 conn_add_id_hash(conn
, id
);
748 close_conn(conn
, WAIT_PLAIN
, "libratbox reports no SSL/TLS support");
750 mod_cmd_write_queue(ctl
, nossl_cmd
, strlen(nossl_cmd
));
754 send_i_am_useless(mod_ctl_t
* ctl
)
756 static const char *useless
= "U";
757 mod_cmd_write_queue(ctl
, useless
, strlen(useless
));
761 send_version(mod_ctl_t
* ctl
)
763 char version
[256] = { 'V', 0 };
764 strncpy(&version
[1], rb_lib_version(), sizeof(version
) - 2);
765 mod_cmd_write_queue(ctl
, version
, strlen(version
));
769 send_nozlib_support(mod_ctl_t
* ctl
, mod_ctl_buf_t
* ctlb
)
771 static const char *nozlib_cmd
= "z";
776 conn
= make_conn(ctl
, ctlb
->F
[0], ctlb
->F
[1]);
777 id
= buf_to_uint32(&ctlb
->buf
[1]);
778 conn_add_id_hash(conn
, id
);
779 close_conn(conn
, WAIT_PLAIN
, "libratbox reports no zlib support");
781 mod_cmd_write_queue(ctl
, nozlib_cmd
, strlen(nozlib_cmd
));
785 mod_process_cmd_recv(mod_ctl_t
* ctl
)
787 rb_dlink_node
*ptr
, *next
;
788 mod_ctl_buf_t
*ctl_buf
;
790 RB_DLINK_FOREACH_SAFE(ptr
, next
, ctl
->readq
.head
)
794 switch (*ctl_buf
->buf
)
798 if (ctl_buf
->nfds
!= 2 || ctl_buf
->buflen
!= 5)
800 cleanup_bad_message(ctl
, ctl_buf
);
806 send_nossl_support(ctl
, ctl_buf
);
809 ssl_process_accept(ctl
, ctl_buf
);
814 if (ctl_buf
->buflen
!= 5)
816 cleanup_bad_message(ctl
, ctl_buf
);
822 send_nossl_support(ctl
, ctl_buf
);
825 ssl_process_connect(ctl
, ctl_buf
);
830 if (ctl_buf
->buflen
!= 5)
832 cleanup_bad_message(ctl
, ctl_buf
);
835 ssl_change_certfp_method(ctl
, ctl_buf
);
842 send_nossl_support(ctl
, ctl_buf
);
845 ssl_new_keys(ctl
, ctl_buf
);
850 process_stats(ctl
, ctl_buf
);
855 send_nozlib_support(ctl
, ctl_buf
);
860 /* Log unknown commands */
862 rb_dlinkDelete(ptr
, &ctl
->readq
);
863 rb_free(ctl_buf
->buf
);
872 mod_read_ctl(rb_fde_t
*F
, void *data
)
874 mod_ctl_buf_t
*ctl_buf
;
875 mod_ctl_t
*ctl
= data
;
881 ctl_buf
= rb_malloc(sizeof(mod_ctl_buf_t
));
882 ctl_buf
->buf
= rb_malloc(READBUF_SIZE
);
883 ctl_buf
->buflen
= READBUF_SIZE
;
884 retlen
= rb_recv_fd_buf(ctl
->F
, ctl_buf
->buf
, ctl_buf
->buflen
, ctl_buf
->F
,
888 rb_free(ctl_buf
->buf
);
893 ctl_buf
->buflen
= retlen
;
894 rb_dlinkAddTail(ctl_buf
, &ctl_buf
->node
, &ctl
->readq
);
895 for (i
= 0; i
< MAXPASSFD
&& ctl_buf
->F
[i
] != NULL
; i
++)
902 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
905 mod_process_cmd_recv(ctl
);
906 rb_setselect(ctl
->F
, RB_SELECT_READ
, mod_read_ctl
, ctl
);
910 mod_write_ctl(rb_fde_t
*F
, void *data
)
912 mod_ctl_t
*ctl
= data
;
913 mod_ctl_buf_t
*ctl_buf
;
914 rb_dlink_node
*ptr
, *next
;
917 RB_DLINK_FOREACH_SAFE(ptr
, next
, ctl
->writeq
.head
)
920 retlen
= rb_send_fd_buf(ctl
->F
, ctl_buf
->F
, ctl_buf
->nfds
, ctl_buf
->buf
,
921 ctl_buf
->buflen
, ppid
);
924 rb_dlinkDelete(ptr
, &ctl
->writeq
);
925 for(x
= 0; x
< ctl_buf
->nfds
; x
++)
926 rb_close(ctl_buf
->F
[x
]);
927 rb_free(ctl_buf
->buf
);
931 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
935 if(rb_dlink_list_length(&ctl
->writeq
) > 0)
936 rb_setselect(ctl
->F
, RB_SELECT_WRITE
, mod_write_ctl
, ctl
);
941 read_pipe_ctl(rb_fde_t
*F
, void *data
)
943 char inbuf
[READBUF_SIZE
];
945 while((retlen
= rb_read(F
, inbuf
, sizeof(inbuf
))) > 0)
947 ;; /* we don't do anything with the pipe really, just care if the other process dies.. */
949 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
951 rb_setselect(F
, RB_SELECT_READ
, read_pipe_ctl
, NULL
);
956 main(int argc
, char **argv
)
958 const char *s_ctlfd
, *s_pipe
, *s_pid
;
959 int ctlfd
, pipefd
, maxfd
, x
;
962 s_ctlfd
= getenv("CTL_FD");
963 s_pipe
= getenv("CTL_PIPE");
964 s_pid
= getenv("CTL_PPID");
966 if(s_ctlfd
== NULL
|| s_pipe
== NULL
|| s_pid
== NULL
)
969 "This is the solanum ssld for internal ircd use.\n");
971 "You aren't supposed to run me directly. Exiting.\n");
975 ctlfd
= atoi(s_ctlfd
);
976 pipefd
= atoi(s_pipe
);
979 for(x
= 3; x
< maxfd
; x
++)
981 if(x
!= ctlfd
&& x
!= pipefd
)
985 x
= open("/dev/null", O_RDWR
);
989 if(ctlfd
!= 0 && pipefd
!= 0)
991 if(ctlfd
!= 1 && pipefd
!= 1)
993 if(ctlfd
!= 2 && pipefd
!= 2)
1000 rb_lib_init(NULL
, NULL
, NULL
, 0, maxfd
, 1024, 4096);
1001 rb_init_rawbuffers(1024);
1002 rb_init_prng(NULL
, RB_PRNG_DEFAULT
);
1003 ssld_ssl_ok
= rb_supports_ssl();
1004 mod_ctl
= rb_malloc(sizeof(mod_ctl_t
));
1005 mod_ctl
->F
= rb_open(ctlfd
, RB_FD_SOCKET
, "ircd control socket");
1006 mod_ctl
->F_pipe
= rb_open(pipefd
, RB_FD_PIPE
, "ircd pipe");
1007 rb_set_nb(mod_ctl
->F
);
1008 rb_set_nb(mod_ctl
->F_pipe
);
1009 rb_event_addish("clean_dead_conns", clean_dead_conns
, NULL
, 10);
1010 rb_event_add("check_handshake_flood", check_handshake_flood
, NULL
, 10);
1011 read_pipe_ctl(mod_ctl
->F_pipe
, NULL
);
1012 mod_read_ctl(mod_ctl
->F
, mod_ctl
);
1013 send_version(mod_ctl
);
1016 /* this is really useless... */
1017 send_i_am_useless(mod_ctl
);
1018 /* sleep until the ircd kills us */
1019 rb_sleep(1 << 30, 0);
1023 send_nozlib_support(mod_ctl
, NULL
);
1025 send_nossl_support(mod_ctl
, NULL
);
1032 dummy_handler(int sig
)
1040 struct sigaction act
;
1043 act
.sa_handler
= SIG_IGN
;
1044 sigemptyset(&act
.sa_mask
);
1045 sigaddset(&act
.sa_mask
, SIGPIPE
);
1046 sigaddset(&act
.sa_mask
, SIGALRM
);
1048 sigaddset(&act
.sa_mask
, SIGTRAP
);
1052 sigaddset(&act
.sa_mask
, SIGWINCH
);
1053 sigaction(SIGWINCH
, &act
, 0);
1055 sigaction(SIGPIPE
, &act
, 0);
1057 sigaction(SIGTRAP
, &act
, 0);
1060 act
.sa_handler
= dummy_handler
;
1061 sigaction(SIGALRM
, &act
, 0);