/* Copyright (C) 2017 Paweł Redman This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include "eli.h" #define eprintf(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) #define DEBUG(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) #define LOCALHOST_NETWORK 0x7F000000 #define LOCALHOST_MASK 0xFF000000 #define REQUEST_HEADER "query " #define REQUEST_HEADER_LEN (sizeof(REQUEST_HEADER) - 1) #define RESPONSE_HEADER "reply " // main.c extern int server_sockfd; uint64_t get_time(void); #define TIME_SECOND (1000000000llu) #define TIME_MINUTE (60 * TIME_SECOND) #define TIME_HOUR (60 * TIME_MINUTE) // shared typedef struct job_s job_t; // database.c enum { DB_INVALID, DB_IN_PROGRESS, DB_VALID }; typedef struct { int state; uint64_t exp_time; char *data; } db_entry_field; typedef struct { uint32_t ipv4; db_entry_field revdns, whois; bool cached_result_valid; int cached_result; job_t *waiting_jobs; eli_header ht_chain; pthread_mutex_t mutex; } db_entry; db_entry *db_find(uint32_t ipv4); void db_destroy(void); // worker.c typedef enum { JOB_REVDNS, JOB_WHOIS, JOB_REPLY, } job_type_t; struct job_s { job_type_t type; db_entry *entry; struct sockaddr_in ret_addr; // for JOB_REPLY uint32_t ipv4; // for other jobs eli_header queue_list, waiting_list; }; job_t *job_create(job_type_t type, db_entry *entry); void job_destroy(job_t *job); void job_enqueue(job_t *job); void job_quit(void); void *worker_main(void *unused); // lexer.c typedef struct { char *data; size_t size, alloc; } vstr_t; #define VSTR_INITIALIZER ((vstr_t){NULL, 0, 0}) void vstr_init(vstr_t *vstr); void vstr_destroy(vstr_t *vstr); void vstr_clear(vstr_t *vstr); int vstr_putc(vstr_t *vstr, char ch); int vstr_cmp(vstr_t *vstr, const char *str); char *vstr_strdup(vstr_t *vstr); char *vstr_to_cstr(vstr_t *vstr); #define LEXER_BUFFER 1024 typedef struct { int error; const char *path; FILE *fp; bool eof; vstr_t *token; char buf[LEXER_BUFFER]; char *buf_c, *buf_e; size_t cc, lc, Cc; // character, line, and column counters char last; bool in_token; bool in_quote; bool in_comment; } lexer_state_t; int lexer_open(lexer_state_t *ls, const char *path, vstr_t *token); void lexer_close(lexer_state_t *ls); int lexer_get_token(lexer_state_t *ls); void lexer_perror(lexer_state_t *ls, const char *fmt, ...); void lexer_perror_eg(lexer_state_t *ls, const char *expected); // lists.c int lists_load(const char *file, size_t depth); void lists_destroy(void); int lists_test(const char *revdns, const char *whois);