/** 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; }