2 * Copyright (C) 2012 Martin Willi
3 * Copyright (C) 2012 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "updown_handler.h"
19 #include <collections/linked_list.h>
20 #include <threading/rwlock.h>
22 typedef struct private_updown_handler_t private_updown_handler_t
;
25 * Private data of an updown_handler_t object.
27 struct private_updown_handler_t
{
30 * Public updown_handler_t interface.
32 updown_handler_t
public;
35 * List of connection specific attributes, as attributes_t
40 * rwlock to lock access to pools
46 * Attributes assigned to an IKE_SA
49 /** unique IKE_SA identifier */
51 /** list of DNS attributes, as host_t */
56 * Destroy an attributes_t entry
58 static void attributes_destroy(attributes_t
*this)
60 this->dns
->destroy_offset(this->dns
, offsetof(host_t
, destroy
));
64 METHOD(attribute_handler_t
, handle
, bool,
65 private_updown_handler_t
*this, identification_t
*server
,
66 configuration_attribute_type_t type
, chunk_t data
)
68 attributes_t
*current
, *attr
= NULL
;
69 enumerator_t
*enumerator
;
73 ike_sa
= charon
->bus
->get_sa(charon
->bus
);
80 case INTERNAL_IP4_DNS
:
81 host
= host_create_from_chunk(AF_INET
, data
, 0);
83 case INTERNAL_IP6_DNS
:
84 host
= host_create_from_chunk(AF_INET6
, data
, 0);
94 this->lock
->write_lock(this->lock
);
95 enumerator
= this->attrs
->create_enumerator(this->attrs
);
96 while (enumerator
->enumerate(enumerator
, ¤t
))
98 if (current
->id
== ike_sa
->get_unique_id(ike_sa
))
103 enumerator
->destroy(enumerator
);
108 .id
= ike_sa
->get_unique_id(ike_sa
),
109 .dns
= linked_list_create(),
111 this->attrs
->insert_last(this->attrs
, attr
);
113 attr
->dns
->insert_last(attr
->dns
, host
);
114 this->lock
->unlock(this->lock
);
119 METHOD(attribute_handler_t
, release
, void,
120 private_updown_handler_t
*this, identification_t
*server
,
121 configuration_attribute_type_t type
, chunk_t data
)
124 enumerator_t
*enumerator
, *servers
;
132 case INTERNAL_IP4_DNS
:
135 case INTERNAL_IP6_DNS
:
142 ike_sa
= charon
->bus
->get_sa(charon
->bus
);
145 this->lock
->write_lock(this->lock
);
146 enumerator
= this->attrs
->create_enumerator(this->attrs
);
147 while (enumerator
->enumerate(enumerator
, &attr
))
149 if (attr
->id
== ike_sa
->get_unique_id(ike_sa
))
151 servers
= attr
->dns
->create_enumerator(attr
->dns
);
152 while (servers
->enumerate(servers
, &host
))
154 if (host
->get_family(host
) == family
&&
155 chunk_equals(data
, host
->get_address(host
)))
157 attr
->dns
->remove_at(attr
->dns
, servers
);
163 servers
->destroy(servers
);
164 if (attr
->dns
->get_count(attr
->dns
) == 0)
166 this->attrs
->remove_at(this->attrs
, enumerator
);
167 attributes_destroy(attr
);
176 enumerator
->destroy(enumerator
);
177 this->lock
->unlock(this->lock
);
181 METHOD(updown_handler_t
, create_dns_enumerator
, enumerator_t
*,
182 private_updown_handler_t
*this, u_int id
)
185 enumerator_t
*enumerator
;
188 ike_sa
= charon
->bus
->get_sa(charon
->bus
);
191 return enumerator_create_empty();
194 this->lock
->read_lock(this->lock
);
195 enumerator
= this->attrs
->create_enumerator(this->attrs
);
196 while (enumerator
->enumerate(enumerator
, &attr
))
198 if (attr
->id
== ike_sa
->get_unique_id(ike_sa
))
200 enumerator
->destroy(enumerator
);
201 return enumerator_create_cleaner(
202 attr
->dns
->create_enumerator(attr
->dns
),
203 (void*)this->lock
->unlock
, this->lock
);
206 enumerator
->destroy(enumerator
);
207 this->lock
->unlock(this->lock
);
209 return enumerator_create_empty();
213 METHOD(updown_handler_t
, destroy
, void,
214 private_updown_handler_t
*this)
216 this->lock
->destroy(this->lock
);
217 this->attrs
->destroy_function(this->attrs
, (void*)attributes_destroy
);
224 updown_handler_t
*updown_handler_create()
226 private_updown_handler_t
*this;
233 .create_attribute_enumerator
= enumerator_create_empty
,
235 .create_dns_enumerator
= _create_dns_enumerator
,
238 .attrs
= linked_list_create(),
239 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
242 return &this->public;