IpConfigStore.java revision 56cf7c517e33df5f871f85c13a2e2315b20cb2ed
1/* 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 } 103 for (InetAddress inetAddr : linkProperties.getDnses()) { 104 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)) { 235 linkProperties.addDns( 236 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) { 308 loge("Error parsing configuration: " + e); 309 } 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} 328