Annotation of embedaddon/strongswan/src/libcharon/plugins/updown/updown_handler.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2012 Martin Willi
3: * Copyright (C) 2012 revosec AG
4: *
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>.
9: *
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
13: * for more details.
14: */
15:
16: #include "updown_handler.h"
17:
18: #include <daemon.h>
19: #include <collections/linked_list.h>
20: #include <threading/rwlock.h>
21:
22: typedef struct private_updown_handler_t private_updown_handler_t;
23:
24: /**
25: * Private data of an updown_handler_t object.
26: */
27: struct private_updown_handler_t {
28:
29: /**
30: * Public updown_handler_t interface.
31: */
32: updown_handler_t public;
33:
34: /**
35: * List of connection specific attributes, as attributes_t
36: */
37: linked_list_t *attrs;
38:
39: /**
40: * rwlock to lock access to pools
41: */
42: rwlock_t *lock;
43: };
44:
45: /**
46: * Attributes assigned to an IKE_SA
47: */
48: typedef struct {
49: /** unique IKE_SA identifier */
50: u_int id;
51: /** list of DNS attributes, as host_t */
52: linked_list_t *dns;
53: } attributes_t;
54:
55: /**
56: * Destroy an attributes_t entry
57: */
58: static void attributes_destroy(attributes_t *this)
59: {
60: this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
61: free(this);
62: }
63:
64: METHOD(attribute_handler_t, handle, bool,
65: private_updown_handler_t *this, ike_sa_t *ike_sa,
66: configuration_attribute_type_t type, chunk_t data)
67: {
68: attributes_t *current, *attr = NULL;
69: enumerator_t *enumerator;
70: host_t *host;
71:
72: switch (type)
73: {
74: case INTERNAL_IP4_DNS:
75: host = host_create_from_chunk(AF_INET, data, 0);
76: break;
77: case INTERNAL_IP6_DNS:
78: host = host_create_from_chunk(AF_INET6, data, 0);
79: break;
80: default:
81: return FALSE;
82: }
83: if (!host)
84: {
85: return FALSE;
86: }
87:
88: this->lock->write_lock(this->lock);
89: enumerator = this->attrs->create_enumerator(this->attrs);
90: while (enumerator->enumerate(enumerator, ¤t))
91: {
92: if (current->id == ike_sa->get_unique_id(ike_sa))
93: {
94: attr = current;
95: }
96: }
97: enumerator->destroy(enumerator);
98:
99: if (!attr)
100: {
101: INIT(attr,
102: .id = ike_sa->get_unique_id(ike_sa),
103: .dns = linked_list_create(),
104: );
105: this->attrs->insert_last(this->attrs, attr);
106: }
107: attr->dns->insert_last(attr->dns, host);
108: this->lock->unlock(this->lock);
109:
110: return TRUE;
111: }
112:
113: METHOD(attribute_handler_t, release, void,
114: private_updown_handler_t *this, ike_sa_t *ike_sa,
115: configuration_attribute_type_t type, chunk_t data)
116: {
117: attributes_t *attr;
118: enumerator_t *enumerator, *servers;
119: host_t *host;
120: bool found = FALSE;
121: int family;
122:
123: switch (type)
124: {
125: case INTERNAL_IP4_DNS:
126: family = AF_INET;
127: break;
128: case INTERNAL_IP6_DNS:
129: family = AF_INET6;
130: break;
131: default:
132: return;
133: }
134:
135: this->lock->write_lock(this->lock);
136: enumerator = this->attrs->create_enumerator(this->attrs);
137: while (enumerator->enumerate(enumerator, &attr))
138: {
139: if (attr->id == ike_sa->get_unique_id(ike_sa))
140: {
141: servers = attr->dns->create_enumerator(attr->dns);
142: while (servers->enumerate(servers, &host))
143: {
144: if (host->get_family(host) == family &&
145: chunk_equals(data, host->get_address(host)))
146: {
147: attr->dns->remove_at(attr->dns, servers);
148: host->destroy(host);
149: found = TRUE;
150: break;
151: }
152: }
153: servers->destroy(servers);
154: if (attr->dns->get_count(attr->dns) == 0)
155: {
156: this->attrs->remove_at(this->attrs, enumerator);
157: attributes_destroy(attr);
158: break;
159: }
160: }
161: if (found)
162: {
163: break;
164: }
165: }
166: enumerator->destroy(enumerator);
167: this->lock->unlock(this->lock);
168: }
169:
170: METHOD(updown_handler_t, create_dns_enumerator, enumerator_t*,
171: private_updown_handler_t *this, u_int id)
172: {
173: attributes_t *attr;
174: enumerator_t *enumerator;
175: ike_sa_t *ike_sa;
176:
177: ike_sa = charon->bus->get_sa(charon->bus);
178: if (!ike_sa)
179: {
180: return enumerator_create_empty();
181: }
182:
183: this->lock->read_lock(this->lock);
184: enumerator = this->attrs->create_enumerator(this->attrs);
185: while (enumerator->enumerate(enumerator, &attr))
186: {
187: if (attr->id == ike_sa->get_unique_id(ike_sa))
188: {
189: enumerator->destroy(enumerator);
190: return enumerator_create_cleaner(
191: attr->dns->create_enumerator(attr->dns),
192: (void*)this->lock->unlock, this->lock);
193: }
194: }
195: enumerator->destroy(enumerator);
196: this->lock->unlock(this->lock);
197:
198: return enumerator_create_empty();
199: }
200:
201:
202: METHOD(updown_handler_t, destroy, void,
203: private_updown_handler_t *this)
204: {
205: this->lock->destroy(this->lock);
206: this->attrs->destroy_function(this->attrs, (void*)attributes_destroy);
207: free(this);
208: }
209:
210: /**
211: * See header
212: */
213: updown_handler_t *updown_handler_create()
214: {
215: private_updown_handler_t *this;
216:
217: INIT(this,
218: .public = {
219: .handler = {
220: .handle = _handle,
221: .release = _release,
222: .create_attribute_enumerator = enumerator_create_empty,
223: },
224: .create_dns_enumerator = _create_dns_enumerator,
225: .destroy = _destroy,
226: },
227: .attrs = linked_list_create(),
228: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
229: );
230:
231: return &this->public;
232: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>