31 |
#include "ircd_defs.h" |
#include "ircd_defs.h" |
32 |
#include "list.h" |
#include "list.h" |
33 |
#include "s_bsd.h" |
#include "s_bsd.h" |
34 |
|
#include "parse.h" |
35 |
#include "client.h" |
#include "client.h" |
36 |
#include "dbuf.h" |
#include "dbuf.h" |
37 |
#include "irc_string.h" |
#include "irc_string.h" |
104 |
* gamble anyway. |
* gamble anyway. |
105 |
*/ |
*/ |
106 |
int |
int |
107 |
get_sockerr(int fd) |
os_get_sockerr(int fd) |
108 |
{ |
{ |
109 |
int errtmp = errno; |
int errtmp = errno; |
110 |
#ifdef SO_ERROR |
#ifdef SO_ERROR |
459 |
errno = errtmp; |
errno = errtmp; |
460 |
} |
} |
461 |
|
|
462 |
|
/** Complete non-blocking connect()-sequence. Check access and |
463 |
|
* terminate connection, if trouble detected. |
464 |
|
* @param client_p Client to which we have connected, with all ConfItem structs attached. |
465 |
|
* @return Zero on failure (caller should exit_client()), non-zero on success. |
466 |
|
*/ |
467 |
|
static int |
468 |
|
completed_connection(struct Client *client_p) |
469 |
|
{ |
470 |
|
struct MaskItem *conf = NULL; |
471 |
|
|
472 |
|
assert(client_p); |
473 |
|
|
474 |
|
/* |
475 |
|
* Get the socket status from the fd first to check if |
476 |
|
* connection actually succeeded |
477 |
|
*/ |
478 |
|
if ((client_p->localClient->error = os_get_sockerr(s_fd(&client_p->localClient->socket)))) |
479 |
|
{ |
480 |
|
const char *msg = strerror(client_p->localClient->error); |
481 |
|
|
482 |
|
if (!msg) |
483 |
|
msg = "Unknown error"; |
484 |
|
|
485 |
|
sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE, |
486 |
|
"Connection failed to %s: %s", |
487 |
|
get_client_name(client_p, HIDE_IP), msg); |
488 |
|
sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE, |
489 |
|
"Connection failed to %s: %s", |
490 |
|
get_client_name(client_p, MASK_IP), msg); |
491 |
|
return 0; |
492 |
|
} |
493 |
|
|
494 |
|
conf = find_conf_name(&client_p->localClient->confs, |
495 |
|
client_p->name, CONF_SERVER); |
496 |
|
if (!conf) |
497 |
|
{ |
498 |
|
sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE, |
499 |
|
"Lost connect{} block for %s", get_client_name(client_p, HIDE_IP)); |
500 |
|
sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE, |
501 |
|
"Lost connect{} block for %s", get_client_name(client_p, MASK_IP)); |
502 |
|
return 0; |
503 |
|
} |
504 |
|
|
505 |
|
if (s_state(&client_p->localClient->socket) == SS_CONNECTING) |
506 |
|
socket_state(&client_p->localClient->socket, SS_CONNECTED); |
507 |
|
|
508 |
|
if (!EmptyString(conf->spasswd)) |
509 |
|
sendto_one(client_p, "PASS %s TS %d %s", conf->spasswd, TS_CURRENT, me.id); |
510 |
|
|
511 |
|
send_capabilities(client_p, 0); |
512 |
|
|
513 |
|
assert(client_p->serv); |
514 |
|
SetHandshake(client_p); |
515 |
|
|
516 |
|
/* |
517 |
|
* Make us timeout after twice the timeout for DNS look ups |
518 |
|
*/ |
519 |
|
client_p->localClient->lasttime = CurrentTime; |
520 |
|
AddFlag(client_p, FLAGS_PINGSENT); |
521 |
|
|
522 |
|
sendto_one(client_p, "SERVER %s 1 :%s%s", me.name, |
523 |
|
ConfigServerHide.hidden ? "(H) " : "", me.info); |
524 |
|
|
525 |
|
return !IsDead(client_p); |
526 |
|
} |
527 |
|
|
528 |
/* |
/* |
529 |
* close_connection |
* close_connection |
530 |
* Close the physical connection. This function must make |
* Close the physical connection. This function must make |