2 * Copyright (C) 2019 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
5 * Copyright (C) 2010 Martin Willi
6 * Copyright (C) 2010 revosec AG
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>.
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
19 #include "farp_listener.h"
21 #include <collections/linked_list.h>
22 #include <threading/rwlock.h>
24 typedef struct private_farp_listener_t private_farp_listener_t
;
27 * Private data of an farp_listener_t object.
29 struct private_farp_listener_t
{
32 * Public farp_listener_t interface.
34 farp_listener_t
public;
39 linked_list_t
*entries
;
48 * Traffic selector cache entry
51 /** list of local selectors */
53 /** list of remote selectors */
54 linked_list_t
*remote
;
55 /** reqid of CHILD_SA */
60 * Destroy a cache entry
62 static void destroy_entry(entry_t
*this)
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
));
71 METHOD(listener_t
, child_updown
, bool,
72 private_farp_listener_t
*this, ike_sa_t
*ike_sa
, child_sa_t
*child_sa
,
75 enumerator_t
*enumerator
;
76 traffic_selector_t
*ts
;
82 .local
= linked_list_create(),
83 .remote
= linked_list_create(),
84 .reqid
= child_sa
->get_reqid(child_sa
),
87 enumerator
= child_sa
->create_ts_enumerator(child_sa
, FALSE
);
88 while (enumerator
->enumerate(enumerator
, &ts
))
90 if (ts
->get_type(ts
) != TS_IPV4_ADDR_RANGE
)
94 entry
->remote
->insert_last(entry
->remote
, ts
->clone(ts
));
96 enumerator
->destroy(enumerator
);
98 enumerator
= child_sa
->create_ts_enumerator(child_sa
, TRUE
);
99 while (enumerator
->enumerate(enumerator
, &ts
))
101 if (ts
->get_type(ts
) != TS_IPV4_ADDR_RANGE
)
105 entry
->local
->insert_last(entry
->local
, ts
->clone(ts
));
107 enumerator
->destroy(enumerator
);
109 if (!entry
->remote
->get_count(entry
->remote
) ||
110 !entry
->local
->get_count(entry
->local
))
112 destroy_entry(entry
);
116 this->lock
->write_lock(this->lock
);
117 this->entries
->insert_last(this->entries
, entry
);
118 this->lock
->unlock(this->lock
);
122 this->lock
->write_lock(this->lock
);
123 enumerator
= this->entries
->create_enumerator(this->entries
);
124 while (enumerator
->enumerate(enumerator
, &entry
))
126 if (entry
->reqid
== child_sa
->get_reqid(child_sa
))
128 this->entries
->remove_at(this->entries
, enumerator
);
129 destroy_entry(entry
);
133 enumerator
->destroy(enumerator
);
134 this->lock
->unlock(this->lock
);
139 METHOD(farp_listener_t
, has_tunnel
, bool,
140 private_farp_listener_t
*this, host_t
*local
, host_t
*remote
)
142 enumerator_t
*entries
, *locals
, *remotes
;
143 traffic_selector_t
*ts
;
147 this->lock
->read_lock(this->lock
);
148 entries
= this->entries
->create_enumerator(this->entries
);
149 while (!found
&& entries
->enumerate(entries
, &entry
))
151 remotes
= entry
->remote
->create_enumerator(entry
->remote
);
152 while (!found
&& remotes
->enumerate(remotes
, &ts
))
154 if (ts
->includes(ts
, remote
))
156 locals
= entry
->local
->create_enumerator(entry
->local
);
157 while (!found
&& locals
->enumerate(locals
, &ts
))
159 found
= ts
->includes(ts
, local
);
161 locals
->destroy(locals
);
164 remotes
->destroy(remotes
);
166 entries
->destroy(entries
);
167 this->lock
->unlock(this->lock
);
172 METHOD(farp_listener_t
, destroy
, void,
173 private_farp_listener_t
*this)
175 this->entries
->destroy(this->entries
);
176 this->lock
->destroy(this->lock
);
183 farp_listener_t
*farp_listener_create()
185 private_farp_listener_t
*this;
190 .child_updown
= _child_updown
,
192 .has_tunnel
= _has_tunnel
,
195 .entries
= linked_list_create(),
196 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
199 return &this->public;