static time_t * get_addr_time_in_cache(const struct sockaddr_in * addr) { /* get block index */ int block = block_from_sockaddr_in(addr); int count = addr_cache_counters[block]; int first = addr_cache_pointers[block]; int i = 0; /* do reverse search for efficency */ for ( i = count - 1; i >= 0; i -- ) if (addr->sin_addr.s_addr == addr_cache[block][(first+i)%ADDR_CACHE_BLOCK_SIZE].addr.sin_addr.s_addr && addr->sin_family == addr_cache[block][(first+i)%ADDR_CACHE_BLOCK_SIZE].addr.sin_family ) return &addr_cache[block][(first+i)%ADDR_CACHE_BLOCK_SIZE].access_time; return NULL; }
static void del_addr_from_cache(const struct sockaddr_in * addr) { /* get block index */ int block = block_from_sockaddr_in(addr); int count = addr_cache_counters[block]; int first = addr_cache_pointers[block]; int i = 0; /* do reverse search for efficency */ for ( i = count - 1; i >= 0; i -- ) if (addr->sin_addr.s_addr == addr_cache[block][(first+i)%ADDR_CACHE_BLOCK_SIZE].addr.sin_addr.s_addr && addr->sin_family == addr_cache[block][(first+i)%ADDR_CACHE_BLOCK_SIZE].addr.sin_family ) /* found. zero this item */ { memset((void *)&addr_cache[block][(first+i)%ADDR_CACHE_BLOCK_SIZE], 0, sizeof(cache_data)); break; } }
static void add_addr_to_cache(const struct sockaddr_in * addr) { int block = block_from_sockaddr_in(addr); int count = addr_cache_counters[block]; int first = addr_cache_pointers[block]; if (count < ADDR_CACHE_BLOCK_SIZE) { memcpy((void *)&addr_cache[block][count], (void *) addr, sizeof(struct sockaddr_in)); addr_cache_counters[block]++; } else { memcpy((void *)&addr_cache[block][first], (void *) addr, sizeof(struct sockaddr_in)); addr_cache_pointers[block]++; addr_cache_pointers[block]%=ADDR_CACHE_BLOCK_SIZE; } }
static int is_addr_in_cache(const struct sockaddr_in * addr) { /* get block index */ int block = block_from_sockaddr_in(addr); int count = addr_cache_counters[block]; int first = addr_cache_pointers[block]; int i = 0; /* do reverse search for efficency */ for ( i = count - 1; i >= 0; i -- ) /* if (0 == memcmp((void *)addr, (void *)&addr_cache[block][(first+i)%ADDR_CACHE_BLOCK_SIZE], sizeof(struct sockaddr_in))) */ if (addr->sin_addr.s_addr == addr_cache[block][(first+i)%ADDR_CACHE_BLOCK_SIZE].sin_addr.s_addr && addr->sin_family == addr_cache[block][(first+i)%ADDR_CACHE_BLOCK_SIZE].sin_family ) return 1; return 0; }
static void add_addr_to_cache(const struct sockaddr_in * addr) { int block = block_from_sockaddr_in(addr); int count = addr_cache_counters[block]; /* use 'first' to index item in cache block when count is equal or greater than block size */ int first = addr_cache_pointers[block]; if (count < ADDR_CACHE_BLOCK_SIZE) { memcpy((void *)&addr_cache[block][count].addr, (void *) addr, sizeof(struct sockaddr_in)); addr_cache[block][count].access_time = redsocks_time(NULL); addr_cache_counters[block]++; } else { memcpy((void *)&addr_cache[block][first].addr, (void *) addr, sizeof(struct sockaddr_in)); addr_cache[block][first].access_time = redsocks_time(NULL); addr_cache_pointers[block]++; addr_cache_pointers[block]%=ADDR_CACHE_BLOCK_SIZE; } }