summaryrefslogtreecommitdiff
path: root/src/shared.h
blob: 46c900e831d1b8fc627f2bcc35f384af164cce49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
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 <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdarg.h>

#include <netinet/in.h>
#include <netinet/udp.h>
#include <sys/socket.h>
#include <unistd.h>

#include <pthread.h>

#include "eli.h"

#define PROGRAM_NAME "schachtmeister2"
#define PROGRAM_VERSION "v0.1.0"

#define eprintf(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
#define DEBUG(fmt, ...) fprintf(stderr, "[DEBUG] %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);
void db_invalidate_cached_results(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);
int lists_reload(const char *file);
void lists_destroy(void);
int lists_test(const char *revdns, const char *whois);