]> jfr.im git - irc/rqf/shadowircd.git/blob - src/sslproc.c
4f9af8bb3e2213fb1ee9e2365bca36ce8a7162f3
[irc/rqf/shadowircd.git] / src / sslproc.c
1 /*
2 * sslproc.c: An interface to ssld
3 * Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
4 * Copyright (C) 2007 ircd-ratbox development team
5 *
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.
10 *
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.
15 *
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
19 * USA
20 *
21 * $Id: sslproc.c 25677 2008-07-06 04:21:42Z androsyn $
22 */
23
24 #include <ratbox_lib.h>
25 #include "stdinc.h"
26 #include "s_conf.h"
27 #include "logger.h"
28 #include "listener.h"
29 #include "sslproc.h"
30 #include "s_serv.h"
31 #include "ircd.h"
32 #include "hash.h"
33 #include "client.h"
34 #include "send.h"
35 #include "packet.h"
36
37 #define ZIPSTATS_TIME 60
38
39 static void collect_zipstats(void *unused);
40 static void ssl_read_ctl(rb_fde_t *F, void *data);
41 static int ssld_count;
42
43 static char tmpbuf[READBUF_SIZE];
44 static char nul = '\0';
45
46 #define MAXPASSFD 4
47 #define READSIZE 1024
48 typedef struct _ssl_ctl_buf
49 {
50 rb_dlink_node node;
51 char *buf;
52 size_t buflen;
53 rb_fde_t *F[MAXPASSFD];
54 int nfds;
55 } ssl_ctl_buf_t;
56
57
58 struct _ssl_ctl
59 {
60 rb_dlink_node node;
61 int cli_count;
62 rb_fde_t *F;
63 rb_fde_t *P;
64 pid_t pid;
65 rb_dlink_list readq;
66 rb_dlink_list writeq;
67 uint8_t dead;
68 };
69
70 static void send_new_ssl_certs_one(ssl_ctl_t *ctl, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params);
71 static void send_init_prng(ssl_ctl_t *ctl, prng_seed_t seedtype, const char *path);
72
73
74 static rb_dlink_list ssl_daemons;
75
76 static inline int32_t buf_to_int32(char *buf)
77 {
78 int32_t x;
79 memcpy(&x, buf, sizeof(x));
80 return x;
81 }
82
83 static inline void int32_to_buf(char *buf, int32_t x)
84 {
85 memcpy(buf, &x, sizeof(x));
86 return;
87 }
88
89
90 static inline uint16_t buf_to_uint16(char *buf)
91 {
92 uint16_t x;
93 memcpy(&x, buf, sizeof(x));
94 return x;
95 }
96
97 static inline void uint16_to_buf(char *buf, uint16_t x)
98 {
99 memcpy(buf, &x, sizeof(x));
100 return;
101 }
102
103
104 static ssl_ctl_t *
105 allocate_ssl_daemon(rb_fde_t *F, rb_fde_t *P, int pid)
106 {
107 ssl_ctl_t *ctl;
108
109 if(F == NULL || pid < 0)
110 return NULL;
111 ctl = rb_malloc(sizeof(ssl_ctl_t));
112 ctl->F = F;
113 ctl->P = P;
114 ctl->pid = pid;
115 ssld_count++;
116 rb_dlinkAdd(ctl, &ctl->node, &ssl_daemons);
117 return ctl;
118 }
119
120 static void
121 free_ssl_daemon(ssl_ctl_t *ctl)
122 {
123 rb_dlink_node *ptr;
124 ssl_ctl_buf_t *ctl_buf;
125 int x;
126 if(ctl->cli_count)
127 return;
128
129 RB_DLINK_FOREACH(ptr, ctl->readq.head)
130 {
131 ctl_buf = ptr->data;
132 for(x = 0; x < ctl_buf->nfds; x++)
133 rb_close(ctl_buf->F[x]);
134
135 rb_free(ctl_buf->buf);
136 rb_free(ctl_buf);
137 }
138
139 RB_DLINK_FOREACH(ptr, ctl->writeq.head)
140 {
141 ctl_buf = ptr->data;
142 for(x = 0; x < ctl_buf->nfds; x++)
143 rb_close(ctl_buf->F[x]);
144
145 rb_free(ctl_buf->buf);
146 rb_free(ctl_buf);
147 }
148 rb_close(ctl->F);
149 rb_close(ctl->P);
150 rb_dlinkDelete(&ctl->node, &ssl_daemons);
151 rb_free(ctl);
152 }
153
154 static char *ssld_path;
155
156 static int ssld_spin_count = 0;
157 static time_t last_spin;
158 static int ssld_wait = 0;
159
160
161 static void
162 ssl_killall(void)
163 {
164 rb_dlink_node *ptr, *next;
165 ssl_ctl_t *ctl;
166 RB_DLINK_FOREACH_SAFE(ptr, next, ssl_daemons.head)
167 {
168 ctl = ptr->data;
169 if(ctl->dead)
170 continue;
171 ctl->dead = 1;
172 ssld_count--;
173 kill(ctl->pid, SIGKILL);
174 }
175 }
176
177 static void
178 ssl_dead(ssl_ctl_t *ctl)
179 {
180 if(ctl->dead)
181 return;
182
183 ctl->dead = 1;
184 ssld_count--;
185 kill(ctl->pid, SIGKILL); /* make sure the process is really gone */
186 ilog(L_MAIN, "ssld helper died - attempting to restart");
187 sendto_realops_snomask(SNO_GENERAL, L_ALL, "ssld helper died - attempting to restart");
188 start_ssldaemon(1, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params);
189 }
190
191 static void
192 ssl_do_pipe(rb_fde_t *F, void *data)
193 {
194 int retlen;
195 ssl_ctl_t *ctl = data;
196 retlen = rb_write(F, "0", 1);
197 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
198 {
199 ssl_dead(ctl);
200 return;
201 }
202 rb_setselect(F, RB_SELECT_READ, ssl_do_pipe, data);
203 }
204
205 static void
206 restart_ssld_event(void *unused)
207 {
208 ssld_spin_count = 0;
209 last_spin = 0;
210 ssld_wait = 0;
211 if(ServerInfo.ssld_count > get_ssld_count())
212 {
213 int start = ServerInfo.ssld_count - get_ssld_count();
214 ilog(L_MAIN, "Attempting to restart ssld processes");
215 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Attempt to restart ssld processes");
216 start_ssldaemon(start, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params);
217 }
218 }
219
220 int
221 start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params)
222 {
223 rb_fde_t *F1, *F2;
224 rb_fde_t *P1, *P2;
225 char fullpath[PATH_MAX + 1];
226 char fdarg[6];
227 const char *parv[2];
228 char buf[128];
229 pid_t pid;
230 int started = 0, i;
231
232 if(ssld_wait)
233 return 0;
234
235 if(ssld_spin_count > 20 && (rb_current_time() - last_spin < 5))
236 {
237 ilog(L_MAIN, "ssld helper is spinning - will attempt to restart in 1 minute");
238 sendto_realops_snomask(SNO_GENERAL, L_ALL, "ssld helper is spinning - will attempt to restart in 1 minute");
239 rb_event_add("restart_ssld_event", restart_ssld_event, NULL, 60);
240 ssld_wait = 1;
241 return 0;
242 }
243
244 ssld_spin_count++;
245 last_spin = rb_current_time();
246 if(ssld_path == NULL)
247 {
248 rb_snprintf(fullpath, sizeof(fullpath), "%s/ssld", BINPATH);
249
250 if(access(fullpath, X_OK) == -1)
251 {
252 rb_snprintf(fullpath, sizeof(fullpath), "%s/bin/ssld", ConfigFileEntry.dpath);
253 if(access(fullpath, X_OK) == -1)
254 {
255 ilog(L_MAIN, "Unable to execute ssld in %s/bin or %s", ConfigFileEntry.dpath, BINPATH);
256 return 0 ;
257 }
258 }
259 ssld_path = rb_strdup(fullpath);
260 }
261
262 rb_strlcpy(buf, "-ircd ssld daemon helper", sizeof(buf));
263 parv[0] = buf;
264 parv[1] = NULL;
265
266 for(i = 0; i < count; i++)
267 {
268 ssl_ctl_t *ctl;
269 rb_socketpair(AF_UNIX, SOCK_DGRAM, 0, &F1, &F2, "SSL/TLS handle passing socket");
270 rb_set_buffers(F1, READBUF_SIZE);
271 rb_set_buffers(F2, READBUF_SIZE);
272 rb_snprintf(fdarg, sizeof(fdarg), "%d", rb_get_fd(F2));
273 setenv("CTL_FD", fdarg, 1);
274 rb_pipe(&P1, &P2, "SSL/TLS pipe");
275 rb_snprintf(fdarg, sizeof(fdarg), "%d", rb_get_fd(P1));
276 setenv("CTL_PIPE", fdarg, 1);
277
278 pid = rb_spawn_process(ssld_path, (const char **)parv);
279 if(pid == -1)
280 {
281 ilog(L_MAIN, "Unable to create ssld: %s\n", strerror(errno));
282 rb_close(F1);
283 rb_close(F2);
284 rb_close(P1);
285 rb_close(P2);
286 return started;
287 }
288 started++;
289 rb_close(F2);
290 rb_close(P1);
291 ctl = allocate_ssl_daemon(F1, P2, pid);
292 if(ssl_ok)
293 {
294 if(ConfigFileEntry.use_egd && (ConfigFileEntry.egdpool_path != NULL))
295 send_init_prng(ctl, RB_PRNG_EGD, ConfigFileEntry.egdpool_path);
296 else
297 send_init_prng(ctl, RB_PRNG_DEFAULT, NULL);
298 }
299 if(ssl_ok && ssl_cert != NULL && ssl_private_key != NULL)
300 send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params != NULL ? ssl_dh_params : "");
301 ssl_read_ctl(ctl->F, ctl);
302 ssl_do_pipe(P2, ctl);
303 }
304 return started;
305 }
306
307 static void
308 ssl_process_zipstats(ssl_ctl_t *ctl, ssl_ctl_buf_t *ctl_buf)
309 {
310 struct Client *server;
311 struct ZipStats *zips;
312 int parc;
313 char *parv[6];
314 parc = rb_string_to_array(ctl_buf->buf, parv, 6);
315 server = find_server(NULL, parv[1]);
316 if(server == NULL || server->localClient == NULL || !IsCapable(server, CAP_ZIP))
317 return;
318 if(server->localClient->zipstats == NULL)
319 server->localClient->zipstats = rb_malloc(sizeof(struct ZipStats));
320
321 zips = server->localClient->zipstats;
322
323 zips->in += strtoull(parv[2], NULL, 10);
324 zips->in_wire += strtoull(parv[3], NULL, 10);
325 zips->out += strtoull(parv[4], NULL, 10);
326 zips->out_wire += strtoull(parv[5], NULL, 10);
327
328 if(zips->in > 0)
329 zips->in_ratio = ((double)(zips->in - zips->in_wire) / (double) zips->in) * 100.00;
330 else
331 zips->in_ratio = 0;
332
333 if(zips->out > 0)
334 zips->out_ratio = ((double)(zips->out - zips->out_wire) / (double) zips->out) * 100.00;
335 else
336 zips->out_ratio = 0;
337 }
338
339 static void
340 ssl_process_dead_fd(ssl_ctl_t *ctl, ssl_ctl_buf_t *ctl_buf)
341 {
342 struct Client *client_p;
343 char reason[256];
344 int32_t fd;
345
346 if(ctl_buf->buflen < 6)
347 return; /* bogus message..drop it.. XXX should warn here */
348
349 fd = buf_to_int32(&ctl_buf->buf[1]);
350 rb_strlcpy(reason, &ctl_buf->buf[5], sizeof(reason));
351 client_p = find_cli_fd_hash(fd);
352 if(client_p == NULL)
353 return;
354 if(IsAnyServer(client_p))
355 {
356 sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) && !IsServer(client_p) ? L_NETWIDE : L_ALL, "ssld error for %s: %s", client_p->name, reason);
357 ilog(L_SERVER, "ssld error for %s: %s", log_client_name(client_p, SHOW_IP), reason);
358 }
359 exit_client(client_p, client_p, &me, reason);
360 }
361
362
363 static void
364 ssl_process_zip_ready(ssl_ctl_t *ctl, ssl_ctl_buf_t *ctl_buf)
365 {
366 struct Client *client_p;
367 int32_t fd;
368
369 if(ctl_buf->buflen < 5)
370 return; /* bogus message..drop it.. XXX should warn here */
371
372 fd = buf_to_int32(&ctl_buf->buf[1]);
373 client_p = find_cli_fd_hash(fd);
374 if(client_p == NULL)
375 return;
376
377 /* Now start sending the data that should be compressed. */
378 // ClearCork(client_p);
379 send_pop_queue(client_p);
380 /* Start reading uncompressed data. */
381 read_packet(client_p->localClient->F, client_p);
382 }
383
384
385 static void
386 ssl_process_cmd_recv(ssl_ctl_t *ctl)
387 {
388 static const char *cannot_setup_ssl = "ssld cannot setup ssl, check your certificates and private key";
389 static const char *no_ssl_or_zlib = "ssld has neither SSL/TLS or zlib support killing all sslds";
390 rb_dlink_node *ptr, *next;
391 ssl_ctl_buf_t *ctl_buf;
392 if(ctl->dead)
393 return;
394 RB_DLINK_FOREACH_SAFE(ptr, next, ctl->readq.head)
395 {
396 ctl_buf = ptr->data;
397 switch(*ctl_buf->buf)
398 {
399 case 'N':
400 ssl_ok = 0; /* ssld says it can't do ssl/tls */
401 break;
402 case 'D':
403 ssl_process_dead_fd(ctl, ctl_buf);
404 break;
405 case 'S':
406 ssl_process_zipstats(ctl, ctl_buf);
407 break;
408 case 'I':
409 ssl_ok = 0;
410 ilog(L_MAIN, cannot_setup_ssl);
411 sendto_realops_snomask(SNO_GENERAL, L_ALL, cannot_setup_ssl);
412 case 'U':
413 zlib_ok = 0;
414 ssl_ok = 0;
415 ilog(L_MAIN, no_ssl_or_zlib);
416 sendto_realops_snomask(SNO_GENERAL, L_ALL, no_ssl_or_zlib);
417 ssl_killall();
418 break;
419 case 'R':
420 ssl_process_zip_ready(ctl, ctl_buf);
421 break;
422 case 'z':
423 zlib_ok = 0;
424 break;
425 default:
426 ilog(L_MAIN, "Received invalid command from ssld: %s", ctl_buf->buf);
427 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Received invalid command from ssld");
428 break;
429 }
430 rb_dlinkDelete(ptr, &ctl->readq);
431 rb_free(ctl_buf->buf);
432 rb_free(ctl_buf);
433 }
434
435 }
436
437
438 static void
439 ssl_read_ctl(rb_fde_t *F, void *data)
440 {
441 ssl_ctl_buf_t *ctl_buf;
442 ssl_ctl_t *ctl = data;
443 int retlen;
444
445 if(ctl->dead)
446 return;
447 do
448 {
449 ctl_buf = rb_malloc(sizeof(ssl_ctl_buf_t));
450 ctl_buf->buf = rb_malloc(READSIZE);
451 retlen = rb_recv_fd_buf(ctl->F, ctl_buf->buf, READSIZE, ctl_buf->F, 4);
452 ctl_buf->buflen = retlen;
453 if(retlen <= 0) {
454 rb_free(ctl_buf->buf);
455 rb_free(ctl_buf);
456 }
457 else
458 rb_dlinkAddTail(ctl_buf, &ctl_buf->node, &ctl->readq);
459 } while(retlen > 0);
460
461 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
462 {
463 ssl_dead(ctl);
464 return;
465 }
466 ssl_process_cmd_recv(ctl);
467 rb_setselect(ctl->F, RB_SELECT_READ, ssl_read_ctl, ctl);
468 }
469
470 static ssl_ctl_t *
471 which_ssld(void)
472 {
473 ssl_ctl_t *ctl, *lowest = NULL;
474 rb_dlink_node *ptr;
475
476 RB_DLINK_FOREACH(ptr, ssl_daemons.head)
477 {
478 ctl = ptr->data;
479 if(ctl->dead)
480 continue;
481 if(lowest == NULL) {
482 lowest = ctl;
483 continue;
484 }
485 if(ctl->cli_count < lowest->cli_count)
486 lowest = ctl;
487 }
488 return(lowest);
489 }
490
491 static void
492 ssl_write_ctl(rb_fde_t *F, void *data)
493 {
494 ssl_ctl_t *ctl = data;
495 ssl_ctl_buf_t *ctl_buf;
496 rb_dlink_node *ptr, *next;
497 int retlen, x;
498
499 if(ctl->dead)
500 return;
501
502 RB_DLINK_FOREACH_SAFE(ptr, next, ctl->writeq.head)
503 {
504 ctl_buf = ptr->data;
505 /* in theory unix sock_dgram shouldn't ever short write this.. */
506 retlen = rb_send_fd_buf(ctl->F, ctl_buf->F, ctl_buf->nfds, ctl_buf->buf, ctl_buf->buflen);
507 if(retlen > 0)
508 {
509 rb_dlinkDelete(ptr, &ctl->writeq);
510 for(x = 0; x < ctl_buf->nfds; x++)
511 rb_close(ctl_buf->F[x]);
512 rb_free(ctl_buf->buf);
513 rb_free(ctl_buf);
514
515 }
516 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
517 {
518 ssl_dead(ctl);
519 return;
520 } else {
521 rb_setselect(ctl->F, RB_SELECT_WRITE, ssl_write_ctl, ctl);
522 }
523 }
524 }
525
526 static void
527 ssl_cmd_write_queue(ssl_ctl_t *ctl, rb_fde_t **F, int count, const void *buf, size_t buflen)
528 {
529 ssl_ctl_buf_t *ctl_buf;
530 int x;
531
532 /* don't bother */
533 if(ctl->dead)
534 return;
535
536 ctl_buf = rb_malloc(sizeof(ssl_ctl_buf_t));
537 ctl_buf->buf = rb_malloc(buflen);
538 memcpy(ctl_buf->buf, buf, buflen);
539 ctl_buf->buflen = buflen;
540
541 for(x = 0; x < count && x < MAXPASSFD; x++)
542 {
543 ctl_buf->F[x] = F[x];
544 }
545 ctl_buf->nfds = count;
546 rb_dlinkAddTail(ctl_buf, &ctl_buf->node, &ctl->writeq);
547 ssl_write_ctl(ctl->F, ctl);
548 }
549
550
551 static void
552 send_new_ssl_certs_one(ssl_ctl_t *ctl, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params)
553 {
554 size_t len;
555
556 len = strlen(ssl_cert) + strlen(ssl_private_key) + strlen(ssl_dh_params) + 5;
557 if(len > sizeof(tmpbuf))
558 {
559 sendto_realops_snomask(SNO_GENERAL, L_ALL,
560 "Parameters for send_new_ssl_certs_one too long (%zu > %zu) to pass to ssld, not sending...",
561 len, sizeof(tmpbuf));
562 ilog(L_MAIN, "Parameters for send_new_ssl_certs_one too long (%zu > %zu) to pass to ssld, not sending...",
563 len, sizeof(tmpbuf));
564 return;
565 }
566 len = rb_snprintf(tmpbuf, sizeof(tmpbuf), "K%c%s%c%s%c%s%c", nul, ssl_cert, nul, ssl_private_key, nul, ssl_dh_params, nul);
567 ssl_cmd_write_queue(ctl, NULL, 0, tmpbuf, len);
568 }
569
570 static void
571 send_init_prng(ssl_ctl_t *ctl, prng_seed_t seedtype, const char *path)
572 {
573 size_t len;
574 const char *s;
575 uint8_t seed = (uint8_t) seedtype;
576
577 if(path == NULL)
578 s = "";
579 else
580 s = path;
581
582 len = strlen(s) + 3;
583 if(len > sizeof(tmpbuf))
584 {
585 sendto_realops_snomask(SNO_GENERAL, L_ALL,
586 "Parameters for send_init_prng too long (%zd > %zd) to pass to ssld, not sending...",
587 len, sizeof(tmpbuf));
588 ilog(L_MAIN, "Parameters for send_init_prng too long (%zd > %zd) to pass to ssld, not sending...",
589 len, sizeof(tmpbuf));
590 return;
591
592 }
593 len = rb_snprintf(tmpbuf, sizeof(tmpbuf), "I%c%s%c", seed, s, nul);
594 ssl_cmd_write_queue(ctl, NULL, 0, tmpbuf, len);
595 }
596
597 void
598 send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params)
599 {
600 rb_dlink_node *ptr;
601 if(ssl_cert == NULL || ssl_private_key == NULL || ssl_dh_params == NULL)
602 {
603 ssl_ok = 0;
604 return;
605 }
606 RB_DLINK_FOREACH(ptr, ssl_daemons.head)
607 {
608 ssl_ctl_t *ctl = ptr->data;
609 send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params);
610 }
611 }
612
613
614 ssl_ctl_t *
615 start_ssld_accept(rb_fde_t *sslF, rb_fde_t *plainF, int32_t id)
616 {
617 rb_fde_t *F[2];
618 ssl_ctl_t *ctl;
619 char buf[5];
620 F[0] = sslF;
621 F[1] = plainF;
622
623 buf[0] = 'A';
624 int32_to_buf(&buf[1], id);
625 ctl = which_ssld();
626 ctl->cli_count++;
627 ssl_cmd_write_queue(ctl, F, 2, buf, sizeof(buf));
628 return ctl;
629 }
630
631 ssl_ctl_t *
632 start_ssld_connect(rb_fde_t *sslF, rb_fde_t *plainF, int32_t id)
633 {
634 rb_fde_t *F[2];
635 ssl_ctl_t *ctl;
636 char buf[5];
637 F[0] = sslF;
638 F[1] = plainF;
639
640 buf[0] = 'C';
641 int32_to_buf(&buf[1], id);
642
643 ctl = which_ssld();
644 ctl->cli_count++;
645 ssl_cmd_write_queue(ctl, F, 2, buf, sizeof(buf));
646 return ctl;
647 }
648
649 void
650 ssld_decrement_clicount(ssl_ctl_t *ctl)
651 {
652 if(ctl == NULL)
653 return;
654
655 ctl->cli_count--;
656 if(ctl->dead && !ctl->cli_count)
657 {
658 free_ssl_daemon(ctl);
659 }
660 }
661
662 /*
663 * what we end up sending to the ssld process for ziplinks is the following
664 * Z[ourfd][level][RECVQ]
665 * Z = ziplinks command = buf[0]
666 * ourfd = Our end of the socketpair = buf[1..4]
667 * level = zip level buf[5]
668 * recvqlen = our recvq len = buf[6-7]
669 * recvq = any data we read prior to starting ziplinks
670 */
671 void
672 start_zlib_session(void *data)
673 {
674 struct Client *server = (struct Client *)data;
675 uint16_t recvqlen;
676 uint8_t level;
677 void *xbuf;
678
679 rb_fde_t *F[2];
680 rb_fde_t *xF1, *xF2;
681 char *buf;
682 void *recvq_start;
683
684 size_t hdr = (sizeof(uint8_t) * 2) + sizeof(int32_t);
685 size_t len;
686 int cpylen, left;
687
688 server->localClient->event = NULL;
689
690 recvqlen = rb_linebuf_len(&server->localClient->buf_recvq);
691
692 len = recvqlen + hdr;
693
694 if(len > READBUF_SIZE)
695 {
696 rb_free(buf);
697 sendto_realops_snomask(SNO_GENERAL, L_ALL, "ssld - attempted to pass message of %zd len, max len %d, giving up", len, READBUF_SIZE);
698 ilog(L_MAIN, "ssld - attempted to pass message of %zd len, max len %d, giving up", len, READBUF_SIZE);
699 exit_client(server, server, server, "ssld readbuf exceeded");
700 return;
701 }
702
703 buf = rb_malloc(len);
704 level = ConfigFileEntry.compression_level;
705
706 int32_to_buf(&buf[1], rb_get_fd(server->localClient->F));
707 buf[5] = (char)level;
708
709 recvq_start = &buf[6];
710 server->localClient->zipstats = rb_malloc(sizeof(struct ZipStats));
711
712 xbuf = recvq_start;
713 left = recvqlen;
714
715 do
716 {
717 cpylen = rb_linebuf_get(&server->localClient->buf_recvq, xbuf, left, LINEBUF_PARTIAL, LINEBUF_RAW);
718 left -= cpylen;
719 xbuf += cpylen;
720 } while(cpylen > 0);
721
722 /* Pass the socket to ssld. */
723 *buf = 'Z';
724 rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF1, &xF2, "Initial zlib socketpairs");
725
726 F[0] = server->localClient->F;
727 F[1] = xF1;
728 del_from_cli_fd_hash(server);
729 server->localClient->F = xF2;
730 /* need to redo as what we did before isn't valid now */
731 int32_to_buf(&buf[1], rb_get_fd(server->localClient->F));
732 add_to_cli_fd_hash(server);
733 server->localClient->ssl_ctl = which_ssld();
734 server->localClient->ssl_ctl->cli_count++;
735 ssl_cmd_write_queue(server->localClient->ssl_ctl, F, 2, buf, len);
736 rb_free(buf);
737 }
738
739 static void
740 collect_zipstats(void *unused)
741 {
742 rb_dlink_node *ptr;
743 struct Client *target_p;
744 char buf[sizeof(uint8_t) + sizeof(int32_t) + HOSTLEN];
745 void *odata;
746 size_t len;
747 int32_t id;
748
749 buf[0] = 'S';
750 odata = buf + sizeof(uint8_t) + sizeof(int32_t);
751
752 RB_DLINK_FOREACH(ptr, serv_list.head)
753 {
754 target_p = ptr->data;
755 if(IsCapable(target_p, CAP_ZIP))
756 {
757 len = sizeof(uint8_t) + sizeof(uint32_t);
758
759 id = rb_get_fd(target_p->localClient->F);
760 int32_to_buf(&buf[1], rb_get_fd(target_p->localClient->F));
761 rb_strlcpy(odata, target_p->name, (sizeof(buf)-len));
762 len += strlen(odata) + 1; /* Get the \0 as well */
763 ssl_cmd_write_queue(target_p->localClient->ssl_ctl, NULL, 0, buf, len);
764 }
765 }
766 }
767
768 static void
769 cleanup_dead_ssl(void *unused)
770 {
771 rb_dlink_node *ptr, *next;
772 ssl_ctl_t *ctl;
773 RB_DLINK_FOREACH_SAFE(ptr, next, ssl_daemons.head)
774 {
775 ctl = ptr->data;
776 if(ctl->dead && !ctl->cli_count)
777 {
778 free_ssl_daemon(ctl);
779 }
780 }
781 }
782
783 int
784 get_ssld_count(void)
785 {
786 return ssld_count;
787 }
788
789 void init_ssld(void)
790 {
791 rb_event_addish("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME);
792 rb_event_addish("cleanup_dead_ssld", cleanup_dead_ssl, NULL, 1200);
793 }
794