diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 85 |
1 files changed, 78 insertions, 7 deletions
@@ -17,9 +17,21 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "shared.h" +#include <time.h> int server_sockfd; +static struct timespec time_ref; + +uint64_t get_time(void) +{ + static struct timespec now; + + clock_gettime(CLOCK_MONOTONIC, &now); + return (uint64_t)(now.tv_sec - time_ref.tv_sec) * TIME_SECOND + + now.tv_nsec + 1; +} + static int parse_req_addr(char *begin, char *end, uint32_t *out) { char *p; @@ -48,6 +60,68 @@ static int parse_req_addr(char *begin, char *end, uint32_t *out) return 0; } +void handle_request(struct sockaddr_in *ret_addr, uint32_t query) +{ + db_entry *entry; + job_t *reply_job; + uint64_t now = get_time(); + + DEBUG("query %08X\n", query); + + entry = db_find(query); + if (!entry) { + eprintf("handle_request: out of memory\n"); + return; + } + + reply_job = job_create(JOB_REPLY, entry); + reply_job->ipv4 = query; + memcpy(&reply_job->ret_addr, ret_addr, sizeof(struct sockaddr_in)); + + if (entry->revdns.state == DB_VALID + && entry->revdns.exp_time <= now) { + entry->revdns.state = DB_INVALID; + DEBUG("revDNS for %08X expired\n", query); + } + + if (entry->whois.state == DB_VALID + && entry->whois.exp_time <= now) { + entry->whois.state = DB_INVALID; + DEBUG("WHOIS for %08X expired\n", query); + } + + if (entry->revdns.state == DB_VALID && + entry->whois.state == DB_VALID) { + job_enqueue(reply_job); + goto out; + } + + if (entry->revdns.state == DB_INVALID) { + job_t *job; + + DEBUG("revDNS cache miss for %08X\n", query); + job = job_create(JOB_REVDNS, entry); + job->ipv4 = query; + job_enqueue(job); + entry->revdns.state = DB_IN_PROGRESS; + } + + if (entry->whois.state == DB_INVALID) { + job_t *job; + + DEBUG("WHOIS cache miss for %08X\n", query); + job = job_create(JOB_WHOIS, entry); + job->ipv4 = query; + job_enqueue(job); + entry->whois.state = DB_IN_PROGRESS; + } + + eli_append(&entry->waiting_jobs, reply_job, waiting_list); + +out: + pthread_mutex_unlock(&entry->mutex); +} + #define NUM_WORKERS 8 // FIXME: shouldn't be hardcoded int main(void) @@ -57,6 +131,8 @@ int main(void) pthread_t workers[NUM_WORKERS]; size_t i; + clock_gettime(CLOCK_MONOTONIC_RAW, &time_ref); + if (lists_load("schachts.list", 0)) { eprintf("fatal error: couldn't load the lists\n"); goto error_lists; @@ -88,7 +164,6 @@ int main(void) socklen_t addrlen = sizeof(addr); ssize_t size; uint32_t query; - job_t *job; size = recvfrom(server_sockfd, buffer, sizeof(buffer), 0, (void*)&addr, &addrlen); @@ -111,11 +186,7 @@ int main(void) &query)) continue; - job = job_create(); - job->type = JOB_TEST; - job->query = query; - memcpy(&job->reply_to, &addr, sizeof(addr)); - job_enqueue(job); + handle_request(&addr, query); } job_quit(); @@ -123,7 +194,7 @@ int main(void) for (i = 0; i < NUM_WORKERS; i++) pthread_join(workers[i], NULL); - cache_destroy(); + db_destroy(); // todo: clear all jobs error_recvfrom: |