int kr_nsrep_update_rtt(struct kr_nsrep *ns, unsigned score, kr_nsrep_lru_t *cache) { if (!ns || !cache || ns->addr.ip.sa_family == AF_UNSPEC) { return kr_error(EINVAL); } char *addr = kr_nsrep_inaddr(ns->addr); size_t addr_len = kr_nsrep_inaddr_len(ns->addr); unsigned *cur = lru_set(cache, addr, addr_len); if (!cur) { return kr_error(ENOMEM); } /* Score limits */ if (score > KR_NS_MAX_SCORE) { score = KR_NS_MAX_SCORE; } if (score <= KR_NS_GLUED) { score = KR_NS_GLUED + 1; } /* Set initial value or smooth over last two measurements */ if (*cur != 0) { *cur = (*cur + score) / 2; } else { /* First measurement, reset */ *cur = score; } return kr_ok(); }
int kr_nsrep_update_rtt(struct kr_nsrep *ns, const struct sockaddr *addr, unsigned score, kr_nsrep_lru_t *cache) { if (!ns || !cache || ns->addr[0].ip.sa_family == AF_UNSPEC) { return kr_error(EINVAL); } const char *addr_in = kr_nsrep_inaddr(ns->addr[0]); size_t addr_len = kr_nsrep_inaddr_len(ns->addr[0]); if (addr) { /* Caller provided specific address */ if (addr->sa_family == AF_INET) { addr_in = (const char *)&((struct sockaddr_in *)addr)->sin_addr; addr_len = sizeof(struct in_addr); } else if (addr->sa_family == AF_INET6) { addr_in = (const char *)&((struct sockaddr_in6 *)addr)->sin6_addr; addr_len = sizeof(struct in6_addr); } } unsigned *cur = lru_set(cache, addr_in, addr_len); if (!cur) { return kr_error(ENOMEM); } /* Score limits */ if (score > KR_NS_MAX_SCORE) { score = KR_NS_MAX_SCORE; } if (score <= KR_NS_GLUED) { score = KR_NS_GLUED + 1; } /* Set initial value or smooth over last two measurements */ if (*cur != 0) { *cur = (*cur + score) / 2; } else { /* First measurement, reset */ *cur = score; } return kr_ok(); }