]> jfr.im git - solanum.git/blob - src/s_serv.c
server: Require EX and IE capabilities (+e and +I cmodes).
[solanum.git] / src / s_serv.c
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * s_serv.c: Server related functions.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
24 * $Id: s_serv.c 3550 2007-08-09 06:47:26Z nenolod $
25 */
26
27 #include "stdinc.h"
28
29 #ifdef HAVE_LIBCRYPTO
30 #include <openssl/rsa.h>
31 #endif
32
33 #include "s_serv.h"
34 #include "class.h"
35 #include "client.h"
36 #include "common.h"
37 #include "hash.h"
38 #include "match.h"
39 #include "ircd.h"
40 #include "ircd_defs.h"
41 #include "numeric.h"
42 #include "packet.h"
43 #include "res.h"
44 #include "s_conf.h"
45 #include "s_newconf.h"
46 #include "logger.h"
47 #include "s_stats.h"
48 #include "s_user.h"
49 #include "scache.h"
50 #include "send.h"
51 #include "client.h"
52 #include "channel.h" /* chcap_usage_counts stuff... */
53 #include "hook.h"
54 #include "msg.h"
55 #include "reject.h"
56 #include "sslproc.h"
57 #include "capability.h"
58 #include "s_assert.h"
59
60 #ifndef INADDR_NONE
61 #define INADDR_NONE ((unsigned int) 0xffffffff)
62 #endif
63
64 int MaxConnectionCount = 1;
65 int MaxClientCount = 1;
66 int refresh_user_links = 0;
67
68 static char buf[BUFSIZE];
69
70 /*
71 * list of recognized server capabilities. "TS" is not on the list
72 * because all servers that we talk to already do TS, and the kludged
73 * extra argument to "PASS" takes care of checking that. -orabidoo
74 */
75 struct CapabilityIndex *serv_capindex = NULL;
76
77 unsigned int CAP_CAP;
78 unsigned int CAP_QS;
79 unsigned int CAP_EX;
80 unsigned int CAP_CHW;
81 unsigned int CAP_IE;
82 unsigned int CAP_KLN;
83 unsigned int CAP_ZIP;
84 unsigned int CAP_KNOCK;
85 unsigned int CAP_TB;
86 unsigned int CAP_UNKLN;
87 unsigned int CAP_CLUSTER;
88 unsigned int CAP_ENCAP;
89 unsigned int CAP_TS6;
90 unsigned int CAP_SERVICE;
91 unsigned int CAP_RSFNC;
92 unsigned int CAP_SAVE;
93 unsigned int CAP_EUID;
94 unsigned int CAP_EOPMOD;
95 unsigned int CAP_BAN;
96 unsigned int CAP_MLOCK;
97
98 /*
99 * initialize our builtin capability table. --nenolod
100 */
101 void
102 init_builtin_capabs(void)
103 {
104 serv_capindex = capability_index_create("server capabilities");
105
106 /* These two are not set via CAPAB/GCAP keywords. */
107 CAP_CAP = capability_put_anonymous(serv_capindex);
108 CAP_TS6 = capability_put_anonymous(serv_capindex);
109
110 CAP_QS = capability_put(serv_capindex, "QS");
111 CAP_EX = capability_put(serv_capindex, "EX");
112 CAP_CHW = capability_put(serv_capindex, "CHW");
113 CAP_IE = capability_put(serv_capindex, "IE");
114 CAP_KLN = capability_put(serv_capindex, "KLN");
115 CAP_KNOCK = capability_put(serv_capindex, "KNOCK");
116 CAP_ZIP = capability_put(serv_capindex, "ZIP");
117 CAP_TB = capability_put(serv_capindex, "TB");
118 CAP_UNKLN = capability_put(serv_capindex, "UNKLN");
119 CAP_CLUSTER = capability_put(serv_capindex, "CLUSTER");
120 CAP_ENCAP = capability_put(serv_capindex, "ENCAP");
121 CAP_SERVICE = capability_put(serv_capindex, "SERVICES");
122 CAP_RSFNC = capability_put(serv_capindex, "RSFNC");
123 CAP_SAVE = capability_put(serv_capindex, "SAVE");
124 CAP_EUID = capability_put(serv_capindex, "EUID");
125 CAP_EOPMOD = capability_put(serv_capindex, "EOPMOD");
126 CAP_BAN = capability_put(serv_capindex, "BAN");
127 CAP_MLOCK = capability_put(serv_capindex, "MLOCK");
128
129 capability_require(serv_capindex, "QS");
130 capability_require(serv_capindex, "EX");
131 capability_require(serv_capindex, "IE");
132 capability_require(serv_capindex, "ENCAP");
133 }
134
135 static CNCB serv_connect_callback;
136 static CNCB serv_connect_ssl_callback;
137
138 /*
139 * hunt_server - Do the basic thing in delivering the message (command)
140 * across the relays to the specific server (server) for
141 * actions.
142 *
143 * Note: The command is a format string and *MUST* be
144 * of prefixed style (e.g. ":%s COMMAND %s ...").
145 * Command can have only max 8 parameters.
146 *
147 * server parv[server] is the parameter identifying the
148 * target server.
149 *
150 * *WARNING*
151 * parv[server] is replaced with the pointer to the
152 * real servername from the matched client (I'm lazy
153 * now --msa).
154 *
155 * returns: (see #defines)
156 */
157 int
158 hunt_server(struct Client *client_p, struct Client *source_p,
159 const char *command, int server, int parc, const char *parv[])
160 {
161 struct Client *target_p;
162 int wilds;
163 rb_dlink_node *ptr;
164 const char *old;
165 char *new;
166
167 /*
168 * Assume it's me, if no server
169 */
170 if(parc <= server || EmptyString(parv[server]) ||
171 match(parv[server], me.name) || (strcmp(parv[server], me.id) == 0))
172 return (HUNTED_ISME);
173
174 new = LOCAL_COPY(parv[server]);
175
176 /*
177 * These are to pickup matches that would cause the following
178 * message to go in the wrong direction while doing quick fast
179 * non-matching lookups.
180 */
181 if(MyClient(source_p))
182 target_p = find_named_client(new);
183 else
184 target_p = find_client(new);
185
186 if(target_p)
187 if(target_p->from == source_p->from && !MyConnect(target_p))
188 target_p = NULL;
189
190 collapse(new);
191 wilds = (strchr(new, '?') || strchr(new, '*'));
192
193 /*
194 * Again, if there are no wild cards involved in the server
195 * name, use the hash lookup
196 */
197 if(!target_p && wilds)
198 {
199 RB_DLINK_FOREACH(ptr, global_serv_list.head)
200 {
201 if(match(new, ((struct Client *) (ptr->data))->name))
202 {
203 target_p = ptr->data;
204 break;
205 }
206 }
207 }
208
209 if(target_p && !IsRegistered(target_p))
210 target_p = NULL;
211
212 if(target_p)
213 {
214 if(IsMe(target_p) || MyClient(target_p))
215 return HUNTED_ISME;
216
217 old = parv[server];
218 parv[server] = get_id(target_p, target_p);
219
220 sendto_one(target_p, command, get_id(source_p, target_p),
221 parv[1], parv[2], parv[3], parv[4], parv[5], parv[6], parv[7], parv[8]);
222 parv[server] = old;
223 return (HUNTED_PASS);
224 }
225
226 if(MyClient(source_p) || !IsDigit(parv[server][0]))
227 sendto_one_numeric(source_p, ERR_NOSUCHSERVER,
228 form_str(ERR_NOSUCHSERVER), parv[server]);
229 return (HUNTED_NOSUCH);
230 }
231
232 /*
233 * try_connections - scan through configuration and try new connections.
234 * Returns the calendar time when the next call to this
235 * function should be made latest. (No harm done if this
236 * is called earlier or later...)
237 */
238 void
239 try_connections(void *unused)
240 {
241 struct Client *client_p;
242 struct server_conf *server_p = NULL;
243 struct server_conf *tmp_p;
244 struct Class *cltmp;
245 rb_dlink_node *ptr;
246 int connecting = FALSE;
247 int confrq = 0;
248 time_t next = 0;
249
250 RB_DLINK_FOREACH(ptr, server_conf_list.head)
251 {
252 tmp_p = ptr->data;
253
254 if(ServerConfIllegal(tmp_p) || !ServerConfAutoconn(tmp_p))
255 continue;
256
257 /* don't allow ssl connections if ssl isn't setup */
258 if(ServerConfSSL(tmp_p) && (!ssl_ok || !get_ssld_count()))
259 continue;
260
261 cltmp = tmp_p->class;
262
263 /*
264 * Skip this entry if the use of it is still on hold until
265 * future. Otherwise handle this entry (and set it on hold
266 * until next time). Will reset only hold times, if already
267 * made one successfull connection... [this algorithm is
268 * a bit fuzzy... -- msa >;) ]
269 */
270 if(tmp_p->hold > rb_current_time())
271 {
272 if(next > tmp_p->hold || next == 0)
273 next = tmp_p->hold;
274 continue;
275 }
276
277 confrq = get_con_freq(cltmp);
278 tmp_p->hold = rb_current_time() + confrq;
279
280 /*
281 * Found a CONNECT config with port specified, scan clients
282 * and see if this server is already connected?
283 */
284 client_p = find_server(NULL, tmp_p->name);
285
286 if(!client_p && (CurrUsers(cltmp) < MaxUsers(cltmp)) && !connecting)
287 {
288 server_p = tmp_p;
289
290 /* We connect only one at time... */
291 connecting = TRUE;
292 }
293
294 if((next > tmp_p->hold) || (next == 0))
295 next = tmp_p->hold;
296 }
297
298 /* TODO: change this to set active flag to 0 when added to event! --Habeeb */
299 if(GlobalSetOptions.autoconn == 0)
300 return;
301
302 if(!connecting)
303 return;
304
305 /* move this connect entry to end.. */
306 rb_dlinkDelete(&server_p->node, &server_conf_list);
307 rb_dlinkAddTail(server_p, &server_p->node, &server_conf_list);
308
309 /*
310 * We used to only print this if serv_connect() actually
311 * suceeded, but since rb_tcp_connect() can call the callback
312 * immediately if there is an error, we were getting error messages
313 * in the wrong order. SO, we just print out the activated line,
314 * and let serv_connect() / serv_connect_callback() print an
315 * error afterwards if it fails.
316 * -- adrian
317 */
318 sendto_realops_snomask(SNO_GENERAL, L_ALL,
319 "Connection to %s activated",
320 server_p->name);
321
322 serv_connect(server_p, 0);
323 }
324
325 int
326 check_server(const char *name, struct Client *client_p)
327 {
328 struct server_conf *server_p = NULL;
329 struct server_conf *tmp_p;
330 rb_dlink_node *ptr;
331 int error = -1;
332 const char *encr;
333
334 s_assert(NULL != client_p);
335 if(client_p == NULL)
336 return error;
337
338 if(!(client_p->localClient->passwd))
339 return -2;
340
341 if(strlen(name) > HOSTLEN)
342 return -4;
343
344 RB_DLINK_FOREACH(ptr, server_conf_list.head)
345 {
346 tmp_p = ptr->data;
347
348 if(ServerConfIllegal(tmp_p))
349 continue;
350
351 if(!match(tmp_p->name, name))
352 continue;
353
354 error = -3;
355
356 /* XXX: Fix me for IPv6 */
357 /* XXX sockhost is the IPv4 ip as a string */
358 if(match(tmp_p->host, client_p->host) ||
359 match(tmp_p->host, client_p->sockhost))
360 {
361 error = -2;
362
363 if(tmp_p->passwd)
364 {
365 if(ServerConfEncrypted(tmp_p))
366 {
367 encr = rb_crypt(client_p->localClient->passwd,
368 tmp_p->passwd);
369 if(encr != NULL && !strcmp(tmp_p->passwd, encr))
370 {
371 server_p = tmp_p;
372 break;
373 }
374 else
375 continue;
376 }
377 else if(strcmp(tmp_p->passwd, client_p->localClient->passwd))
378 continue;
379 }
380
381 if(tmp_p->certfp)
382 {
383 if(!client_p->certfp || strcasecmp(tmp_p->certfp, client_p->certfp) != 0)
384 continue;
385 }
386
387 server_p = tmp_p;
388 break;
389 }
390 }
391
392 if(server_p == NULL)
393 return error;
394
395 if(ServerConfSSL(server_p) && client_p->localClient->ssl_ctl == NULL)
396 {
397 return -5;
398 }
399
400 attach_server_conf(client_p, server_p);
401
402 /* clear ZIP/TB if they support but we dont want them */
403 #ifdef HAVE_LIBZ
404 if(!ServerConfCompressed(server_p))
405 #endif
406 ClearCap(client_p, CAP_ZIP);
407
408 if(!ServerConfTb(server_p))
409 ClearCap(client_p, CAP_TB);
410
411 return 0;
412 }
413
414 /*
415 * send_capabilities
416 *
417 * inputs - Client pointer to send to
418 * - int flag of capabilities that this server has
419 * output - NONE
420 * side effects - send the CAPAB line to a server -orabidoo
421 *
422 */
423 void
424 send_capabilities(struct Client *client_p, unsigned int cap_can_send)
425 {
426 sendto_one(client_p, "CAPAB :%s", capability_index_list(serv_capindex, cap_can_send));
427 }
428
429 static void
430 burst_ban(struct Client *client_p)
431 {
432 rb_dlink_node *ptr;
433 struct ConfItem *aconf;
434 const char *type, *oper;
435 /* +5 for !,@,{,} and null */
436 char operbuf[NICKLEN + USERLEN + HOSTLEN + HOSTLEN + 5];
437 char *p;
438 size_t melen;
439
440 melen = strlen(me.name);
441 RB_DLINK_FOREACH(ptr, prop_bans.head)
442 {
443 aconf = ptr->data;
444
445 /* Skip expired stuff. */
446 if(aconf->lifetime < rb_current_time())
447 continue;
448 switch(aconf->status & ~CONF_ILLEGAL)
449 {
450 case CONF_KILL: type = "K"; break;
451 case CONF_DLINE: type = "D"; break;
452 case CONF_XLINE: type = "X"; break;
453 case CONF_RESV_NICK: type = "R"; break;
454 case CONF_RESV_CHANNEL: type = "R"; break;
455 default:
456 continue;
457 }
458 oper = aconf->info.oper;
459 if(aconf->flags & CONF_FLAGS_MYOPER)
460 {
461 /* Our operator{} names may not be meaningful
462 * to other servers, so rewrite to our server
463 * name.
464 */
465 rb_strlcpy(operbuf, aconf->info.oper, sizeof buf);
466 p = strrchr(operbuf, '{');
467 if (p != NULL &&
468 operbuf + sizeof operbuf - p > (ptrdiff_t)(melen + 2))
469 {
470 memcpy(p + 1, me.name, melen);
471 p[melen + 1] = '}';
472 p[melen + 2] = '\0';
473 oper = operbuf;
474 }
475 }
476 sendto_one(client_p, ":%s BAN %s %s %s %lu %d %d %s :%s%s%s",
477 me.id,
478 type,
479 aconf->user ? aconf->user : "*", aconf->host,
480 (unsigned long)aconf->created,
481 (int)(aconf->hold - aconf->created),
482 (int)(aconf->lifetime - aconf->created),
483 oper,
484 aconf->passwd,
485 aconf->spasswd ? "|" : "",
486 aconf->spasswd ? aconf->spasswd : "");
487 }
488 }
489
490 /* burst_modes_TS6()
491 *
492 * input - client to burst to, channel name, list to burst, mode flag
493 * output -
494 * side effects - client is sent a list of +b, +e, or +I modes
495 */
496 static void
497 burst_modes_TS6(struct Client *client_p, struct Channel *chptr,
498 rb_dlink_list *list, char flag)
499 {
500 rb_dlink_node *ptr;
501 struct Ban *banptr;
502 char *t;
503 int tlen;
504 int mlen;
505 int cur_len;
506
507 cur_len = mlen = rb_sprintf(buf, ":%s BMASK %ld %s %c :",
508 me.id, (long) chptr->channelts, chptr->chname, flag);
509 t = buf + mlen;
510
511 RB_DLINK_FOREACH(ptr, list->head)
512 {
513 banptr = ptr->data;
514
515 tlen = strlen(banptr->banstr) + (banptr->forward ? strlen(banptr->forward) + 1 : 0) + 1;
516
517 /* uh oh */
518 if(cur_len + tlen > BUFSIZE - 3)
519 {
520 /* the one we're trying to send doesnt fit at all! */
521 if(cur_len == mlen)
522 {
523 s_assert(0);
524 continue;
525 }
526
527 /* chop off trailing space and send.. */
528 *(t-1) = '\0';
529 sendto_one(client_p, "%s", buf);
530 cur_len = mlen;
531 t = buf + mlen;
532 }
533
534 if (banptr->forward)
535 rb_sprintf(t, "%s$%s ", banptr->banstr, banptr->forward);
536 else
537 rb_sprintf(t, "%s ", banptr->banstr);
538 t += tlen;
539 cur_len += tlen;
540 }
541
542 /* cant ever exit the loop above without having modified buf,
543 * chop off trailing space and send.
544 */
545 *(t-1) = '\0';
546 sendto_one(client_p, "%s", buf);
547 }
548
549 /*
550 * burst_TS6
551 *
552 * inputs - client (server) to send nick towards
553 * - client to send nick for
554 * output - NONE
555 * side effects - NICK message is sent towards given client_p
556 */
557 static void
558 burst_TS6(struct Client *client_p)
559 {
560 char ubuf[BUFSIZE];
561 struct Client *target_p;
562 struct Channel *chptr;
563 struct membership *msptr;
564 hook_data_client hclientinfo;
565 hook_data_channel hchaninfo;
566 rb_dlink_node *ptr;
567 rb_dlink_node *uptr;
568 char *t;
569 int tlen, mlen;
570 int cur_len = 0;
571
572 hclientinfo.client = hchaninfo.client = client_p;
573
574 RB_DLINK_FOREACH(ptr, global_client_list.head)
575 {
576 target_p = ptr->data;
577
578 if(!IsPerson(target_p))
579 continue;
580
581 send_umode(NULL, target_p, 0, 0, ubuf);
582 if(!*ubuf)
583 {
584 ubuf[0] = '+';
585 ubuf[1] = '\0';
586 }
587
588 if(IsCapable(client_p, CAP_EUID))
589 sendto_one(client_p, ":%s EUID %s %d %ld %s %s %s %s %s %s %s :%s",
590 target_p->servptr->id, target_p->name,
591 target_p->hopcount + 1,
592 (long) target_p->tsinfo, ubuf,
593 target_p->username, target_p->host,
594 IsIPSpoof(target_p) ? "0" : target_p->sockhost,
595 target_p->id,
596 IsDynSpoof(target_p) ? target_p->orighost : "*",
597 EmptyString(target_p->user->suser) ? "*" : target_p->user->suser,
598 target_p->info);
599 else
600 sendto_one(client_p, ":%s UID %s %d %ld %s %s %s %s %s :%s",
601 target_p->servptr->id, target_p->name,
602 target_p->hopcount + 1,
603 (long) target_p->tsinfo, ubuf,
604 target_p->username, target_p->host,
605 IsIPSpoof(target_p) ? "0" : target_p->sockhost,
606 target_p->id, target_p->info);
607
608 if(!EmptyString(target_p->certfp))
609 sendto_one(client_p, ":%s ENCAP * CERTFP :%s",
610 use_id(target_p), target_p->certfp);
611
612 if(!IsCapable(client_p, CAP_EUID))
613 {
614 if(IsDynSpoof(target_p))
615 sendto_one(client_p, ":%s ENCAP * REALHOST %s",
616 use_id(target_p), target_p->orighost);
617 if(!EmptyString(target_p->user->suser))
618 sendto_one(client_p, ":%s ENCAP * LOGIN %s",
619 use_id(target_p), target_p->user->suser);
620 }
621
622 if(ConfigFileEntry.burst_away && !EmptyString(target_p->user->away))
623 sendto_one(client_p, ":%s AWAY :%s",
624 use_id(target_p),
625 target_p->user->away);
626
627 hclientinfo.target = target_p;
628 call_hook(h_burst_client, &hclientinfo);
629 }
630
631 RB_DLINK_FOREACH(ptr, global_channel_list.head)
632 {
633 chptr = ptr->data;
634
635 if(*chptr->chname != '#')
636 continue;
637
638 cur_len = mlen = rb_sprintf(buf, ":%s SJOIN %ld %s %s :", me.id,
639 (long) chptr->channelts, chptr->chname,
640 channel_modes(chptr, client_p));
641
642 t = buf + mlen;
643
644 RB_DLINK_FOREACH(uptr, chptr->members.head)
645 {
646 msptr = uptr->data;
647
648 tlen = strlen(use_id(msptr->client_p)) + 1;
649 if(is_chanop(msptr))
650 tlen++;
651 if(is_voiced(msptr))
652 tlen++;
653
654 if(cur_len + tlen >= BUFSIZE - 3)
655 {
656 *(t-1) = '\0';
657 sendto_one(client_p, "%s", buf);
658 cur_len = mlen;
659 t = buf + mlen;
660 }
661
662 rb_sprintf(t, "%s%s ", find_channel_status(msptr, 1),
663 use_id(msptr->client_p));
664
665 cur_len += tlen;
666 t += tlen;
667 }
668
669 if (rb_dlink_list_length(&chptr->members) > 0)
670 {
671 /* remove trailing space */
672 *(t-1) = '\0';
673 }
674 sendto_one(client_p, "%s", buf);
675
676 if(rb_dlink_list_length(&chptr->banlist) > 0)
677 burst_modes_TS6(client_p, chptr, &chptr->banlist, 'b');
678
679 if(IsCapable(client_p, CAP_EX) &&
680 rb_dlink_list_length(&chptr->exceptlist) > 0)
681 burst_modes_TS6(client_p, chptr, &chptr->exceptlist, 'e');
682
683 if(IsCapable(client_p, CAP_IE) &&
684 rb_dlink_list_length(&chptr->invexlist) > 0)
685 burst_modes_TS6(client_p, chptr, &chptr->invexlist, 'I');
686
687 if(rb_dlink_list_length(&chptr->quietlist) > 0)
688 burst_modes_TS6(client_p, chptr, &chptr->quietlist, 'q');
689
690 if(IsCapable(client_p, CAP_TB) && chptr->topic != NULL)
691 sendto_one(client_p, ":%s TB %s %ld %s%s:%s",
692 me.id, chptr->chname, (long) chptr->topic_time,
693 ConfigChannel.burst_topicwho ? chptr->topic_info : "",
694 ConfigChannel.burst_topicwho ? " " : "",
695 chptr->topic);
696
697 if(IsCapable(client_p, CAP_MLOCK))
698 sendto_one(client_p, ":%s MLOCK %ld %s :%s",
699 me.id, (long) chptr->channelts, chptr->chname,
700 EmptyString(chptr->mode_lock) ? "" : chptr->mode_lock);
701
702 hchaninfo.chptr = chptr;
703 call_hook(h_burst_channel, &hchaninfo);
704 }
705
706 hclientinfo.target = NULL;
707 call_hook(h_burst_finished, &hclientinfo);
708 }
709
710 /*
711 * show_capabilities - show current server capabilities
712 *
713 * inputs - pointer to an struct Client
714 * output - pointer to static string
715 * side effects - build up string representing capabilities of server listed
716 */
717 const char *
718 show_capabilities(struct Client *target_p)
719 {
720 static char msgbuf[BUFSIZE];
721
722 *msgbuf = '\0';
723
724 if(has_id(target_p))
725 rb_strlcpy(msgbuf, " TS6", sizeof(msgbuf));
726
727 if(IsSSL(target_p))
728 rb_strlcat(msgbuf, " SSL", sizeof(msgbuf));
729
730 if(!IsServer(target_p) || !target_p->serv->caps) /* short circuit if no caps */
731 return msgbuf + 1;
732
733 rb_strlcat(msgbuf, " ", sizeof(msgbuf));
734 rb_strlcat(msgbuf, capability_index_list(serv_capindex, target_p->serv->caps), sizeof(msgbuf));
735
736 return msgbuf + 1;
737 }
738
739 /*
740 * server_estab
741 *
742 * inputs - pointer to a struct Client
743 * output -
744 * side effects -
745 */
746 int
747 server_estab(struct Client *client_p)
748 {
749 struct Client *target_p;
750 struct server_conf *server_p;
751 hook_data_client hdata;
752 char *host;
753 rb_dlink_node *ptr;
754 char note[HOSTLEN + 15];
755
756 s_assert(NULL != client_p);
757 if(client_p == NULL)
758 return -1;
759
760 host = client_p->name;
761
762 if((server_p = client_p->localClient->att_sconf) == NULL)
763 {
764 /* This shouldn't happen, better tell the ops... -A1kmm */
765 sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
766 "Warning: Lost connect{} block for server %s!", host);
767 return exit_client(client_p, client_p, client_p, "Lost connect{} block!");
768 }
769
770 /* We shouldn't have to check this, it should already done before
771 * server_estab is called. -A1kmm
772 */
773 if(client_p->localClient->passwd)
774 {
775 memset(client_p->localClient->passwd, 0, strlen(client_p->localClient->passwd));
776 rb_free(client_p->localClient->passwd);
777 client_p->localClient->passwd = NULL;
778 }
779
780 /* Its got identd , since its a server */
781 SetGotId(client_p);
782
783 /* If there is something in the serv_list, it might be this
784 * connecting server..
785 */
786 if(!ServerInfo.hub && serv_list.head)
787 {
788 if(client_p != serv_list.head->data || serv_list.head->next)
789 {
790 ServerStats.is_ref++;
791 sendto_one(client_p, "ERROR :I'm a leaf not a hub");
792 return exit_client(client_p, client_p, client_p, "I'm a leaf");
793 }
794 }
795
796 if(IsUnknown(client_p))
797 {
798 /* the server may be linking based on certificate fingerprint now. --nenolod */
799 sendto_one(client_p, "PASS %s TS %d :%s",
800 EmptyString(server_p->spasswd) ? "*" : server_p->spasswd, TS_CURRENT, me.id);
801
802 /* pass info to new server */
803 send_capabilities(client_p, default_server_capabs
804 | (ServerConfCompressed(server_p) ? CAP_ZIP_SUPPORTED : 0)
805 | (ServerConfTb(server_p) ? CAP_TB : 0));
806
807 sendto_one(client_p, "SERVER %s 1 :%s%s",
808 me.name,
809 ConfigServerHide.hidden ? "(H) " : "",
810 (me.info[0]) ? (me.info) : "IRCers United");
811 }
812
813 if(!rb_set_buffers(client_p->localClient->F, READBUF_SIZE))
814 ilog_error("rb_set_buffers failed for server");
815
816 /* Enable compression now */
817 if(IsCapable(client_p, CAP_ZIP))
818 {
819 start_zlib_session(client_p);
820 }
821 sendto_one(client_p, "SVINFO %d %d 0 :%ld", TS_CURRENT, TS_MIN, (long int)rb_current_time());
822
823 client_p->servptr = &me;
824
825 if(IsAnyDead(client_p))
826 return CLIENT_EXITED;
827
828 SetServer(client_p);
829
830 rb_dlinkAdd(client_p, &client_p->lnode, &me.serv->servers);
831 rb_dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &serv_list);
832 rb_dlinkAddTailAlloc(client_p, &global_serv_list);
833
834 if(has_id(client_p))
835 add_to_id_hash(client_p->id, client_p);
836
837 add_to_client_hash(client_p->name, client_p);
838 /* doesnt duplicate client_p->serv if allocated this struct already */
839 make_server(client_p);
840
841 client_p->serv->caps = client_p->localClient->caps;
842
843 if(client_p->localClient->fullcaps)
844 {
845 client_p->serv->fullcaps = rb_strdup(client_p->localClient->fullcaps);
846 rb_free(client_p->localClient->fullcaps);
847 client_p->localClient->fullcaps = NULL;
848 }
849
850 client_p->serv->nameinfo = scache_connect(client_p->name, client_p->info, IsHidden(client_p));
851 client_p->localClient->firsttime = rb_current_time();
852 /* fixing eob timings.. -gnp */
853
854 if((rb_dlink_list_length(&lclient_list) + rb_dlink_list_length(&serv_list)) >
855 (unsigned long)MaxConnectionCount)
856 MaxConnectionCount = rb_dlink_list_length(&lclient_list) +
857 rb_dlink_list_length(&serv_list);
858
859 /* Show the real host/IP to admins */
860 sendto_realops_snomask(SNO_GENERAL, L_ALL,
861 "Link with %s established: (%s) link",
862 client_p->name,
863 show_capabilities(client_p));
864
865 ilog(L_SERVER, "Link with %s established: (%s) link",
866 log_client_name(client_p, SHOW_IP), show_capabilities(client_p));
867
868 hdata.client = &me;
869 hdata.target = client_p;
870 call_hook(h_server_introduced, &hdata);
871
872 rb_snprintf(note, sizeof(note), "Server: %s", client_p->name);
873 rb_note(client_p->localClient->F, note);
874
875 /*
876 ** Old sendto_serv_but_one() call removed because we now
877 ** need to send different names to different servers
878 ** (domain name matching) Send new server to other servers.
879 */
880 RB_DLINK_FOREACH(ptr, serv_list.head)
881 {
882 target_p = ptr->data;
883
884 if(target_p == client_p)
885 continue;
886
887 if(has_id(target_p) && has_id(client_p))
888 {
889 sendto_one(target_p, ":%s SID %s 2 %s :%s%s",
890 me.id, client_p->name, client_p->id,
891 IsHidden(client_p) ? "(H) " : "", client_p->info);
892
893 if(!EmptyString(client_p->serv->fullcaps))
894 sendto_one(target_p, ":%s ENCAP * GCAP :%s",
895 client_p->id, client_p->serv->fullcaps);
896 }
897 else
898 {
899 sendto_one(target_p, ":%s SERVER %s 2 :%s%s",
900 me.name, client_p->name,
901 IsHidden(client_p) ? "(H) " : "", client_p->info);
902
903 if(!EmptyString(client_p->serv->fullcaps))
904 sendto_one(target_p, ":%s ENCAP * GCAP :%s",
905 client_p->name, client_p->serv->fullcaps);
906 }
907 }
908
909 /*
910 ** Pass on my client information to the new server
911 **
912 ** First, pass only servers (idea is that if the link gets
913 ** cancelled beacause the server was already there,
914 ** there are no NICK's to be cancelled...). Of course,
915 ** if cancellation occurs, all this info is sent anyway,
916 ** and I guess the link dies when a read is attempted...? --msa
917 **
918 ** Note: Link cancellation to occur at this point means
919 ** that at least two servers from my fragment are building
920 ** up connection this other fragment at the same time, it's
921 ** a race condition, not the normal way of operation...
922 **
923 ** ALSO NOTE: using the get_client_name for server names--
924 ** see previous *WARNING*!!! (Also, original inpath
925 ** is destroyed...)
926 */
927 RB_DLINK_FOREACH(ptr, global_serv_list.head)
928 {
929 target_p = ptr->data;
930
931 /* target_p->from == target_p for target_p == client_p */
932 if(IsMe(target_p) || target_p->from == client_p)
933 continue;
934
935 /* presumption, if target has an id, so does its uplink */
936 if(has_id(client_p) && has_id(target_p))
937 sendto_one(client_p, ":%s SID %s %d %s :%s%s",
938 target_p->servptr->id, target_p->name,
939 target_p->hopcount + 1, target_p->id,
940 IsHidden(target_p) ? "(H) " : "", target_p->info);
941 else
942 sendto_one(client_p, ":%s SERVER %s %d :%s%s",
943 target_p->servptr->name,
944 target_p->name, target_p->hopcount + 1,
945 IsHidden(target_p) ? "(H) " : "", target_p->info);
946
947 if(!EmptyString(target_p->serv->fullcaps))
948 sendto_one(client_p, ":%s ENCAP * GCAP :%s",
949 get_id(target_p, client_p),
950 target_p->serv->fullcaps);
951 }
952
953 if(IsCapable(client_p, CAP_BAN))
954 burst_ban(client_p);
955
956 burst_TS6(client_p);
957
958 /* Always send a PING after connect burst is done */
959 sendto_one(client_p, "PING :%s", get_id(&me, client_p));
960
961 free_pre_client(client_p);
962
963 send_pop_queue(client_p);
964
965 return 0;
966 }
967
968 /*
969 * New server connection code
970 * Based upon the stuff floating about in s_bsd.c
971 * -- adrian
972 */
973
974 static int
975 serv_connect_resolved(struct Client *client_p)
976 {
977 struct rb_sockaddr_storage myipnum;
978 char vhoststr[HOSTIPLEN];
979 struct server_conf *server_p;
980 uint16_t port;
981
982 if((server_p = client_p->localClient->att_sconf) == NULL)
983 {
984 sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL, "Lost connect{} block for %s",
985 client_p->name);
986 exit_client(client_p, client_p, &me, "Lost connect{} block");
987 return 0;
988 }
989
990 #ifdef RB_IPV6
991 if(client_p->localClient->ip.ss_family == AF_INET6)
992 port = ntohs(((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port);
993 else
994 #endif
995 port = ntohs(((struct sockaddr_in *)&client_p->localClient->ip)->sin_port);
996
997 if(ServerConfVhosted(server_p))
998 {
999 memcpy(&myipnum, &server_p->my_ipnum, sizeof(myipnum));
1000 ((struct sockaddr_in *)&myipnum)->sin_port = 0;
1001 myipnum.ss_family = server_p->aftype;
1002
1003 }
1004 else if(server_p->aftype == AF_INET && ServerInfo.specific_ipv4_vhost)
1005 {
1006 memcpy(&myipnum, &ServerInfo.ip, sizeof(myipnum));
1007 ((struct sockaddr_in *)&myipnum)->sin_port = 0;
1008 myipnum.ss_family = AF_INET;
1009 SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in));
1010 }
1011
1012 #ifdef RB_IPV6
1013 else if((server_p->aftype == AF_INET6) && ServerInfo.specific_ipv6_vhost)
1014 {
1015 memcpy(&myipnum, &ServerInfo.ip6, sizeof(myipnum));
1016 ((struct sockaddr_in6 *)&myipnum)->sin6_port = 0;
1017 myipnum.ss_family = AF_INET6;
1018 SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in6));
1019 }
1020 #endif
1021 else
1022 {
1023 /* log */
1024 ilog(L_SERVER, "Connecting to %s[%s] port %d (%s)", client_p->name, client_p->sockhost, port,
1025 #ifdef RB_IPV6
1026 server_p->aftype == AF_INET6 ? "IPv6" :
1027 #endif
1028 (server_p->aftype == AF_INET ? "IPv4" : "?"));
1029
1030 if(ServerConfSSL(server_p))
1031 {
1032 rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip,
1033 NULL, 0, serv_connect_ssl_callback,
1034 client_p, ConfigFileEntry.connect_timeout);
1035 }
1036 else
1037 rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip,
1038 NULL, 0, serv_connect_callback,
1039 client_p, ConfigFileEntry.connect_timeout);
1040 return 1;
1041 }
1042
1043 /* log */
1044 rb_inet_ntop_sock((struct sockaddr *)&myipnum, vhoststr, sizeof vhoststr);
1045 ilog(L_SERVER, "Connecting to %s[%s] port %d (%s) (vhost %s)", client_p->name, client_p->sockhost, port,
1046 #ifdef RB_IPV6
1047 server_p->aftype == AF_INET6 ? "IPv6" :
1048 #endif
1049 (server_p->aftype == AF_INET ? "IPv4" : "?"), vhoststr);
1050
1051
1052 if(ServerConfSSL(server_p))
1053 rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip,
1054 (struct sockaddr *) &myipnum,
1055 GET_SS_LEN(&myipnum), serv_connect_ssl_callback, client_p,
1056 ConfigFileEntry.connect_timeout);
1057 else
1058 rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip,
1059 (struct sockaddr *) &myipnum,
1060 GET_SS_LEN(&myipnum), serv_connect_callback, client_p,
1061 ConfigFileEntry.connect_timeout);
1062
1063 return 1;
1064 }
1065
1066 static void
1067 serv_connect_dns_callback(void *vptr, struct DNSReply *reply)
1068 {
1069 struct Client *client_p = vptr;
1070 uint16_t port;
1071
1072 rb_free(client_p->localClient->dnsquery);
1073 client_p->localClient->dnsquery = NULL;
1074
1075 if (reply == NULL)
1076 {
1077 sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL, "Cannot resolve hostname for %s",
1078 client_p->name);
1079 ilog(L_SERVER, "Cannot resolve hostname for %s",
1080 log_client_name(client_p, HIDE_IP));
1081 exit_client(client_p, client_p, &me, "Cannot resolve hostname");
1082 return;
1083 }
1084 #ifdef RB_IPV6
1085 if(reply->addr.ss_family == AF_INET6)
1086 port = ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port;
1087 else
1088 #endif
1089 port = ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port;
1090 memcpy(&client_p->localClient->ip, &reply->addr, sizeof(client_p->localClient->ip));
1091 #ifdef RB_IPV6
1092 if(reply->addr.ss_family == AF_INET6)
1093 ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = port;
1094 else
1095 #endif
1096 ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = port;
1097 /* Set sockhost properly now -- jilles */
1098 rb_inet_ntop_sock((struct sockaddr *)&client_p->localClient->ip,
1099 client_p->sockhost, sizeof client_p->sockhost);
1100 serv_connect_resolved(client_p);
1101 }
1102
1103 /*
1104 * serv_connect() - initiate a server connection
1105 *
1106 * inputs - pointer to conf
1107 * - pointer to client doing the connet
1108 * output -
1109 * side effects -
1110 *
1111 * This code initiates a connection to a server. It first checks to make
1112 * sure the given server exists. If this is the case, it creates a socket,
1113 * creates a client, saves the socket information in the client, and
1114 * initiates a connection to the server through rb_connect_tcp(). The
1115 * completion of this goes through serv_completed_connection().
1116 *
1117 * We return 1 if the connection is attempted, since we don't know whether
1118 * it suceeded or not, and 0 if it fails in here somewhere.
1119 */
1120 int
1121 serv_connect(struct server_conf *server_p, struct Client *by)
1122 {
1123 struct Client *client_p;
1124 struct rb_sockaddr_storage theiripnum;
1125 rb_fde_t *F;
1126 char note[HOSTLEN + 10];
1127
1128 s_assert(server_p != NULL);
1129 if(server_p == NULL)
1130 return 0;
1131
1132 /*
1133 * Make sure this server isn't already connected
1134 */
1135 if((client_p = find_server(NULL, server_p->name)))
1136 {
1137 sendto_realops_snomask(SNO_GENERAL, L_ALL,
1138 "Server %s already present from %s",
1139 server_p->name, client_p->name);
1140 if(by && IsPerson(by) && !MyClient(by))
1141 sendto_one_notice(by, ":Server %s already present from %s",
1142 server_p->name, client_p->name);
1143 return 0;
1144 }
1145
1146 /* create a socket for the server connection */
1147 if((F = rb_socket(server_p->aftype, SOCK_STREAM, 0, NULL)) == NULL)
1148 {
1149 ilog_error("opening a stream socket");
1150 return 0;
1151 }
1152
1153 rb_snprintf(note, sizeof note, "Server: %s", server_p->name);
1154 rb_note(F, note);
1155
1156 /* Create a local client */
1157 client_p = make_client(NULL);
1158
1159 /* Copy in the server, hostname, fd
1160 * The sockhost may be a hostname, this will be corrected later
1161 * -- jilles
1162 */
1163 rb_strlcpy(client_p->name, server_p->name, sizeof(client_p->name));
1164 rb_strlcpy(client_p->host, server_p->host, sizeof(client_p->host));
1165 rb_strlcpy(client_p->sockhost, server_p->host, sizeof(client_p->sockhost));
1166 client_p->localClient->F = F;
1167 add_to_cli_fd_hash(client_p);
1168
1169 /*
1170 * Set up the initial server evilness, ripped straight from
1171 * connect_server(), so don't blame me for it being evil.
1172 * -- adrian
1173 */
1174
1175 if(!rb_set_buffers(client_p->localClient->F, READBUF_SIZE))
1176 {
1177 ilog_error("setting the buffer size for a server connection");
1178 }
1179
1180 /*
1181 * Attach config entries to client here rather than in
1182 * serv_connect_callback(). This to avoid null pointer references.
1183 */
1184 attach_server_conf(client_p, server_p);
1185
1186 /*
1187 * at this point we have a connection in progress and C/N lines
1188 * attached to the client, the socket info should be saved in the
1189 * client and it should either be resolved or have a valid address.
1190 *
1191 * The socket has been connected or connect is in progress.
1192 */
1193 make_server(client_p);
1194 if(by && IsPerson(by))
1195 {
1196 rb_strlcpy(client_p->serv->by, by->name,
1197 sizeof client_p->serv->by);
1198 if(client_p->serv->user)
1199 free_user(client_p->serv->user, NULL);
1200 client_p->serv->user = by->user;
1201 by->user->refcnt++;
1202 }
1203 else
1204 {
1205 rb_strlcpy(client_p->serv->by, "AutoConn.",
1206 sizeof client_p->serv->by);
1207 if(client_p->serv->user)
1208 free_user(client_p->serv->user, NULL);
1209 client_p->serv->user = NULL;
1210 }
1211 SetConnecting(client_p);
1212 rb_dlinkAddTail(client_p, &client_p->node, &global_client_list);
1213
1214 if (rb_inet_pton_sock(server_p->host, (struct sockaddr *)&theiripnum) > 0)
1215 {
1216 memcpy(&client_p->localClient->ip, &theiripnum, sizeof(client_p->localClient->ip));
1217 #ifdef RB_IPV6
1218 if(theiripnum.ss_family == AF_INET6)
1219 ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = htons(server_p->port);
1220 else
1221 #endif
1222 ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = htons(server_p->port);
1223
1224 return serv_connect_resolved(client_p);
1225 }
1226 else
1227 {
1228 #ifdef RB_IPV6
1229 if(theiripnum.ss_family == AF_INET6)
1230 ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = htons(server_p->port);
1231 else
1232 #endif
1233 ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = htons(server_p->port);
1234
1235 client_p->localClient->dnsquery = rb_malloc(sizeof(struct DNSQuery));
1236 client_p->localClient->dnsquery->ptr = client_p;
1237 client_p->localClient->dnsquery->callback = serv_connect_dns_callback;
1238 gethost_byname_type(server_p->host, client_p->localClient->dnsquery,
1239 #ifdef RB_IPV6
1240 server_p->aftype == AF_INET6 ? T_AAAA :
1241 #endif
1242 T_A);
1243 return 1;
1244 }
1245 }
1246
1247 static void
1248 serv_connect_ssl_callback(rb_fde_t *F, int status, void *data)
1249 {
1250 struct Client *client_p = data;
1251 rb_fde_t *xF[2];
1252 rb_connect_sockaddr(F, (struct sockaddr *)&client_p->localClient->ip, sizeof(client_p->localClient->ip));
1253 if(status != RB_OK)
1254 {
1255 /* Print error message, just like non-SSL. */
1256 serv_connect_callback(F, status, data);
1257 return;
1258 }
1259 if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Outgoing ssld connection") == -1)
1260 {
1261 ilog_error("rb_socketpair failed for server");
1262 serv_connect_callback(F, RB_ERROR, data);
1263 return;
1264
1265 }
1266 del_from_cli_fd_hash(client_p);
1267 client_p->localClient->F = xF[0];
1268 add_to_cli_fd_hash(client_p);
1269
1270 client_p->localClient->ssl_ctl = start_ssld_connect(F, xF[1], rb_get_fd(xF[0]));
1271 SetSSL(client_p);
1272 serv_connect_callback(client_p->localClient->F, RB_OK, client_p);
1273 }
1274
1275 /*
1276 * serv_connect_callback() - complete a server connection.
1277 *
1278 * This routine is called after the server connection attempt has
1279 * completed. If unsucessful, an error is sent to ops and the client
1280 * is closed. If sucessful, it goes through the initialisation/check
1281 * procedures, the capabilities are sent, and the socket is then
1282 * marked for reading.
1283 */
1284 static void
1285 serv_connect_callback(rb_fde_t *F, int status, void *data)
1286 {
1287 struct Client *client_p = data;
1288 struct server_conf *server_p;
1289 char *errstr;
1290
1291 /* First, make sure its a real client! */
1292 s_assert(client_p != NULL);
1293 s_assert(client_p->localClient->F == F);
1294
1295 if(client_p == NULL)
1296 return;
1297
1298 /* while we were waiting for the callback, its possible this already
1299 * linked in.. --fl
1300 */
1301 if(find_server(NULL, client_p->name) != NULL)
1302 {
1303 exit_client(client_p, client_p, &me, "Server Exists");
1304 return;
1305 }
1306
1307 if(client_p->localClient->ssl_ctl == NULL)
1308 rb_connect_sockaddr(F, (struct sockaddr *)&client_p->localClient->ip, sizeof(client_p->localClient->ip));
1309
1310 /* Check the status */
1311 if(status != RB_OK)
1312 {
1313 /* COMM_ERR_TIMEOUT wont have an errno associated with it,
1314 * the others will.. --fl
1315 */
1316 if(status == RB_ERR_TIMEOUT)
1317 {
1318 sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
1319 "Error connecting to %s[%s]: %s",
1320 client_p->name,
1321 "255.255.255.255",
1322 rb_errstr(status));
1323 ilog(L_SERVER, "Error connecting to %s[%s]: %s",
1324 client_p->name, client_p->sockhost,
1325 rb_errstr(status));
1326 }
1327 else
1328 {
1329 errstr = strerror(rb_get_sockerr(F));
1330 sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
1331 "Error connecting to %s[%s]: %s (%s)",
1332 client_p->name,
1333 "255.255.255.255",
1334 rb_errstr(status), errstr);
1335 ilog(L_SERVER, "Error connecting to %s[%s]: %s (%s)",
1336 client_p->name, client_p->sockhost,
1337 rb_errstr(status), errstr);
1338 }
1339
1340 exit_client(client_p, client_p, &me, rb_errstr(status));
1341 return;
1342 }
1343
1344 /* COMM_OK, so continue the connection procedure */
1345 /* Get the C/N lines */
1346 if((server_p = client_p->localClient->att_sconf) == NULL)
1347 {
1348 sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL, "Lost connect{} block for %s",
1349 client_p->name);
1350 exit_client(client_p, client_p, &me, "Lost connect{} block");
1351 return;
1352 }
1353
1354 /* Next, send the initial handshake */
1355 SetHandshake(client_p);
1356
1357 /* the server may be linking based on certificate fingerprint now. --nenolod */
1358 sendto_one(client_p, "PASS %s TS %d :%s",
1359 EmptyString(server_p->spasswd) ? "*" : server_p->spasswd, TS_CURRENT, me.id);
1360
1361 /* pass my info to the new server */
1362 send_capabilities(client_p, default_server_capabs
1363 | (ServerConfCompressed(server_p) ? CAP_ZIP_SUPPORTED : 0)
1364 | (ServerConfTb(server_p) ? CAP_TB : 0));
1365
1366 sendto_one(client_p, "SERVER %s 1 :%s%s",
1367 me.name,
1368 ConfigServerHide.hidden ? "(H) " : "", me.info);
1369
1370 /*
1371 * If we've been marked dead because a send failed, just exit
1372 * here now and save everyone the trouble of us ever existing.
1373 */
1374 if(IsAnyDead(client_p))
1375 {
1376 sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
1377 "%s went dead during handshake", client_p->name);
1378 exit_client(client_p, client_p, &me, "Went dead during handshake");
1379 return;
1380 }
1381
1382 /* don't move to serv_list yet -- we haven't sent a burst! */
1383
1384 /* If we get here, we're ok, so lets start reading some data */
1385 read_packet(F, client_p);
1386 }