ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/server.c
Revision: 9213
Committed: Sat Jan 25 23:20:08 2020 UTC (5 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 18984 byte(s)
Log Message:
- server_tls_handshake(), ssl_handshake(): make use of client_get_name()

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2916 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 9101 * Copyright (c) 1997-2020 ircd-hybrid development team
5 adx 30 *
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 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 adx 30 * USA
20     */
21    
22 michael 8426 /*! \file server.c
23 michael 2916 * \brief Server related functions.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 michael 1011 #include "list.h"
29 adx 30 #include "client.h"
30     #include "event.h"
31     #include "hash.h"
32     #include "irc_string.h"
33     #include "ircd.h"
34     #include "ircd_defs.h"
35     #include "s_bsd.h"
36     #include "packet.h"
37 michael 1309 #include "conf.h"
38 michael 3347 #include "server.h"
39 michael 8166 #include "server_capab.h"
40 michael 1309 #include "log.h"
41 adx 30 #include "send.h"
42     #include "memory.h"
43 michael 1243 #include "parse.h"
44 adx 30
45 michael 6527
46 michael 2156 dlink_list flatten_links;
47 michael 8426 static void server_connect_callback(fde_t *, int, void *);
48 adx 30
49    
50     /*
51     * write_links_file
52     *
53     * inputs - void pointer which is not used
54     * output - NONE
55     * side effects - called from an event, write out list of linked servers
56     * but in no particular order.
57     */
58     void
59 michael 4439 write_links_file(void *unused)
60 adx 30 {
61 michael 9202 char buf[IRCD_BUFSIZE];
62 michael 7995 dlink_node *node, *node_next;
63 adx 30
64 michael 6599 if (EmptyString(ConfigServerHide.flatten_links_file))
65 adx 30 return;
66    
67 michael 9202 FILE *file = fopen(ConfigServerHide.flatten_links_file, "w");
68     if (file == NULL)
69 michael 6602 {
70     ilog(LOG_TYPE_IRCD, "Couldn't open \"%s\": %s", ConfigServerHide.flatten_links_file,
71     strerror(errno));
72 michael 6599 return;
73 michael 6602 }
74 michael 6599
75 michael 4815 DLINK_FOREACH_SAFE(node, node_next, flatten_links.head)
76 adx 30 {
77 michael 4815 dlinkDelete(node, &flatten_links);
78 michael 7032 xfree(node->data);
79 michael 4815 free_dlink_node(node);
80 adx 30 }
81    
82 michael 4815 DLINK_FOREACH(node, global_server_list.head)
83 adx 30 {
84 michael 4815 const struct Client *target_p = node->data;
85 adx 30
86 michael 2156 /*
87     * Skip hidden servers, aswell as ourselves, since we already send
88     * ourselves in /links
89     */
90     if (IsHidden(target_p) || IsMe(target_p))
91 adx 30 continue;
92    
93 michael 1851 if (HasFlag(target_p, FLAGS_SERVICE) && ConfigServerHide.hide_services)
94     continue;
95    
96 michael 1545 /*
97     * Attempt to format the file in such a way it follows the usual links output
98 adx 30 * ie "servername uplink :hops info"
99     * Mostly for aesthetic reasons - makes it look pretty in mIRC ;)
100     * - madmax
101     */
102 michael 9202 snprintf(buf, sizeof(buf), "%s %s :1 %s", target_p->name, me.name, target_p->info);
103     dlinkAddTail(xstrdup(buf), make_dlink_node(), &flatten_links);
104 adx 30
105 michael 9202 strlcat(buf, "\n", sizeof(buf));
106     fputs(buf, file);
107 adx 30 }
108    
109 michael 1325 fclose(file);
110 adx 30 }
111    
112 michael 2216 void
113     read_links_file(void)
114     {
115 michael 9202 char buf[IRCD_BUFSIZE];
116 michael 2216
117 michael 6599 if (EmptyString(ConfigServerHide.flatten_links_file))
118 michael 2216 return;
119    
120 michael 9202 FILE *file = fopen(ConfigServerHide.flatten_links_file, "r");
121     if (file == NULL)
122 michael 6602 {
123     ilog(LOG_TYPE_IRCD, "Couldn't open \"%s\": %s", ConfigServerHide.flatten_links_file,
124     strerror(errno));
125 michael 6599 return;
126 michael 6602 }
127 michael 6599
128 michael 9202 while (fgets(buf, sizeof(buf), file))
129 michael 2216 {
130 michael 9202 char *p = strchr(buf, '\n');
131     if (p)
132 michael 2216 *p = '\0';
133    
134 michael 9202 dlinkAddTail(xstrdup(buf), make_dlink_node(), &flatten_links);
135 michael 2216 }
136    
137     fclose(file);
138     }
139    
140 michael 7953 /* server_hunt()
141 adx 30 * Do the basic thing in delivering the message (command)
142     * across the relays to the specific server (server) for
143     * actions.
144     *
145     * Note: The command is a format string and *MUST* be
146     * of prefixed style (e.g. ":%s COMMAND %s ...").
147     * Command can have only max 8 parameters.
148     *
149     * server parv[server] is the parameter identifying the
150     * target server.
151     *
152     * *WARNING*
153     * parv[server] is replaced with the pointer to the
154     * real servername from the matched client (I'm lazy
155     * now --msa).
156     *
157     * returns: (see #defines)
158     */
159 michael 7973 const struct server_hunt *
160 michael 7953 server_hunt(struct Client *source_p, const char *command,
161 michael 1857 const int server, const int parc, char *parv[])
162 adx 30 {
163 michael 7971 static struct server_hunt hunt;
164 michael 7995 struct server_hunt *const h = &hunt;
165 michael 7971 dlink_node *node;
166 adx 30
167 michael 1344 /* Assume it's me, if no server */
168     if (parc <= server || EmptyString(parv[server]))
169 michael 7971 {
170 michael 7991 h->target_p = &me;
171 michael 7971 h->ret = HUNTED_ISME;
172     return h;
173     }
174 adx 30
175 michael 9202 h->target_p = find_person(source_p, parv[server]);
176     if (h->target_p == NULL)
177 michael 7971 h->target_p = hash_find_server(parv[server]);
178 michael 1344
179 michael 4206 /*
180     * These are to pickup matches that would cause the following
181 adx 30 * message to go in the wrong direction while doing quick fast
182     * non-matching lookups.
183     */
184 michael 7971 if (h->target_p)
185     if (h->target_p->from == source_p->from && !MyConnect(h->target_p))
186     h->target_p = NULL;
187 adx 30
188 michael 8512 if (h->target_p == NULL && has_wildcards(parv[server]))
189 adx 30 {
190 michael 6060 DLINK_FOREACH(node, global_server_list.head)
191 adx 30 {
192 michael 4815 struct Client *tmp = node->data;
193 michael 4206
194 michael 6060 assert(IsMe(tmp) || IsServer(tmp));
195 michael 8512 if (match(parv[server], tmp->name) == 0)
196 adx 30 {
197 michael 4206 if (tmp->from == source_p->from && !MyConnect(tmp))
198     continue;
199 michael 4210
200 michael 7991 h->target_p = tmp;
201 michael 4210 break;
202 adx 30 }
203     }
204 michael 6060
205 michael 8512 if (h->target_p == NULL)
206 michael 6060 {
207     DLINK_FOREACH(node, global_client_list.head)
208     {
209     struct Client *tmp = node->data;
210    
211 michael 7963 assert(IsClient(tmp));
212 michael 8512 if (match(parv[server], tmp->name) == 0)
213 michael 6060 {
214     if (tmp->from == source_p->from && !MyConnect(tmp))
215     continue;
216    
217 michael 7991 h->target_p = tmp;
218 michael 6060 break;
219     }
220     }
221     }
222 adx 30 }
223    
224 michael 7971 if (h->target_p)
225 adx 30 {
226 michael 7971 assert(IsMe(h->target_p) || IsServer(h->target_p) || IsClient(h->target_p));
227     if (IsMe(h->target_p) || MyClient(h->target_p))
228     {
229     h->ret = HUNTED_ISME;
230     return h;
231     }
232 adx 30
233 michael 7971 parv[server] = h->target_p->id;
234     sendto_one(h->target_p, command, source_p->id,
235 adx 30 parv[1], parv[2], parv[3], parv[4],
236     parv[5], parv[6], parv[7], parv[8]);
237 michael 7971 h->ret = HUNTED_PASS;
238     return h;
239 michael 2345 }
240 adx 30
241 michael 3109 sendto_one_numeric(source_p, &me, ERR_NOSUCHSERVER, parv[server]);
242 michael 7971 h->ret = HUNTED_NOSUCH;
243     return h;
244 adx 30 }
245    
246     /* try_connections()
247     *
248     * inputs - void pointer which is not used
249     * output - NONE
250     * side effects -
251     * scan through configuration and try new connections.
252     * Returns the calendar time when the next call to this
253     * function should be made latest. (No harm done if this
254     * is called earlier or later...)
255     */
256     void
257     try_connections(void *unused)
258     {
259 michael 7995 dlink_node *node;
260 adx 30
261 michael 8800 if (GlobalSetOptions.autoconn == false)
262 adx 30 return;
263    
264 michael 7401 DLINK_FOREACH(node, connect_items.head)
265 adx 30 {
266 michael 4815 struct MaskItem *conf = node->data;
267 adx 30
268 michael 1636 assert(conf->type == CONF_SERVER);
269 michael 7995 assert(conf->class);
270 michael 1632
271 michael 6721 /* Also when already connecting! (update holdtimes) --SRB */
272 michael 8437 if (conf->port == 0 || !IsConfAllowAutoConn(conf))
273 adx 30 continue;
274    
275 michael 6721 /*
276     * Skip this entry if the use of it is still on hold until
277 adx 30 * future. Otherwise handle this entry (and set it on hold
278     * until next time). Will reset only hold times, if already
279     * made one successfull connection... [this algorithm is
280     * a bit fuzzy... -- msa >;) ]
281     */
282 michael 8980 if (conf->until > event_base->time.sec_monotonic)
283 adx 30 continue;
284    
285 michael 8980 conf->until = event_base->time.sec_monotonic + conf->class->con_freq;
286 michael 4028
287 michael 3246 /*
288     * Found a CONNECT config with port specified, scan clients
289 adx 30 * and see if this server is already connected?
290     */
291 michael 3246 if (hash_find_server(conf->name))
292 adx 30 continue;
293    
294 michael 1632 if (conf->class->ref_count < conf->class->max_total)
295 adx 30 {
296 michael 6390 /* Move this entry to the end of the list, if not already last */
297 michael 4815 if (node->next)
298 adx 30 {
299 michael 7401 dlinkDelete(node, &connect_items);
300     dlinkAddTail(conf, &conf->node, &connect_items);
301 adx 30 }
302    
303     if (find_servconn_in_progress(conf->name))
304     return;
305    
306 michael 3246 /*
307 michael 8426 * We used to only print this if server_connect() actually
308 adx 30 * succeeded, but since comm_tcp_connect() can call the callback
309     * immediately if there is an error, we were getting error messages
310     * in the wrong order. SO, we just print out the activated line,
311 michael 8426 * and let server_connect() / server_connect_callback() print an
312 adx 30 * error afterwards if it fails.
313     * -- adrian
314     */
315     if (ConfigServerHide.hide_server_ips)
316 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
317 michael 1618 "Connection to %s activated.",
318 adx 30 conf->name);
319     else
320 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
321 michael 1618 "Connection to %s[%s] activated.",
322 michael 1632 conf->name, conf->host);
323 adx 30
324 michael 8426 server_connect(conf, NULL);
325 adx 30 /* We connect only one at time... */
326     return;
327     }
328     }
329     }
330    
331 michael 8660 bool
332 michael 8437 server_valid_name(const char *name)
333 michael 1115 {
334 michael 3451 unsigned int dots = 0;
335 michael 1115 const char *p = name;
336    
337     for (; *p; ++p)
338     {
339     if (!IsServChar(*p))
340 michael 8660 return false;
341 michael 1115
342     if (*p == '.')
343     ++dots;
344     }
345    
346 michael 3451 return dots && (p - name) <= HOSTLEN;
347 michael 1115 }
348    
349 michael 8426 /* server_make()
350 adx 30 *
351     * inputs - pointer to client struct
352     * output - pointer to struct Server
353     * side effects - add's an Server information block to a client
354     * if it was not previously allocated.
355     */
356     struct Server *
357 michael 8426 server_make(struct Client *client_p)
358 adx 30 {
359     if (client_p->serv == NULL)
360 michael 8310 client_p->serv = xcalloc(sizeof(*client_p->serv));
361 adx 30
362     return client_p->serv;
363     }
364    
365 michael 8426 /* server_connect() - initiate a server connection
366 adx 30 *
367 michael 2345 * inputs - pointer to conf
368 adx 30 * - pointer to client doing the connect
369     * output -
370     * side effects -
371     *
372     * This code initiates a connection to a server. It first checks to make
373     * sure the given server exists. If this is the case, it creates a socket,
374     * creates a client, saves the socket information in the client, and
375     * initiates a connection to the server through comm_connect_tcp(). The
376     * completion of this goes through serv_completed_connection().
377     *
378     * We return 1 if the connection is attempted, since we don't know whether
379     * it suceeded or not, and 0 if it fails in here somewhere.
380     */
381 michael 8660 bool
382 michael 8426 server_connect(struct MaskItem *conf, struct Client *by)
383 adx 30 {
384 michael 9202 char buf[HOSTIPLEN + 1];
385 adx 30
386 michael 1632 /* Make sure conf is useful */
387 michael 3246 assert(conf);
388 michael 8391 assert(conf->type == CONF_SERVER);
389     assert(hash_find_server(conf->name) == NULL); /* This should have been checked by the caller */
390 adx 30
391     /* Still processing a DNS lookup? -> exit */
392 michael 8658 if (conf->dns_pending == true)
393 adx 30 {
394 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
395 michael 992 "Error connecting to %s: DNS lookup for connect{} in progress.",
396     conf->name);
397 michael 8660 return false;
398 adx 30 }
399    
400 michael 8658 if (conf->dns_failed == true)
401 michael 992 {
402 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
403 michael 992 "Error connecting to %s: DNS lookup for connect{} failed.",
404     conf->name);
405 michael 8660 return false;
406 michael 992 }
407    
408 michael 8872 getnameinfo((const struct sockaddr *)conf->addr, conf->addr->ss_len,
409     buf, sizeof(buf), NULL, 0, NI_NUMERICHOST);
410     ilog(LOG_TYPE_IRCD, "Connect to %s[%s] @%s", conf->name, conf->host, buf);
411    
412 michael 8391 /* Create a socket for the server connection */
413 michael 8872 int fd = comm_socket(conf->addr->ss.ss_family, SOCK_STREAM, 0);
414 michael 8391 if (fd == -1)
415 michael 2345 {
416 michael 8391 /* Eek, failure to create the socket */
417     report_error(L_ALL, "opening stream socket to %s: %s", conf->name, errno);
418 michael 8660 return false;
419 adx 30 }
420 michael 2345
421 adx 30 /* Create a local client */
422 michael 8391 struct Client *client_p = client_make(NULL);
423 adx 30
424     /* Copy in the server, hostname, fd */
425     strlcpy(client_p->name, conf->name, sizeof(client_p->name));
426 michael 1632 strlcpy(client_p->host, conf->host, sizeof(client_p->host));
427 adx 30
428     /* We already converted the ip once, so lets use it - stu */
429 michael 1115 strlcpy(client_p->sockhost, buf, sizeof(client_p->sockhost));
430 adx 30
431 michael 9003 client_p->ip = *conf->addr;
432 michael 8658 client_p->connection->fd = fd_open(fd, true, NULL);
433 michael 8339
434 michael 6725 /* Server names are always guaranteed under HOSTLEN chars */
435 michael 8339 fd_note(client_p->connection->fd, "Server: %s", client_p->name);
436 adx 30
437 michael 6725 /*
438 michael 8426 * Attach config entries to client here rather than in server_connect_callback().
439 michael 6725 * This to avoid null pointer references.
440 adx 30 */
441 michael 8395 conf_attach(client_p, conf);
442 michael 3110
443 michael 8426 server_make(client_p);
444 adx 30
445     if (by && IsClient(by))
446     strlcpy(client_p->serv->by, by->name, sizeof(client_p->serv->by));
447     else
448     strlcpy(client_p->serv->by, "AutoConn.", sizeof(client_p->serv->by));
449    
450     SetConnecting(client_p);
451    
452     /* Now, initiate the connection */
453 michael 8872 comm_connect_tcp(client_p->connection->fd, conf->addr, conf->port, conf->bind,
454 michael 9096 server_connect_callback, client_p, conf->timeout);
455 michael 4415
456 michael 8426 /*
457     * At this point we have a connection in progress and a connect {} block
458     * attached to the client, the socket info should be saved in the client
459     * and it should either be resolved or have a valid address.
460     *
461     * The socket has been connected or connect is in progress.
462     */
463 michael 8660 return true;
464 adx 30 }
465    
466 michael 1303 static void
467 michael 8426 server_finish_tls_handshake(struct Client *client_p)
468 michael 1303 {
469 michael 7588 const struct MaskItem *conf = find_conf_name(&client_p->connection->confs,
470     client_p->name, CONF_SERVER);
471 michael 9202 if (conf == NULL)
472 michael 1303 {
473 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
474 michael 7997 "Lost connect{} block for %s", client_get_name(client_p, SHOW_IP));
475 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_OPER, SEND_NOTICE,
476 michael 7997 "Lost connect{} block for %s", client_get_name(client_p, MASK_IP));
477 michael 1303
478 michael 3171 exit_client(client_p, "Lost connect{} block");
479 michael 1303 return;
480     }
481    
482 michael 8839 /* Next, send the initial handshake */
483     SetHandshake(client_p);
484    
485 michael 7355 sendto_one(client_p, "PASS %s TS %u %s", conf->spasswd, TS_CURRENT, me.id);
486 michael 1303
487 michael 8166 sendto_one(client_p, "CAPAB :%s", capab_get(NULL));
488 michael 1303
489     sendto_one(client_p, "SERVER %s 1 :%s%s",
490     me.name, ConfigServerHide.hidden ? "(H) " : "",
491     me.info);
492    
493     /* If we get here, we're ok, so lets start reading some data */
494 michael 8403 read_packet(client_p->connection->fd, client_p);
495 michael 1303 }
496    
497     static void
498 michael 8426 server_tls_handshake(fde_t *F, void *data)
499 michael 1303 {
500 michael 4461 struct Client *client_p = data;
501 michael 7105 const char *sslerr = NULL;
502 michael 1303
503 michael 8339 assert(client_p);
504     assert(client_p->connection);
505     assert(client_p->connection->fd);
506     assert(client_p->connection->fd == F);
507    
508 michael 9157 tls_handshake_status_t ret = tls_handshake(&F->tls, TLS_ROLE_CLIENT, &sslerr);
509 michael 7105 if (ret != TLS_HANDSHAKE_DONE)
510 michael 1303 {
511 michael 8943 if ((event_base->time.sec_monotonic - client_p->connection->created_monotonic) > TLS_HANDSHAKE_TIMEOUT)
512 michael 4732 {
513 michael 7105 exit_client(client_p, "Timeout during TLS handshake");
514 michael 4732 return;
515     }
516    
517 michael 7105 switch (ret)
518 michael 1303 {
519 michael 7105 case TLS_HANDSHAKE_WANT_WRITE:
520 michael 8339 comm_setselect(F, COMM_SELECT_WRITE,
521 michael 8943 server_tls_handshake, client_p, TLS_HANDSHAKE_TIMEOUT);
522 michael 1303 return;
523 michael 7105 case TLS_HANDSHAKE_WANT_READ:
524 michael 8339 comm_setselect(F, COMM_SELECT_READ,
525 michael 8943 server_tls_handshake, client_p, TLS_HANDSHAKE_TIMEOUT);
526 michael 1303 return;
527     default:
528 michael 1308 {
529 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
530 michael 1308 "Error connecting to %s: %s", client_p->name,
531 michael 7105 sslerr ? sslerr : "unknown TLS error");
532     exit_client(client_p, "Error during TLS handshake");
533 michael 1303 return;
534 michael 1308 }
535 michael 1303 }
536     }
537    
538 michael 8339 comm_settimeout(F, 0, NULL, NULL);
539 michael 4732
540 michael 9157 if (tls_verify_cert(&F->tls, ConfigServerInfo.message_digest_algorithm, &client_p->certfp) == false)
541 michael 9213 ilog(LOG_TYPE_IRCD, "Server %s gave bad TLS client certificate",
542     client_get_name(client_p, MASK_IP));
543 michael 2463
544 michael 8426 server_finish_tls_handshake(client_p);
545 michael 1303 }
546    
547     static void
548 michael 8426 server_tls_connect_init(struct Client *client_p, const struct MaskItem *conf, fde_t *F)
549 michael 1303 {
550 michael 8339 assert(client_p);
551     assert(client_p->connection);
552     assert(client_p->connection->fd);
553     assert(client_p->connection->fd == F);
554    
555 michael 9157 if (tls_new(&F->tls, F->fd, TLS_ROLE_CLIENT) == false)
556 michael 1303 {
557     SetDead(client_p);
558 michael 7105 exit_client(client_p, "TLS context initialization failed");
559 michael 1303 return;
560     }
561    
562 michael 1632 if (!EmptyString(conf->cipher_list))
563 michael 9157 tls_set_ciphers(&F->tls, conf->cipher_list);
564 michael 1306
565 michael 8426 server_tls_handshake(F, client_p);
566 michael 1303 }
567    
568 michael 8426 /* server_connect_callback() - complete a server connection.
569 michael 2345 *
570 adx 30 * This routine is called after the server connection attempt has
571     * completed. If unsucessful, an error is sent to ops and the client
572     * is closed. If sucessful, it goes through the initialisation/check
573     * procedures, the capabilities are sent, and the socket is then
574     * marked for reading.
575     */
576     static void
577 michael 8426 server_connect_callback(fde_t *F, int status, void *data)
578 adx 30 {
579 michael 6397 struct Client *const client_p = data;
580 adx 30
581 michael 4298 /* First, make sure it's a real client! */
582 michael 3246 assert(client_p);
583 michael 8339 assert(client_p->connection);
584     assert(client_p->connection->fd);
585     assert(client_p->connection->fd == F);
586 adx 30
587     /* Check the status */
588     if (status != COMM_OK)
589     {
590 michael 6428 /* We have an error, so report it and quit */
591     sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
592     "Error connecting to %s: %s",
593 michael 7997 client_get_name(client_p, SHOW_IP), comm_errstr(status));
594 michael 6428 sendto_realops_flags(UMODE_SERVNOTICE, L_OPER, SEND_NOTICE,
595     "Error connecting to %s: %s",
596 michael 7997 client_get_name(client_p, MASK_IP), comm_errstr(status));
597 michael 6428
598     /*
599     * If a fd goes bad, call dead_link() the socket is no
600     * longer valid for reading or writing.
601 adx 30 */
602 michael 6428 dead_link_on_write(client_p, 0);
603     return;
604 adx 30 }
605    
606     /* COMM_OK, so continue the connection procedure */
607 michael 7588 /* Get the connect {} block */
608     const struct MaskItem *conf = find_conf_name(&client_p->connection->confs,
609     client_p->name, CONF_SERVER);
610 michael 9202 if (conf == NULL)
611 adx 30 {
612 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
613 michael 7997 "Lost connect{} block for %s", client_get_name(client_p, SHOW_IP));
614 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_OPER, SEND_NOTICE,
615 michael 7997 "Lost connect{} block for %s", client_get_name(client_p, MASK_IP));
616 adx 30
617 michael 3171 exit_client(client_p, "Lost connect{} block");
618 adx 30 return;
619     }
620    
621 michael 9157 if (IsConfTLS(conf))
622 michael 1303 {
623 michael 8426 server_tls_connect_init(client_p, conf, F);
624 michael 1303 return;
625     }
626 adx 30
627 michael 8839 /* Next, send the initial handshake */
628     SetHandshake(client_p);
629    
630 michael 7355 sendto_one(client_p, "PASS %s TS %u %s", conf->spasswd, TS_CURRENT, me.id);
631 adx 30
632 michael 8166 sendto_one(client_p, "CAPAB :%s", capab_get(NULL));
633 adx 30
634 michael 2134 sendto_one(client_p, "SERVER %s 1 :%s%s", me.name,
635     ConfigServerHide.hidden ? "(H) " : "", me.info);
636 adx 30
637     /* If we get here, we're ok, so lets start reading some data */
638 michael 8403 read_packet(client_p->connection->fd, client_p);
639 adx 30 }
640    
641     struct Client *
642     find_servconn_in_progress(const char *name)
643     {
644     dlink_node *ptr;
645    
646     DLINK_FOREACH(ptr, unknown_list.head)
647     {
648 michael 7533 struct Client *cptr = ptr->data;
649 adx 30
650 michael 7533 if (cptr->name[0])
651     if (!irccmp(name, cptr->name))
652 adx 30 return cptr;
653     }
654 michael 2345
655 adx 30 return NULL;
656     }

Properties

Name Value
svn:eol-style native
svn:keywords Id