1 /* 2 * Copyright (C) 2020 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 17 package com.android.internal.net; 18 19 import static android.system.OsConstants.AF_INET; 20 import static android.system.OsConstants.AF_INET6; 21 22 import android.annotation.NonNull; 23 import android.system.Os; 24 25 import java.io.FileDescriptor; 26 27 /** @hide */ 28 public class NetworkUtilsInternal { 29 30 private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET, AF_INET6}; 31 32 /** 33 * Allow/Disallow creating AF_INET/AF_INET6 sockets and DNS lookups for current process. 34 * 35 * @param allowNetworking whether to allow or disallow creating AF_INET/AF_INET6 sockets 36 * and DNS lookups. 37 */ setAllowNetworkingForProcess(boolean allowNetworking)38 public static native void setAllowNetworkingForProcess(boolean allowNetworking); 39 40 /** 41 * Protect {@code fd} from VPN connections. After protecting, data sent through 42 * this socket will go directly to the underlying network, so its traffic will not be 43 * forwarded through the VPN. 44 */ protectFromVpn(FileDescriptor fd)45 public static native boolean protectFromVpn(FileDescriptor fd); 46 47 /** 48 * Protect {@code socketfd} from VPN connections. After protecting, data sent through 49 * this socket will go directly to the underlying network, so its traffic will not be 50 * forwarded through the VPN. 51 */ protectFromVpn(int socketfd)52 public static native boolean protectFromVpn(int socketfd); 53 54 /** 55 * Returns true if the hostname is weakly validated. 56 * @param hostname Name of host to validate. 57 * @return True if it's a valid-ish hostname. 58 * 59 * @hide 60 */ isWeaklyValidatedHostname(@onNull String hostname)61 public static boolean isWeaklyValidatedHostname(@NonNull String hostname) { 62 // TODO(b/34953048): Use a validation method that permits more accurate, 63 // but still inexpensive, checking of likely valid DNS hostnames. 64 final String weakHostnameRegex = "^[a-zA-Z0-9_.-]+$"; 65 if (!hostname.matches(weakHostnameRegex)) { 66 return false; 67 } 68 69 for (int address_family : ADDRESS_FAMILIES) { 70 if (Os.inet_pton(address_family, hostname) != null) { 71 return false; 72 } 73 } 74 75 return true; 76 } 77 78 /** 79 * Safely multiple a value by a rational. 80 * <p> 81 * Internally it uses integer-based math whenever possible, but switches 82 * over to double-based math if values would overflow. 83 * @hide 84 */ multiplySafeByRational(long value, long num, long den)85 public static long multiplySafeByRational(long value, long num, long den) { 86 if (den == 0) { 87 throw new ArithmeticException("Invalid Denominator"); 88 } 89 long x = value; 90 long y = num; 91 92 // Logic shamelessly borrowed from Math.multiplyExact() 93 long r = x * y; 94 long ax = Math.abs(x); 95 long ay = Math.abs(y); 96 if (((ax | ay) >>> 31 != 0)) { 97 // Some bits greater than 2^31 that might cause overflow 98 // Check the result using the divide operator 99 // and check for the special case of Long.MIN_VALUE * -1 100 if (((y != 0) && (r / y != x)) 101 || (x == Long.MIN_VALUE && y == -1)) { 102 // Use double math to avoid overflowing 103 return (long) (((double) num / den) * value); 104 } 105 } 106 return r / den; 107 } 108 } 109