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