Annotation of embedaddon/strongswan/src/libcharon/plugins/farp/farp_listener.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2019 Tobias Brunner
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * Copyright (C) 2010 Martin Willi
6: * Copyright (C) 2010 revosec AG
7: *
8: * This program is free software; you can redistribute it and/or modify it
9: * under the terms of the GNU General Public License as published by the
10: * Free Software Foundation; either version 2 of the License, or (at your
11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12: *
13: * This program is distributed in the hope that it will be useful, but
14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16: * for more details.
17: */
18:
19: #include "farp_listener.h"
20:
21: #include <collections/linked_list.h>
22: #include <threading/rwlock.h>
23:
24: typedef struct private_farp_listener_t private_farp_listener_t;
25:
26: /**
27: * Private data of an farp_listener_t object.
28: */
29: struct private_farp_listener_t {
30:
31: /**
32: * Public farp_listener_t interface.
33: */
34: farp_listener_t public;
35:
36: /**
37: * List with entry_t
38: */
39: linked_list_t *entries;
40:
41: /**
42: * RWlock for IP list
43: */
44: rwlock_t *lock;
45: };
46:
47: /**
48: * Traffic selector cache entry
49: */
50: typedef struct {
51: /** list of local selectors */
52: linked_list_t *local;
53: /** list of remote selectors */
54: linked_list_t *remote;
55: /** reqid of CHILD_SA */
56: uint32_t reqid;
57: } entry_t;
58:
59: /**
60: * Destroy a cache entry
61: */
62: static void destroy_entry(entry_t *this)
63: {
64: this->local->destroy_offset(this->local,
65: offsetof(traffic_selector_t, destroy));
66: this->remote->destroy_offset(this->remote,
67: offsetof(traffic_selector_t, destroy));
68: free(this);
69: }
70:
71: METHOD(listener_t, child_updown, bool,
72: private_farp_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
73: bool up)
74: {
75: enumerator_t *enumerator;
76: traffic_selector_t *ts;
77: entry_t *entry;
78: const chunk_t full_from = chunk_from_chars(0x00, 0x00, 0x00, 0x00),
79: full_to = chunk_from_chars(0xff, 0xff, 0xff, 0xff);
80:
81: if (up)
82: {
83: INIT(entry,
84: .local = linked_list_create(),
85: .remote = linked_list_create(),
86: .reqid = child_sa->get_reqid(child_sa),
87: );
88:
89: enumerator = child_sa->create_ts_enumerator(child_sa, FALSE);
90: while (enumerator->enumerate(enumerator, &ts))
91: {
92: if (ts->get_type(ts) != TS_IPV4_ADDR_RANGE)
93: {
94: continue;
95: }
96: /* ignore 0.0.0.0/0 remote TS because we don't want to
97: * reply to ARP requests for locally connected subnets */
98: if (chunk_equals(ts->get_from_address(ts), full_from) &&
99: chunk_equals(ts->get_to_address(ts), full_to))
100: {
101: continue;
102: }
103: entry->remote->insert_last(entry->remote, ts->clone(ts));
104: }
105: enumerator->destroy(enumerator);
106:
107: enumerator = child_sa->create_ts_enumerator(child_sa, TRUE);
108: while (enumerator->enumerate(enumerator, &ts))
109: {
110: if (ts->get_type(ts) != TS_IPV4_ADDR_RANGE)
111: {
112: continue;
113: }
114: entry->local->insert_last(entry->local, ts->clone(ts));
115: }
116: enumerator->destroy(enumerator);
117:
118: if (!entry->remote->get_count(entry->remote) ||
119: !entry->local->get_count(entry->local))
120: {
121: destroy_entry(entry);
122: return TRUE;
123: }
124:
125: this->lock->write_lock(this->lock);
126: this->entries->insert_last(this->entries, entry);
127: this->lock->unlock(this->lock);
128: }
129: else
130: {
131: this->lock->write_lock(this->lock);
132: enumerator = this->entries->create_enumerator(this->entries);
133: while (enumerator->enumerate(enumerator, &entry))
134: {
135: if (entry->reqid == child_sa->get_reqid(child_sa))
136: {
137: this->entries->remove_at(this->entries, enumerator);
138: destroy_entry(entry);
139: break;
140: }
141: }
142: enumerator->destroy(enumerator);
143: this->lock->unlock(this->lock);
144: }
145: return TRUE;
146: }
147:
148: METHOD(farp_listener_t, has_tunnel, bool,
149: private_farp_listener_t *this, host_t *local, host_t *remote)
150: {
151: enumerator_t *entries, *locals, *remotes;
152: traffic_selector_t *ts;
153: bool found = FALSE;
154: entry_t *entry;
155:
156: this->lock->read_lock(this->lock);
157: entries = this->entries->create_enumerator(this->entries);
158: while (!found && entries->enumerate(entries, &entry))
159: {
160: remotes = entry->remote->create_enumerator(entry->remote);
161: while (!found && remotes->enumerate(remotes, &ts))
162: {
163: if (ts->includes(ts, remote))
164: {
165: locals = entry->local->create_enumerator(entry->local);
166: while (!found && locals->enumerate(locals, &ts))
167: {
168: found = ts->includes(ts, local);
169: }
170: locals->destroy(locals);
171: }
172: }
173: remotes->destroy(remotes);
174: }
175: entries->destroy(entries);
176: this->lock->unlock(this->lock);
177:
178: return found;
179: }
180:
181: METHOD(farp_listener_t, destroy, void,
182: private_farp_listener_t *this)
183: {
184: this->entries->destroy(this->entries);
185: this->lock->destroy(this->lock);
186: free(this);
187: }
188:
189: /**
190: * See header
191: */
192: farp_listener_t *farp_listener_create()
193: {
194: private_farp_listener_t *this;
195:
196: INIT(this,
197: .public = {
198: .listener = {
199: .child_updown = _child_updown,
200: },
201: .has_tunnel = _has_tunnel,
202: .destroy = _destroy,
203: },
204: .entries = linked_list_create(),
205: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
206: );
207:
208: return &this->public;
209: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>