File: spd_db.c

package info (click to toggle)
libreswan 5.2-2.3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 81,644 kB
  • sloc: ansic: 129,988; sh: 32,018; xml: 20,646; python: 10,303; makefile: 3,022; javascript: 1,506; sed: 574; yacc: 511; perl: 264; awk: 52
file content (100 lines) | stat: -rw-r--r-- 3,022 bytes parent folder | download | duplicates (2)
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
/* Connection database indexed by serialno, for libreswan
 *
 * Copyright (C) 2020 Andrew Cagney <cagney@gnu.org>
 *
 * 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 2 of the License, or (at your
 * option) any later version.  See <https://www.gnu.org/licenses/gpl2.txt>.
 *
 * 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.
 */

#include "spd_db.h"
#include "log.h"
#include "hash_table.h"
#include "connections.h"

/*
 * SPD_ROUTE database.
 */

static size_t jam_spd(struct jambuf *buf, const struct spd *sr)
{
	size_t s = 0;
	s += jam_connection(buf, sr->connection);
	s += jam_string(buf, " ");
	s += jam_selector_pair(buf, &sr->local->client, &sr->remote->client);
	return s;
}

static hash_t hash_spd_remote_client(const ip_selector *sr)
{
	return hash_thing(sr->lo, zero_hash);
}

HASH_TABLE(spd, remote_client, .remote->client, STATE_TABLE_SIZE);

HASH_DB(spd, &spd_remote_client_hash_table);

REHASH_DB_ENTRY(spd, remote_client, .remote->client);

static struct list_head *spd_filter_head(struct spd_filter *filter)
{
	/* select list head */
	if (filter->remote_client_range != NULL) {
		selector_buf sb;
		dbg("FOR_EACH_SPD[remote_client_range=%s]... in "PRI_WHERE,
		    str_selector(filter->remote_client_range, &sb), pri_where(filter->where));
		hash_t hash = hash_spd_remote_client(filter->remote_client_range);
		return hash_table_bucket(&spd_remote_client_hash_table, hash);
	}

	/* else other queries? */
	dbg("FOR_EACH_SPD_... in "PRI_WHERE, pri_where(filter->where));
	return &spd_db_list_head;
}

static bool matches_spd_filter(struct spd *spd, struct spd_filter *filter)
{
	if (filter->remote_client_range != NULL &&
	    !selector_range_eq_selector_range(*filter->remote_client_range, spd->remote->client)) {
		return false;
	}
	return true;
}

bool next_spd(enum chrono order, struct spd_filter *filter)
{
	if (filter->internal == NULL) {
		/*
		 * Advance to first entry of the circular list (if the
		 * list is entry it ends up back on HEAD which has no
		 * data).
		 */
		filter->internal = spd_filter_head(filter)->head.next[order];
	}
	/* Walk list until an entry matches */
	filter->spd = NULL;
	for (struct list_entry *entry = filter->internal;
	     entry->data != NULL /* head has DATA == NULL */;
	     entry = entry->next[order]) {
		struct spd *spd = (struct spd *) entry->data;
		if (matches_spd_filter(spd, filter)) {
			/* save connection; but step off current entry */
			filter->internal = entry->next[order];
			filter->count++;
			LDBGP_JAMBUF(DBG_BASE, &global_logger, buf) {
				jam_string(buf, "  found ");
				jam_spd(buf, spd);
			}
			filter->spd = spd;
			return true;
		}
	}
	dbg("  matches: %d", filter->count);
	return false;
}