Loading core/java/com/android/server/NetworkManagementSocketTagger.java +31 −86 Original line number Diff line number Diff line Loading @@ -75,30 +75,20 @@ public final class NetworkManagementSocketTagger extends SocketTagger { Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x" + Integer.toHexString(options.statsTag) + ", statsUid=" + options.statsUid); } try { // TODO: skip tagging when options would be no-op tagSocketFd(fd, options.statsTag, options.statsUid); } catch (IOException e) { throw new SocketException("Problem tagging socket", e); } } private void tagSocketFd(FileDescriptor fd, int tag, int uid) throws IOException { final int fdNum = fd.getInt$(); if (fdNum == -1 || (tag == -1 && uid == -1)) return; private void tagSocketFd(FileDescriptor fd, int tag, int uid) { int errno; if (tag == -1 && uid == -1) return; String cmd = "t " + fdNum; if (tag == -1) { // Case where just the uid needs adjusting. But probably the caller // will want to track his own name here, just in case. cmd += " 0"; } else { cmd += " " + tagToKernel(tag); } if (uid != -1) { cmd += " " + uid; errno = native_tagSocketFd(fd, tag, uid); if (errno < 0) { Log.i(TAG, "tagSocketFd(" + fd.getInt$() + ", " + tag + ", " + + uid + ") failed with errno" + errno); } internalModuleCtrl(cmd); } @Override Loading @@ -106,19 +96,18 @@ public final class NetworkManagementSocketTagger extends SocketTagger { if (LOGD) { Log.i(TAG, "untagSocket(" + fd.getInt$() + ")"); } try { unTagSocketFd(fd); } catch (IOException e) { throw new SocketException("Problem untagging socket", e); } } private void unTagSocketFd(FileDescriptor fd) throws IOException { int fdNum = fd.getInt$(); private void unTagSocketFd(FileDescriptor fd) { final SocketTags options = threadSocketTags.get(); if (fdNum == -1 || (options.statsTag == -1 && options.statsUid == -1)) return; String cmd = "u " + fdNum; internalModuleCtrl(cmd); int errno; if (options.statsTag == -1 && options.statsUid == -1) return; errno = native_untagSocketFd(fd); if (errno < 0) { Log.w(TAG, "untagSocket(" + fd.getInt$() + ") failed with errno " + errno); } } public static class SocketTags { Loading @@ -127,68 +116,19 @@ public final class NetworkManagementSocketTagger extends SocketTagger { } public static void setKernelCounterSet(int uid, int counterSet) { final StringBuilder command = new StringBuilder(); command.append("s ").append(counterSet).append(" ").append(uid); try { internalModuleCtrl(command.toString()); } catch (IOException e) { Slog.w(TAG, "problem changing counter set for uid " + uid + " : " + e); int errno = native_setCounterSet(counterSet, uid); if (errno < 0) { Log.w(TAG, "setKernelCountSet(" + uid + ", " + counterSet + ") failed with errno " + errno); } } public static void resetKernelUidStats(int uid) { final StringBuilder command = new StringBuilder(); command.append("d 0 ").append(uid); try { internalModuleCtrl(command.toString()); } catch (IOException e) { Slog.w(TAG, "problem clearing counters for uid " + uid + " : " + e); int errno = native_deleteTagData(0, uid); if (errno < 0) { Slog.w(TAG, "problem clearing counters for uid " + uid + " : errno " + errno); } } /** * Sends commands to the kernel netfilter module. * * @param cmd command string for the qtaguid netfilter module. May not be null. * <p>Supports: * <ul><li>tag a socket:<br> * <code>t <i>sock_fd</i> <i>acct_tag</i> [<i>uid_in_case_caller_is_acting_on_behalf_of</i>]</code><br> * <code>*_tag</code> defaults to default_policy_tag_from_uid(uid_of_caller)<br> * <code>acct_tag</code> is either 0 or greater that 2^32.<br> * <code>uid_*</code> is only settable by privileged UIDs (DownloadManager,...) * </li> * <li>untag a socket, preserving counters:<br> * <code>u <i>sock_fd</i></code> * </li></ul> * <p>Notes:<br> * <ul><li><i>sock_fd</i> is withing the callers process space.</li> * <li><i>*_tag</i> are 64bit values</li></ul> * */ private static void internalModuleCtrl(String cmd) throws IOException { if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return; // TODO: migrate to native library for tagging commands FileOutputStream procOut = null; try { procOut = new FileOutputStream("/proc/net/xt_qtaguid/ctrl"); procOut.write(cmd.getBytes(Charsets.US_ASCII)); } finally { IoUtils.closeQuietly(procOut); } } /** * Convert {@link Integer} tag to {@code /proc/} format. Assumes unsigned * base-10 format like {@code 2147483647}. Currently strips signed bit to * avoid using {@link BigInteger}. */ public static String tagToKernel(int tag) { // TODO: eventually write in hex, since that's what proc exports // TODO: migrate to direct integer instead of odd shifting return Long.toString((((long) tag) << 32) & 0x7FFFFFFF00000000L); } /** * Convert {@code /proc/} tag format to {@link Integer}. Assumes incoming * format like {@code 0x7fffffff00000000}. Loading @@ -197,4 +137,9 @@ public final class NetworkManagementSocketTagger extends SocketTagger { // TODO: migrate to direct integer instead of odd shifting return (int) (Long.decode(string) >> 32); } private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid); private static native int native_untagSocketFd(FileDescriptor fd); private static native int native_setCounterSet(int uid, int counterSetNum); private static native int native_deleteTagData(int tag, int uid); } core/jni/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,7 @@ LOCAL_SRC_FILES:= \ android_server_BluetoothService.cpp \ android_server_BluetoothEventLoop.cpp \ android_server_BluetoothA2dpService.cpp \ android_server_NetworkManagementSocketTagger.cpp \ android_server_Watchdog.cpp \ android_ddm_DdmHandleNativeHeap.cpp \ com_android_internal_os_ZygoteInit.cpp \ Loading core/jni/AndroidRuntime.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ extern int register_android_bluetooth_BluetoothSocket(JNIEnv *env); extern int register_android_server_BluetoothService(JNIEnv* env); extern int register_android_server_BluetoothEventLoop(JNIEnv *env); extern int register_android_server_BluetoothA2dpService(JNIEnv* env); extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env); extern int register_android_server_Watchdog(JNIEnv* env); extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env); extern int register_com_android_internal_os_ZygoteInit(JNIEnv* env); Loading Loading @@ -1178,6 +1179,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_server_BluetoothService), REG_JNI(register_android_server_BluetoothEventLoop), REG_JNI(register_android_server_BluetoothA2dpService), REG_JNI(register_android_server_NetworkManagementSocketTagger), REG_JNI(register_android_server_Watchdog), REG_JNI(register_android_ddm_DdmHandleNativeHeap), REG_JNI(register_android_backup_BackupDataInput), Loading core/jni/android_server_NetworkManagementSocketTagger.cpp 0 → 100644 +97 −0 Original line number Diff line number Diff line /* * Copyright 2011, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "NMST_QTagUidNative" #include <utils/Log.h> #include "JNIHelp.h" #include "jni.h" #include <utils/misc.h> #include <cutils/qtaguid.h> #include <errno.h> #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> namespace android { static jint QTagUid_tagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor, jint tagNum, jint uid) { int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor); if (env->ExceptionOccurred() != NULL) { LOGE("Can't get FileDescriptor num"); return (jint)-1; } int res = qtaguid_tagSocket(userFd, tagNum, uid); if (res < 0) { return (jint)-errno; } return (jint)res; } static int QTagUid_untagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor) { int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor); if (env->ExceptionOccurred() != NULL) { LOGE("Can't get FileDescriptor num"); return (jint)-1; } int res = qtaguid_untagSocket(userFd); if (res < 0) { return (jint)-errno; } return (jint)res; } static jint QTagUid_setCounterSet(JNIEnv* env, jclass, jint setNum, jint uid) { int res = qtaguid_setCounterSet(setNum, uid); if (res < 0) { return (jint)-errno; } return (jint)res; } static jint QTagUid_deleteTagData(JNIEnv* env, jclass, jint tagNum, jint uid) { int res = qtaguid_deleteTagData(tagNum, uid); if (res < 0) { return (jint)-errno; } return (jint)res; } static JNINativeMethod gQTagUidMethods[] = { { "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*)QTagUid_tagSocketFd}, { "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*)QTagUid_untagSocketFd}, { "native_setCounterSet", "(II)I", (void*)QTagUid_setCounterSet}, { "native_deleteTagData", "(II)I", (void*)QTagUid_deleteTagData}, }; int register_android_server_NetworkManagementSocketTagger(JNIEnv* env) { return jniRegisterNativeMethods(env, "com/android/server/NetworkManagementSocketTagger", gQTagUidMethods, NELEM(gQTagUidMethods)); } }; services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java +0 −7 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.net.NetworkStats.SET_FOREGROUND; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static com.android.server.NetworkManagementSocketTagger.kernelToTag; import static com.android.server.NetworkManagementSocketTagger.tagToKernel; import android.content.res.Resources; import android.net.NetworkStats; Loading Loading @@ -144,12 +143,6 @@ public class NetworkManagementServiceTest extends AndroidTestCase { } public void testKernelTags() throws Exception { assertEquals("0", tagToKernel(0x0)); assertEquals("214748364800", tagToKernel(0x32)); assertEquals("9223372032559808512", tagToKernel(Integer.MAX_VALUE)); assertEquals("0", tagToKernel(Integer.MIN_VALUE)); assertEquals("9223369837831520256", tagToKernel(Integer.MIN_VALUE - 512)); assertEquals(0, kernelToTag("0x0000000000000000")); assertEquals(0x32, kernelToTag("0x0000003200000000")); assertEquals(2147483647, kernelToTag("0x7fffffff00000000")); Loading Loading
core/java/com/android/server/NetworkManagementSocketTagger.java +31 −86 Original line number Diff line number Diff line Loading @@ -75,30 +75,20 @@ public final class NetworkManagementSocketTagger extends SocketTagger { Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x" + Integer.toHexString(options.statsTag) + ", statsUid=" + options.statsUid); } try { // TODO: skip tagging when options would be no-op tagSocketFd(fd, options.statsTag, options.statsUid); } catch (IOException e) { throw new SocketException("Problem tagging socket", e); } } private void tagSocketFd(FileDescriptor fd, int tag, int uid) throws IOException { final int fdNum = fd.getInt$(); if (fdNum == -1 || (tag == -1 && uid == -1)) return; private void tagSocketFd(FileDescriptor fd, int tag, int uid) { int errno; if (tag == -1 && uid == -1) return; String cmd = "t " + fdNum; if (tag == -1) { // Case where just the uid needs adjusting. But probably the caller // will want to track his own name here, just in case. cmd += " 0"; } else { cmd += " " + tagToKernel(tag); } if (uid != -1) { cmd += " " + uid; errno = native_tagSocketFd(fd, tag, uid); if (errno < 0) { Log.i(TAG, "tagSocketFd(" + fd.getInt$() + ", " + tag + ", " + + uid + ") failed with errno" + errno); } internalModuleCtrl(cmd); } @Override Loading @@ -106,19 +96,18 @@ public final class NetworkManagementSocketTagger extends SocketTagger { if (LOGD) { Log.i(TAG, "untagSocket(" + fd.getInt$() + ")"); } try { unTagSocketFd(fd); } catch (IOException e) { throw new SocketException("Problem untagging socket", e); } } private void unTagSocketFd(FileDescriptor fd) throws IOException { int fdNum = fd.getInt$(); private void unTagSocketFd(FileDescriptor fd) { final SocketTags options = threadSocketTags.get(); if (fdNum == -1 || (options.statsTag == -1 && options.statsUid == -1)) return; String cmd = "u " + fdNum; internalModuleCtrl(cmd); int errno; if (options.statsTag == -1 && options.statsUid == -1) return; errno = native_untagSocketFd(fd); if (errno < 0) { Log.w(TAG, "untagSocket(" + fd.getInt$() + ") failed with errno " + errno); } } public static class SocketTags { Loading @@ -127,68 +116,19 @@ public final class NetworkManagementSocketTagger extends SocketTagger { } public static void setKernelCounterSet(int uid, int counterSet) { final StringBuilder command = new StringBuilder(); command.append("s ").append(counterSet).append(" ").append(uid); try { internalModuleCtrl(command.toString()); } catch (IOException e) { Slog.w(TAG, "problem changing counter set for uid " + uid + " : " + e); int errno = native_setCounterSet(counterSet, uid); if (errno < 0) { Log.w(TAG, "setKernelCountSet(" + uid + ", " + counterSet + ") failed with errno " + errno); } } public static void resetKernelUidStats(int uid) { final StringBuilder command = new StringBuilder(); command.append("d 0 ").append(uid); try { internalModuleCtrl(command.toString()); } catch (IOException e) { Slog.w(TAG, "problem clearing counters for uid " + uid + " : " + e); int errno = native_deleteTagData(0, uid); if (errno < 0) { Slog.w(TAG, "problem clearing counters for uid " + uid + " : errno " + errno); } } /** * Sends commands to the kernel netfilter module. * * @param cmd command string for the qtaguid netfilter module. May not be null. * <p>Supports: * <ul><li>tag a socket:<br> * <code>t <i>sock_fd</i> <i>acct_tag</i> [<i>uid_in_case_caller_is_acting_on_behalf_of</i>]</code><br> * <code>*_tag</code> defaults to default_policy_tag_from_uid(uid_of_caller)<br> * <code>acct_tag</code> is either 0 or greater that 2^32.<br> * <code>uid_*</code> is only settable by privileged UIDs (DownloadManager,...) * </li> * <li>untag a socket, preserving counters:<br> * <code>u <i>sock_fd</i></code> * </li></ul> * <p>Notes:<br> * <ul><li><i>sock_fd</i> is withing the callers process space.</li> * <li><i>*_tag</i> are 64bit values</li></ul> * */ private static void internalModuleCtrl(String cmd) throws IOException { if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return; // TODO: migrate to native library for tagging commands FileOutputStream procOut = null; try { procOut = new FileOutputStream("/proc/net/xt_qtaguid/ctrl"); procOut.write(cmd.getBytes(Charsets.US_ASCII)); } finally { IoUtils.closeQuietly(procOut); } } /** * Convert {@link Integer} tag to {@code /proc/} format. Assumes unsigned * base-10 format like {@code 2147483647}. Currently strips signed bit to * avoid using {@link BigInteger}. */ public static String tagToKernel(int tag) { // TODO: eventually write in hex, since that's what proc exports // TODO: migrate to direct integer instead of odd shifting return Long.toString((((long) tag) << 32) & 0x7FFFFFFF00000000L); } /** * Convert {@code /proc/} tag format to {@link Integer}. Assumes incoming * format like {@code 0x7fffffff00000000}. Loading @@ -197,4 +137,9 @@ public final class NetworkManagementSocketTagger extends SocketTagger { // TODO: migrate to direct integer instead of odd shifting return (int) (Long.decode(string) >> 32); } private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid); private static native int native_untagSocketFd(FileDescriptor fd); private static native int native_setCounterSet(int uid, int counterSetNum); private static native int native_deleteTagData(int tag, int uid); }
core/jni/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,7 @@ LOCAL_SRC_FILES:= \ android_server_BluetoothService.cpp \ android_server_BluetoothEventLoop.cpp \ android_server_BluetoothA2dpService.cpp \ android_server_NetworkManagementSocketTagger.cpp \ android_server_Watchdog.cpp \ android_ddm_DdmHandleNativeHeap.cpp \ com_android_internal_os_ZygoteInit.cpp \ Loading
core/jni/AndroidRuntime.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ extern int register_android_bluetooth_BluetoothSocket(JNIEnv *env); extern int register_android_server_BluetoothService(JNIEnv* env); extern int register_android_server_BluetoothEventLoop(JNIEnv *env); extern int register_android_server_BluetoothA2dpService(JNIEnv* env); extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env); extern int register_android_server_Watchdog(JNIEnv* env); extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env); extern int register_com_android_internal_os_ZygoteInit(JNIEnv* env); Loading Loading @@ -1178,6 +1179,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_server_BluetoothService), REG_JNI(register_android_server_BluetoothEventLoop), REG_JNI(register_android_server_BluetoothA2dpService), REG_JNI(register_android_server_NetworkManagementSocketTagger), REG_JNI(register_android_server_Watchdog), REG_JNI(register_android_ddm_DdmHandleNativeHeap), REG_JNI(register_android_backup_BackupDataInput), Loading
core/jni/android_server_NetworkManagementSocketTagger.cpp 0 → 100644 +97 −0 Original line number Diff line number Diff line /* * Copyright 2011, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "NMST_QTagUidNative" #include <utils/Log.h> #include "JNIHelp.h" #include "jni.h" #include <utils/misc.h> #include <cutils/qtaguid.h> #include <errno.h> #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> namespace android { static jint QTagUid_tagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor, jint tagNum, jint uid) { int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor); if (env->ExceptionOccurred() != NULL) { LOGE("Can't get FileDescriptor num"); return (jint)-1; } int res = qtaguid_tagSocket(userFd, tagNum, uid); if (res < 0) { return (jint)-errno; } return (jint)res; } static int QTagUid_untagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor) { int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor); if (env->ExceptionOccurred() != NULL) { LOGE("Can't get FileDescriptor num"); return (jint)-1; } int res = qtaguid_untagSocket(userFd); if (res < 0) { return (jint)-errno; } return (jint)res; } static jint QTagUid_setCounterSet(JNIEnv* env, jclass, jint setNum, jint uid) { int res = qtaguid_setCounterSet(setNum, uid); if (res < 0) { return (jint)-errno; } return (jint)res; } static jint QTagUid_deleteTagData(JNIEnv* env, jclass, jint tagNum, jint uid) { int res = qtaguid_deleteTagData(tagNum, uid); if (res < 0) { return (jint)-errno; } return (jint)res; } static JNINativeMethod gQTagUidMethods[] = { { "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*)QTagUid_tagSocketFd}, { "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*)QTagUid_untagSocketFd}, { "native_setCounterSet", "(II)I", (void*)QTagUid_setCounterSet}, { "native_deleteTagData", "(II)I", (void*)QTagUid_deleteTagData}, }; int register_android_server_NetworkManagementSocketTagger(JNIEnv* env) { return jniRegisterNativeMethods(env, "com/android/server/NetworkManagementSocketTagger", gQTagUidMethods, NELEM(gQTagUidMethods)); } };
services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java +0 −7 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.net.NetworkStats.SET_FOREGROUND; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static com.android.server.NetworkManagementSocketTagger.kernelToTag; import static com.android.server.NetworkManagementSocketTagger.tagToKernel; import android.content.res.Resources; import android.net.NetworkStats; Loading Loading @@ -144,12 +143,6 @@ public class NetworkManagementServiceTest extends AndroidTestCase { } public void testKernelTags() throws Exception { assertEquals("0", tagToKernel(0x0)); assertEquals("214748364800", tagToKernel(0x32)); assertEquals("9223372032559808512", tagToKernel(Integer.MAX_VALUE)); assertEquals("0", tagToKernel(Integer.MIN_VALUE)); assertEquals("9223369837831520256", tagToKernel(Integer.MIN_VALUE - 512)); assertEquals(0, kernelToTag("0x0000000000000000")); assertEquals(0x32, kernelToTag("0x0000003200000000")); assertEquals(2147483647, kernelToTag("0x7fffffff00000000")); Loading