blob: bb0d5fe6088414a2bc24204d8b413bb7ff84bfab [file] [log] [blame]
Jaewan Kim63461552014-03-10 17:10:51 +09001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.net;
18
19import android.net.IpConfiguration;
20import android.net.IpConfiguration.IpAssignment;
21import android.net.IpConfiguration.ProxySettings;
22import android.net.LinkAddress;
23import android.net.LinkProperties;
24import android.net.NetworkUtils;
25import android.net.ProxyInfo;
26import android.net.RouteInfo;
27import android.os.Handler;
28import android.os.HandlerThread;
29import android.text.TextUtils;
30import android.util.Log;
31import android.util.SparseArray;
32
33import com.android.server.net.DelayedDiskWrite;
34
35import java.io.BufferedInputStream;
36import java.io.BufferedOutputStream;
37import java.io.DataInputStream;
38import java.io.DataOutputStream;
39import java.io.EOFException;
40import java.io.FileInputStream;
41import java.io.FileOutputStream;
42import java.io.IOException;
43import java.net.InetAddress;
44import java.util.Map;
45
46public class IpConfigStore {
47 private static final String TAG = "IpConfigStore";
48 private static final boolean DBG = true;
49
50 protected final DelayedDiskWrite mWriter;
51
52 /* IP and proxy configuration keys */
53 protected static final String ID_KEY = "id";
54 protected static final String IP_ASSIGNMENT_KEY = "ipAssignment";
55 protected static final String LINK_ADDRESS_KEY = "linkAddress";
56 protected static final String GATEWAY_KEY = "gateway";
57 protected static final String DNS_KEY = "dns";
58 protected static final String PROXY_SETTINGS_KEY = "proxySettings";
59 protected static final String PROXY_HOST_KEY = "proxyHost";
60 protected static final String PROXY_PORT_KEY = "proxyPort";
61 protected static final String PROXY_PAC_FILE = "proxyPac";
62 protected static final String EXCLUSION_LIST_KEY = "exclusionList";
63 protected static final String EOS = "eos";
64
65 protected static final int IPCONFIG_FILE_VERSION = 2;
66
67 public IpConfigStore() {
68 mWriter = new DelayedDiskWrite();
69 }
70
71 private boolean writeConfig(DataOutputStream out, int configKey,
72 IpConfiguration config) throws IOException {
73 boolean written = false;
74
75 try {
76 LinkProperties linkProperties = config.linkProperties;
77 switch (config.ipAssignment) {
78 case STATIC:
79 out.writeUTF(IP_ASSIGNMENT_KEY);
80 out.writeUTF(config.ipAssignment.toString());
81 for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
82 out.writeUTF(LINK_ADDRESS_KEY);
83 out.writeUTF(linkAddr.getAddress().getHostAddress());
84 out.writeInt(linkAddr.getNetworkPrefixLength());
85 }
86 for (RouteInfo route : linkProperties.getRoutes()) {
87 out.writeUTF(GATEWAY_KEY);
88 LinkAddress dest = route.getDestination();
89 if (dest != null) {
90 out.writeInt(1);
91 out.writeUTF(dest.getAddress().getHostAddress());
92 out.writeInt(dest.getNetworkPrefixLength());
93 } else {
94 out.writeInt(0);
95 }
96 if (route.getGateway() != null) {
97 out.writeInt(1);
98 out.writeUTF(route.getGateway().getHostAddress());
99 } else {
100 out.writeInt(0);
101 }
102 }
Robert Greenwalt25702b32014-06-06 10:30:11 -0700103 for (InetAddress inetAddr : linkProperties.getDnsServers()) {
Jaewan Kim63461552014-03-10 17:10:51 +0900104 out.writeUTF(DNS_KEY);
105 out.writeUTF(inetAddr.getHostAddress());
106 }
107 written = true;
108 break;
109 case DHCP:
110 out.writeUTF(IP_ASSIGNMENT_KEY);
111 out.writeUTF(config.ipAssignment.toString());
112 written = true;
113 break;
114 case UNASSIGNED:
115 /* Ignore */
116 break;
117 default:
118 loge("Ignore invalid ip assignment while writing");
119 break;
120 }
121
122 switch (config.proxySettings) {
123 case STATIC:
124 ProxyInfo proxyProperties = linkProperties.getHttpProxy();
125 String exclusionList = proxyProperties.getExclusionListAsString();
126 out.writeUTF(PROXY_SETTINGS_KEY);
127 out.writeUTF(config.proxySettings.toString());
128 out.writeUTF(PROXY_HOST_KEY);
129 out.writeUTF(proxyProperties.getHost());
130 out.writeUTF(PROXY_PORT_KEY);
131 out.writeInt(proxyProperties.getPort());
132 out.writeUTF(EXCLUSION_LIST_KEY);
133 out.writeUTF(exclusionList);
134 written = true;
135 break;
136 case PAC:
137 ProxyInfo proxyPacProperties = linkProperties.getHttpProxy();
138 out.writeUTF(PROXY_SETTINGS_KEY);
139 out.writeUTF(config.proxySettings.toString());
140 out.writeUTF(PROXY_PAC_FILE);
141 out.writeUTF(proxyPacProperties.getPacFileUrl().toString());
142 written = true;
143 break;
144 case NONE:
145 out.writeUTF(PROXY_SETTINGS_KEY);
146 out.writeUTF(config.proxySettings.toString());
147 written = true;
148 break;
149 case UNASSIGNED:
150 /* Ignore */
151 break;
152 default:
153 loge("Ignore invalid proxy settings while writing");
154 break;
155 }
156
157 if (written) {
158 out.writeUTF(ID_KEY);
159 out.writeInt(configKey);
160 }
161 } catch (NullPointerException e) {
162 loge("Failure in writing " + config.linkProperties + e);
163 }
164 out.writeUTF(EOS);
165
166 return written;
167 }
168
169 public void writeIpAndProxyConfigurations(String filePath,
170 final SparseArray<IpConfiguration> networks) {
171 mWriter.write(filePath, new DelayedDiskWrite.Writer() {
172 public void onWriteCalled(DataOutputStream out) throws IOException{
173 out.writeInt(IPCONFIG_FILE_VERSION);
174 for(int i = 0; i < networks.size(); i++) {
175 writeConfig(out, networks.keyAt(i), networks.valueAt(i));
176 }
177 }
178 });
179 }
180
181 public SparseArray<IpConfiguration> readIpAndProxyConfigurations(String filePath) {
182 SparseArray<IpConfiguration> networks = new SparseArray<IpConfiguration>();
183
184 DataInputStream in = null;
185 try {
186 in = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
187
188 int version = in.readInt();
189 if (version != 2 && version != 1) {
190 loge("Bad version on IP configuration file, ignore read");
191 return null;
192 }
193
194 while (true) {
195 int id = -1;
196 // Default is DHCP with no proxy
197 IpAssignment ipAssignment = IpAssignment.DHCP;
198 ProxySettings proxySettings = ProxySettings.NONE;
199 LinkProperties linkProperties = new LinkProperties();
200 String proxyHost = null;
201 String pacFileUrl = null;
202 int proxyPort = -1;
203 String exclusionList = null;
204 String key;
205
206 do {
207 key = in.readUTF();
208 try {
209 if (key.equals(ID_KEY)) {
210 id = in.readInt();
211 } else if (key.equals(IP_ASSIGNMENT_KEY)) {
212 ipAssignment = IpAssignment.valueOf(in.readUTF());
213 } else if (key.equals(LINK_ADDRESS_KEY)) {
214 LinkAddress linkAddr = new LinkAddress(
215 NetworkUtils.numericToInetAddress(in.readUTF()), in.readInt());
216 linkProperties.addLinkAddress(linkAddr);
217 } else if (key.equals(GATEWAY_KEY)) {
218 LinkAddress dest = null;
219 InetAddress gateway = null;
220 if (version == 1) {
221 // only supported default gateways - leave the dest/prefix empty
222 gateway = NetworkUtils.numericToInetAddress(in.readUTF());
223 } else {
224 if (in.readInt() == 1) {
225 dest = new LinkAddress(
226 NetworkUtils.numericToInetAddress(in.readUTF()),
227 in.readInt());
228 }
229 if (in.readInt() == 1) {
230 gateway = NetworkUtils.numericToInetAddress(in.readUTF());
231 }
232 }
233 linkProperties.addRoute(new RouteInfo(dest, gateway));
234 } else if (key.equals(DNS_KEY)) {
Robert Greenwalt25702b32014-06-06 10:30:11 -0700235 linkProperties.addDnsServer(
Jaewan Kim63461552014-03-10 17:10:51 +0900236 NetworkUtils.numericToInetAddress(in.readUTF()));
237 } else if (key.equals(PROXY_SETTINGS_KEY)) {
238 proxySettings = ProxySettings.valueOf(in.readUTF());
239 } else if (key.equals(PROXY_HOST_KEY)) {
240 proxyHost = in.readUTF();
241 } else if (key.equals(PROXY_PORT_KEY)) {
242 proxyPort = in.readInt();
243 } else if (key.equals(PROXY_PAC_FILE)) {
244 pacFileUrl = in.readUTF();
245 } else if (key.equals(EXCLUSION_LIST_KEY)) {
246 exclusionList = in.readUTF();
247 } else if (key.equals(EOS)) {
248 break;
249 } else {
250 loge("Ignore unknown key " + key + "while reading");
251 }
252 } catch (IllegalArgumentException e) {
253 loge("Ignore invalid address while reading" + e);
254 }
255 } while (true);
256
257 if (id != -1) {
258 IpConfiguration config = new IpConfiguration();
259 networks.put(id, config);
260
261 config.linkProperties = linkProperties;
262 switch (ipAssignment) {
263 case STATIC:
264 case DHCP:
265 config.ipAssignment = ipAssignment;
266 break;
267 case UNASSIGNED:
268 loge("BUG: Found UNASSIGNED IP on file, use DHCP");
269 config.ipAssignment = IpAssignment.DHCP;
270 break;
271 default:
272 loge("Ignore invalid ip assignment while reading.");
273 config.ipAssignment = IpAssignment.UNASSIGNED;
274 break;
275 }
276
277 switch (proxySettings) {
278 case STATIC:
279 config.proxySettings = proxySettings;
280 ProxyInfo ProxyInfo =
281 new ProxyInfo(proxyHost, proxyPort, exclusionList);
282 linkProperties.setHttpProxy(ProxyInfo);
283 break;
284 case PAC:
285 config.proxySettings = proxySettings;
286 ProxyInfo proxyPacProperties =
287 new ProxyInfo(pacFileUrl);
288 linkProperties.setHttpProxy(proxyPacProperties);
289 break;
290 case NONE:
291 config.proxySettings = proxySettings;
292 break;
293 case UNASSIGNED:
294 loge("BUG: Found UNASSIGNED proxy on file, use NONE");
295 config.proxySettings = ProxySettings.NONE;
296 break;
297 default:
298 loge("Ignore invalid proxy settings while reading");
299 config.proxySettings = ProxySettings.UNASSIGNED;
300 break;
301 }
302 } else {
303 if (DBG) log("Missing id while parsing configuration");
304 }
305 }
306 } catch (EOFException ignore) {
307 } catch (IOException e) {
Lorenzo Colitti56cf7c52014-05-21 16:30:22 -0700308 loge("Error parsing configuration: " + e);
Jaewan Kim63461552014-03-10 17:10:51 +0900309 } finally {
310 if (in != null) {
311 try {
312 in.close();
313 } catch (Exception e) {}
314 }
315 }
316
317 return networks;
318 }
319
320 protected void loge(String s) {
321 Log.e(TAG, s);
322 }
323
324 protected void log(String s) {
325 Log.d(TAG, s);
326 }
327}