2
* Copyright (c) 2002, Vidar Madsen
4
*----------------------------------------------------------------------
5
* This file is part of gtk-gnutella.
7
* gtk-gnutella is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* gtk-gnutella is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with gtk-gnutella; if not, write to the Free Software
20
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
*----------------------------------------------------------------------
28
* Needs brief description here.
30
* Functions for keeping a whitelist of nodes we always allow in,
31
* and whom we try to keep a connection to.
33
* @author Vidar Madsen
39
RCSID("$Id: whitelist.c,v 1.6 2005/06/29 14:24:25 daichik Exp $");
41
#include "whitelist.h"
46
#include "lib/glib-missing.h"
47
#include "lib/override.h" /* Must be the last header included */
49
static GSList *sl_whitelist = NULL;
51
static const gchar whitelist_file[] = "whitelist";
52
static time_t whitelist_mtime, whitelist_checked;
53
static gchar *whitelist_path = NULL;
58
* Loads the whitelist into memory.
60
static void whitelist_retrieve(void)
63
gchar *p, *sport, *snetmask;
64
guint32 ip, port, netmask;
71
file_path_set(fp, settings_config_dir(), whitelist_file);
72
f = file_config_open_read_norename("Host Whitelist", fp, G_N_ELEMENTS(fp));
76
if (fstat(fileno(f), &st)) {
77
g_warning("whitelist_retrieve: fstat() failed: %s", g_strerror(errno));
81
whitelist_checked = time(NULL);
82
whitelist_mtime = st.st_mtime;
84
while (fgets(line, sizeof(line), f)) {
86
if (*line == '#') continue;
88
/* Remove trailing spaces so that lines that contain spaces only
89
* are ignored and cause no warnings. */
90
p = strchr(line, '\0');
92
if (!is_ascii_space((guchar) *p))
100
sport = snetmask = NULL;
102
if ((p = strchr(line, '/')) != NULL) {
106
if ((p = strchr(line, ':')) != NULL) {
111
ip = host_to_ip(line);
113
g_warning("whitelist_retrieve(): "
114
"Line %d: Invalid IP \"%s\"", linenum, line);
123
netmask = 0xffffffffU; /* Default mask */
125
if (strchr(snetmask, '.')) {
126
netmask = gchar_to_ip(snetmask);
128
netmask = 0xffffffff;
129
g_warning("whitelist_retrieve(): "
130
"Line %d: Invalid netmask \"%s\", "
131
"using 255.255.255.255 instead.", linenum, snetmask);
137
v = gm_atoul(snetmask, NULL, &error);
138
if (!error && v > 0 && v <= 32) {
139
netmask = ~(0xffffffffU >> v);
141
g_warning("whitelist_retrieve(): "
142
"Line %d: Invalid netmask \"%s\", "
143
"using /32 instead.", linenum, snetmask);
148
n = g_malloc0(sizeof(*n));
151
n->netmask = netmask;
153
sl_whitelist = g_slist_prepend(sl_whitelist, n);
156
sl_whitelist = g_slist_reverse(sl_whitelist);
163
* Attempts to connect to the nodes we have whitelisted.
164
* Only entries with a specified port will be tried.
166
* @returns the number of new nodes that are connected to.
168
guint whitelist_connect(void)
172
time_t now = time(NULL);
175
for (sl = sl_whitelist; sl; sl = g_slist_next(sl)) {
179
if (node_is_connected(n->ip, n->port, TRUE))
182
if (delta_time(now, n->last_try) > WHITELIST_RETRY_DELAY) {
184
node_add(n->ip, n->port);
194
* Called on startup. Loads the whitelist into memory.
196
void whitelist_init(void)
198
whitelist_path = make_pathname(settings_config_dir(), whitelist_file);
199
whitelist_retrieve();
205
* Frees all entries in the whitelist.
207
void whitelist_close(void)
211
for (sl = sl_whitelist; sl; sl = g_slist_next(sl))
214
g_slist_free(sl_whitelist);
216
G_FREE_NULL(whitelist_path);
222
* Reloads the whitelist.
224
void whitelist_reload(void)
227
whitelist_retrieve();
233
* Check the given IP agains the entries in the whitelist.
234
* @returns TRUE if found, and FALSE if not.
236
* Also, it will peridically check the whitelist file for
237
* updates, and reload it if it has changed.
239
gboolean whitelist_check(guint32 ip)
242
time_t now = time(NULL);
245
/* Check if the file has changed on disk, and reload it if necessary. */
246
if (delta_time(now, whitelist_checked) > WHITELIST_CHECK_INTERVAL) {
249
whitelist_checked = now;
251
if (NULL != whitelist_path && 0 == stat(whitelist_path, &st)) {
252
if (st.st_mtime != whitelist_mtime) {
253
g_warning("whitelist_check(): "
254
"Whitelist changed on disk. Reloading.");
260
for (sl = sl_whitelist; sl; sl = g_slist_next(sl)) {
262
if ((ip & n->netmask) == (n->ip & n->netmask))