/** Start sending upings to a server. * @param[in] sptr Client requesting the upings. * @param[in] aconf ConfItem containing the address to ping. * @param[in] port Port number to ping. * @param[in] count Number of times to ping (should be at least 20). * @return Zero. */ int uping_server(struct Client* sptr, struct ConfItem* aconf, int port, int count) { int fd; struct UPing* pptr; assert(0 != sptr); assert(0 != aconf); if (INADDR_NONE == aconf->ipnum.s_addr) { sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Host lookup failed for " "%s", sptr, aconf->name); return 0; } if (IsUPing(sptr)) uping_cancel(sptr, sptr); /* Cancel previous ping request */ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Unable to create udp " "ping socket", sptr); return 0; } if (!os_set_nonblocking(fd)) { sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Can't set fd non-" "blocking", sptr); close(fd); return 0; } pptr = (struct UPing*) MyMalloc(sizeof(struct UPing)); assert(0 != pptr); memset(pptr, 0, sizeof(struct UPing)); if (!socket_add(&pptr->socket, uping_read_callback, (void*) pptr, SS_DATAGRAM, SOCK_EVENT_READABLE, fd)) { sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Can't queue fd for " "reading", sptr); close(fd); MyFree(pptr); return 0; } pptr->fd = fd; pptr->sin.sin_port = htons(port); pptr->sin.sin_addr.s_addr = aconf->ipnum.s_addr; pptr->sin.sin_family = AF_INET; pptr->count = IRCD_MIN(20, count); pptr->client = sptr; pptr->index = -1; pptr->freeable = UPING_PENDING_SOCKET; strcpy(pptr->name, aconf->name); pptr->next = pingList; pingList = pptr; SetUPing(sptr); uping_start(pptr); return 0; }
/** Start sending upings to a server. * @param[in] sptr Client requesting the upings. * @param[in] aconf ConfItem containing the address to ping. * @param[in] port Port number to ping. * @param[in] count Number of times to ping (should be at least 20). * @return Zero. */ int uping_server(struct Client* sptr, struct ConfItem* aconf, int port, int count) { int fd; int family = 0; struct UPing* pptr; struct irc_sockaddr *local; assert(0 != sptr); assert(0 != aconf); if (!irc_in_addr_valid(&aconf->address.addr)) { sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Host lookup failed for " "%s", sptr, aconf->name); return 0; } if (IsUPing(sptr)) uping_cancel(sptr, sptr); /* Cancel previous ping request */ if (irc_in_addr_is_ipv4(&aconf->address.addr)) { local = &VirtualHost_v4; family = AF_INET; } else { local = &VirtualHost_v6; } fd = os_socket(local, SOCK_DGRAM, "Outbound uping socket", family); if (fd < 0) return 0; pptr = (struct UPing*) MyMalloc(sizeof(struct UPing)); assert(0 != pptr); memset(pptr, 0, sizeof(struct UPing)); if (!socket_add(&pptr->socket, uping_read_callback, (void*) pptr, SS_DATAGRAM, SOCK_EVENT_READABLE, fd)) { sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :UPING: Can't queue fd for " "reading", sptr); close(fd); MyFree(pptr); return 0; } pptr->fd = fd; memcpy(&pptr->addr.addr, &aconf->address.addr, sizeof(pptr->addr.addr)); pptr->addr.port = port; pptr->count = IRCD_MIN(20, count); pptr->client = sptr; pptr->freeable = UPING_PENDING_SOCKET; strcpy(pptr->name, aconf->name); pptr->next = pingList; pingList = pptr; SetUPing(sptr); uping_start(pptr); return 0; }
/* Rewritten by Run - 24 sept 94 */ static void exit_one_client(struct Client* bcptr, const char* comment) { struct SLink *lp; struct Ban *bp; if (cli_serv(bcptr) && cli_serv(bcptr)->client_list) /* Was SetServerYXX called ? */ ClearServerYXX(bcptr); /* Removes server from server_list[] */ if (IsUser(bcptr)) { /* * clear out uping requests */ if (IsUPing(bcptr)) uping_cancel(bcptr, 0); /* * Stop a running /LIST clean */ if (MyUser(bcptr) && cli_listing(bcptr)) { MyFree(cli_listing(bcptr)); cli_listing(bcptr) = NULL; } /* * If a person is on a channel, send a QUIT notice * to every client (person) on the same channel (so * that the client can show the "**signoff" message). * (Note: The notice is to the local clients *only*) */ sendcmdto_common_channels_butone(bcptr, CMD_QUIT, NULL, ":%s", comment); remove_user_from_all_channels(bcptr); /* Clean up invitefield */ while ((lp = cli_user(bcptr)->invited)) del_invite(bcptr, lp->value.chptr); /* Clean up silencefield */ while ((bp = cli_user(bcptr)->silence)) { cli_user(bcptr)->silence = bp->next; free_ban(bp); } /* Clean up snotice lists */ if (MyUser(bcptr)) set_snomask(bcptr, ~0, SNO_DEL); if (IsInvisible(bcptr)) { assert(UserStats.inv_clients > 0); --UserStats.inv_clients; } if (IsOper(bcptr)) { assert(UserStats.opers > 0); --UserStats.opers; } if (MyConnect(bcptr)) Count_clientdisconnects(bcptr, UserStats); else Count_remoteclientquits(UserStats, bcptr); } else if (IsServer(bcptr)) { /* Remove downlink list node of uplink */ remove_dlink(&(cli_serv(cli_serv(bcptr)->up))->down, cli_serv(bcptr)->updown); cli_serv(bcptr)->updown = 0; if (MyConnect(bcptr)) Count_serverdisconnects(UserStats); else Count_remoteserverquits(UserStats); } else if (IsMe(bcptr)) { sendto_opmask_butone(0, SNO_OLDSNO, "ERROR: tried to exit me! : %s", comment); return; /* ...must *never* exit self! */ } else if (IsUnknown(bcptr) || IsConnecting(bcptr) || IsHandshake(bcptr)) Count_unknowndisconnects(UserStats); /* * Update IPregistry */ if (IsIPChecked(bcptr)) IPcheck_disconnect(bcptr); /* * Remove from serv->client_list * NOTE: user is *always* NULL if this is a server */ if (cli_user(bcptr)) { assert(!IsServer(bcptr)); /* bcptr->user->server->serv->client_list[IndexYXX(bcptr)] = NULL; */ RemoveYXXClient(cli_user(bcptr)->server, cli_yxx(bcptr)); } /* Remove bcptr from the client list */ #ifdef DEBUGMODE if (hRemClient(bcptr) != 0) Debug((DEBUG_ERROR, "%p !in tab %s[%s] %p %p %p %d %d %p", bcptr, cli_name(bcptr), cli_from(bcptr) ? cli_sockhost(cli_from(bcptr)) : "??host", cli_from(bcptr), cli_next(bcptr), cli_prev(bcptr), cli_fd(bcptr), cli_status(bcptr), cli_user(bcptr))); #else hRemClient(bcptr); #endif remove_client_from_list(bcptr); }