X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fuping.c;h=62b69560db348c636e148f2f967d99e487746c6f;hb=refs%2Fheads%2Fupstream;hp=6982577515bdd7e752b5320ba7eb7b6050df1f7a;hpb=da712d65837b082fadf38f7ef573a3b9476c1883;p=ircu2.10.12-pk.git diff --git a/ircd/uping.c b/ircd/uping.c index 6982577..62b6956 100644 --- a/ircd/uping.c +++ b/ircd/uping.c @@ -55,8 +55,8 @@ #define UPINGTIMEOUT 60 /**< Timeout waiting for ping responses */ static struct UPing* pingList = 0; /**< Linked list of UPing structs */ -static int UPingFileDescriptor = -1; /**< UDP listener socket for upings */ -static struct Socket upingSock; /**< Socket struct for upings */ +static struct Socket upingSock_v4; /**< Socket struct for IPv4 upings */ +static struct Socket upingSock_v6; /**< Socket struct for IPv6 upings */ /** Start iteration of uping list. * @return Start of uping list. @@ -88,71 +88,79 @@ static void uping_erase(struct UPing* p) } /** Callback for uping listener socket. + * Reads a uping from the socket and respond, but not more than 10 + * times per second. * @param[in] ev I/O event for uping socket. */ static void uping_echo_callback(struct Event* ev) { + struct Socket *sock; + struct irc_sockaddr from; + unsigned int len = 0; + static time_t last = 0; + static int counter = 0; + char buf[BUFSIZE + 1]; + assert(ev_type(ev) == ET_READ || ev_type(ev) == ET_ERROR); + sock = ev_socket(ev); + assert(sock == &upingSock_v4 || sock == &upingSock_v6); - uping_echo(); + Debug((DEBUG_DEBUG, "UPING: uping_echo")); + + if (IO_SUCCESS != os_recvfrom_nonb(s_fd(sock), buf, BUFSIZE, &len, &from)) + return; + /* + * count em even if we're getting flooded so we can tell we're getting + * flooded. + */ + ++ServerStats->uping_recv; + if (len < 19) + return; + else if (CurrentTime != last) { + counter = 0; + last = CurrentTime; + } else if (++counter > 10) + return; + os_sendto_nonb(s_fd(sock), buf, len, NULL, 0, &from); } /** Initialize a UDP socket for upings. - * @returns File descriptor of UDP socket (-1 on error). + * @returns 0 on success, -1 on error. */ int uping_init(void) { struct irc_sockaddr from; int fd; - memcpy(&from, &VirtualHost, sizeof(from)); + memcpy(&from, &VirtualHost_v4, sizeof(from)); from.port = atoi(UDP_PORT); - fd = os_socket(&from, SOCK_DGRAM, "UDP listener socket"); + fd = os_socket(&from, SOCK_DGRAM, "IPv4 uping listener", AF_INET); if (fd < 0) return -1; - if (!socket_add(&upingSock, uping_echo_callback, 0, SS_DATAGRAM, - SOCK_EVENT_READABLE, fd)) { + if (!socket_add(&upingSock_v4, uping_echo_callback, 0, SS_DATAGRAM, + SOCK_EVENT_READABLE, fd)) { Debug((DEBUG_ERROR, "UPING: Unable to queue fd to event system")); close(fd); return -1; } - UPingFileDescriptor = fd; - return fd; -} - -/** Read a uping from the socket and respond (but not more than 10 - * times per second). - */ -void uping_echo() -{ - struct irc_sockaddr from; - unsigned int len = 0; - static time_t last = 0; - static int counter = 0; - char buf[BUFSIZE + 1]; - - Debug((DEBUG_DEBUG, "UPING: uping_echo")); +#ifdef AF_INET6 + memcpy(&from, &VirtualHost_v6, sizeof(from)); + from.port = atoi(UDP_PORT); - if (IO_SUCCESS != os_recvfrom_nonb(UPingFileDescriptor, buf, BUFSIZE, &len, &from)) - return; - /* - * count em even if we're getting flooded so we can tell we're getting - * flooded. - */ - ++ServerStats->uping_recv; - if (CurrentTime == last) { - if (++counter > 10) - return; - } - else { - counter = 0; - last = CurrentTime; + fd = os_socket(&from, SOCK_DGRAM, "IPv6 uping listener", AF_INET6); + if (fd < 0) + return -1; + if (!socket_add(&upingSock_v6, uping_echo_callback, 0, SS_DATAGRAM, + SOCK_EVENT_READABLE, fd)) { + Debug((DEBUG_ERROR, "UPING: Unable to queue fd to event system")); + close(fd); + return -1; } - if (len < 19) - return; - os_sendto_nonb(UPingFileDescriptor, buf, len, NULL, 0, &from); +#endif + + return 0; } @@ -362,7 +370,9 @@ void uping_read(struct UPing* pptr) 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); @@ -376,7 +386,13 @@ int uping_server(struct Client* sptr, struct ConfItem* aconf, int port, int coun if (IsUPing(sptr)) uping_cancel(sptr, sptr); /* Cancel previous ping request */ - fd = os_socket(NULL, SOCK_DGRAM, "UDP ping socket"); + 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; @@ -422,7 +438,7 @@ void uping_end(struct UPing* pptr) sendcmdto_one(&me, CMD_NOTICE, pptr->client, "%C :UPING %s%s", pptr->client, pptr->name, pptr->buf); sendcmdto_one(&me, CMD_NOTICE, pptr->client, "%C :UPING Stats: " - "sent %d recvd %d ; min/avg/max = %1lu/%1lu/%1lu ms", + "sent %d recvd %d ; min/avg/max = %u/%u/%u ms", pptr->client, pptr->sent, pptr->received, pptr->ms_min, (2 * pptr->ms_ave) / (2 * pptr->received), pptr->ms_max); } else @@ -456,7 +472,7 @@ void uping_cancel(struct Client *sptr, struct Client* acptr) struct UPing* ping; struct UPing* ping_next; - Debug((DEBUG_DEBUG, "UPING: cancelling uping for %s", cli_name(sptr))); + Debug((DEBUG_DEBUG, "UPING: canceling uping for %s", cli_name(sptr))); for (ping = pingList; ping; ping = ping_next) { ping_next = ping->next; if (sptr == ping->client) { @@ -466,5 +482,3 @@ void uping_cancel(struct Client *sptr, struct Client* acptr) } ClearUPing(sptr); } - -