]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libcharon/plugins/android/android_handler.c
Correctly install DNS servers on Android if frontend is not used.
[thirdparty/strongswan.git] / src / libcharon / plugins / android / android_handler.c
CommitLineData
55699f03 1/*
4437914a 2 * Copyright (C) 2010-2011 Tobias Brunner
55699f03 3 * Copyright (C) 2010 Martin Willi
55699f03
MW
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
71070c88 17#include "android_handler.h"
55699f03
MW
18
19#include <utils/linked_list.h>
20
21#include <cutils/properties.h>
22
71070c88 23typedef struct private_android_handler_t private_android_handler_t;
55699f03
MW
24
25/**
71070c88 26 * Private data of an android_handler_t object.
55699f03 27 */
71070c88 28struct private_android_handler_t {
55699f03
MW
29
30 /**
71070c88 31 * Public android_handler_t interface.
55699f03 32 */
71070c88 33 android_handler_t public;
55699f03
MW
34
35 /**
36 * List of registered DNS servers
37 */
38 linked_list_t *dns;
4437914a
TB
39
40 /**
41 * Whether the VPN frontend is used
42 */
43 bool frontend;
55699f03
MW
44};
45
4437914a
TB
46/**
47 * Prefixes to be used when installing DNS servers
48 */
49#define DNS_PREFIX_DEFAULT "net"
50#define DNS_PREFIX_FRONTEND "vpn"
51
55699f03
MW
52/**
53 * Struct to store a pair of old and installed DNS servers
54 */
55typedef struct {
56 /** installed dns server */
57 host_t *dns;
58 /** old dns server */
59 host_t *old;
60} dns_pair_t;
61
62/**
63 * Destroy a pair of old and installed DNS servers
64 */
65void destroy_dns_pair(dns_pair_t *this)
66{
67 DESTROY_IF(this->dns);
68 DESTROY_IF(this->old);
69 free(this);
70}
71
72/**
73 * Filter pairs of DNS servers
74 */
75bool filter_dns_pair(void *data, dns_pair_t **in, host_t **out)
76{
77 *out = (*in)->dns;
78 return TRUE;
79}
80
81/**
82 * Read DNS server property with a given index
83 */
4437914a 84host_t *get_dns_server(private_android_handler_t *this, int index)
55699f03
MW
85{
86 host_t *dns = NULL;
4437914a
TB
87 char key[10], value[PROPERTY_VALUE_MAX],
88 *prefix = this->frontend ? DNS_PREFIX_FRONTEND : DNS_PREFIX_DEFAULT;
55699f03 89
4437914a 90 if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key))
55699f03
MW
91 {
92 return NULL;
93 }
94
95 if (property_get(key, value, NULL) > 0)
96 {
97 dns = host_create_from_string(value, 0);
98 }
99 return dns;
100}
101
102/**
103 * Set DNS server property with a given index
104 */
4437914a 105bool set_dns_server(private_android_handler_t *this, int index, host_t *dns)
55699f03 106{
4437914a
TB
107 char key[10], value[PROPERTY_VALUE_MAX],
108 *prefix = this->frontend ? DNS_PREFIX_FRONTEND : DNS_PREFIX_DEFAULT;
55699f03 109
4437914a 110 if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key))
55699f03
MW
111 {
112 return FALSE;
113 }
114
115 if (dns)
116 {
117 if (snprintf(value, sizeof(value), "%H", dns) >= sizeof(value))
118 {
119 return FALSE;
120 }
121 }
122 else
123 {
124 value[0] = '\0';
125 }
126
127 if (property_set(key, value) != 0)
128 {
129 return FALSE;
130 }
131 return TRUE;
132}
133
134METHOD(attribute_handler_t, handle, bool,
71070c88 135 private_android_handler_t *this, identification_t *id,
55699f03
MW
136 configuration_attribute_type_t type, chunk_t data)
137{
138 switch (type)
139 {
140 case INTERNAL_IP4_DNS:
141 {
142 host_t *dns;
143 dns_pair_t *pair;
144 int index;
145
146 dns = host_create_from_chunk(AF_INET, data, 0);
147 if (dns)
148 {
149 pair = malloc_thing(dns_pair_t);
150 pair->dns = dns;
151 index = this->dns->get_count(this->dns) + 1;
4437914a
TB
152 pair->old = get_dns_server(this, index);
153 set_dns_server(this, index, dns);
55699f03
MW
154 this->dns->insert_last(this->dns, pair);
155 return TRUE;
156 }
157 return FALSE;
71070c88 158 }
55699f03
MW
159 default:
160 return FALSE;
161 }
162}
163
164METHOD(attribute_handler_t, release, void,
71070c88 165 private_android_handler_t *this, identification_t *server,
55699f03
MW
166 configuration_attribute_type_t type, chunk_t data)
167{
168 if (type == INTERNAL_IP4_DNS)
169 {
170 enumerator_t *enumerator;
171 dns_pair_t *pair;
172 int index;
173
174 enumerator = this->dns->create_enumerator(this->dns);
175 for (index = 1; enumerator->enumerate(enumerator, &pair); index++)
176 {
177 if (chunk_equals(pair->dns->get_address(pair->dns), data))
178 {
179 this->dns->remove_at(this->dns, enumerator);
4437914a 180 set_dns_server(this, index, pair->old);
55699f03
MW
181 destroy_dns_pair(pair);
182 }
183 }
184 enumerator->destroy(enumerator);
185 }
186}
187
188METHOD(enumerator_t, enumerate_dns, bool,
189 enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data)
190{
191 *type = INTERNAL_IP4_DNS;
192 *data = chunk_empty;
193 /* stop enumeration */
194 this->enumerate = (void*)return_false;
195 return TRUE;
196}
197
198METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
71070c88 199 android_handler_t *this, identification_t *id, host_t *vip)
55699f03
MW
200{
201 enumerator_t *enumerator;
202
203 INIT(enumerator,
204 .enumerate = (void*)_enumerate_dns,
205 .destroy = (void*)free,
206 );
207 return enumerator;
208}
209
71070c88
MW
210METHOD(android_handler_t, destroy, void,
211 private_android_handler_t *this)
55699f03
MW
212{
213 this->dns->destroy_function(this->dns, (void*)destroy_dns_pair);
214 free(this);
215}
216
217/**
218 * See header
219 */
4437914a 220android_handler_t *android_handler_create(bool frontend)
55699f03 221{
71070c88 222 private_android_handler_t *this;
55699f03
MW
223
224 INIT(this,
225 .public = {
226 .handler = {
227 .handle = _handle,
228 .release = _release,
229 .create_attribute_enumerator = _create_attribute_enumerator,
230 },
231 .destroy = _destroy,
232 },
233 .dns = linked_list_create(),
4437914a 234 .frontend = frontend,
55699f03
MW
235 );
236
237 return &this->public;
238}
239