From 8093d78d1ca851b52cea53d7e4d08f5f298cc9f7 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Wed, 19 Jan 2022 18:08:40 +0900 Subject: [PATCH 1/2] Add a module-lib API for constructing a LocalSocket from an fd. This allows constructing a LocalSocket from a FileDescriptor referring to an already-connected socket. The LocalSocket can then be used to exchange ancillary filedescriptors and fetch peer socket credentials for the existing FD. The fd is not dup'd or closed by the API, and the caller is responsible for closing it. This is consistent with the constructor of the related LocalServerSocket class, which also takes an fd and does not manage its lifecycle. Bug: 200200870 Test: atest CoreTests:android.net.LocalSocketTest CtsNetTestCases:android.net.cts.LocalSocketTest Change-Id: I86448ba80475c4563194a4a2d9a0c0bbd0b76444 --- core/api/module-lib-current.txt | 4 ++ core/java/android/net/LocalServerSocket.java | 4 +- core/java/android/net/LocalSocket.java | 53 +++++++++++++++----- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 1dcb0c600adfb..450a7dd2bebe2 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -235,6 +235,10 @@ package android.net { method public int getResourceId(); } + public class LocalSocket implements java.io.Closeable { + ctor public LocalSocket(@NonNull java.io.FileDescriptor); + } + public class NetworkIdentity { method public int getOemManaged(); method public int getRatType(); diff --git a/core/java/android/net/LocalServerSocket.java b/core/java/android/net/LocalServerSocket.java index d1f49d2082f5b..506cbcb0623dd 100644 --- a/core/java/android/net/LocalServerSocket.java +++ b/core/java/android/net/LocalServerSocket.java @@ -55,7 +55,9 @@ public class LocalServerSocket implements Closeable { * Create a LocalServerSocket from a file descriptor that's already * been created and bound. listen() will be called immediately on it. * Used for cases where file descriptors are passed in via environment - * variables + * variables. The passed-in FileDescriptor is not managed by this class + * and must be closed by the caller. Calling {@link #close()} on a socket + * created by this method has no effect. * * @param fd bound file descriptor * @throws IOException diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java index 5b38f78782a8c..e9b3f4bc6db24 100644 --- a/core/java/android/net/LocalSocket.java +++ b/core/java/android/net/LocalSocket.java @@ -16,7 +16,14 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + +import android.annotation.NonNull; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.system.ErrnoException; +import android.system.Os; import java.io.Closeable; import java.io.FileDescriptor; @@ -74,32 +81,52 @@ public class LocalSocket implements Closeable { this.isBound = false; } + private void checkConnected() { + try { + Os.getpeername(impl.getFileDescriptor()); + } catch (ErrnoException e) { + throw new IllegalArgumentException("Not a connected socket", e); + } + isConnected = true; + isBound = true; + implCreated = true; + } + + /** + * Creates a LocalSocket instance using the {@link FileDescriptor} for an already-connected + * AF_LOCAL/UNIX domain stream socket. The passed-in FileDescriptor is not managed by this class + * and must be closed by the caller. Calling {@link #close()} on a socket created by this + * method has no effect. + * + * @param fd the filedescriptor to adopt + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public LocalSocket(@NonNull @SuppressLint("UseParcelFileDescriptor") FileDescriptor fd) { + this(new LocalSocketImpl(fd), SOCKET_UNKNOWN); + checkConnected(); + } + /** * Creates a LocalSocket instances using the FileDescriptor for an already-connected * AF_LOCAL/UNIX domain stream socket. Note: the FileDescriptor must be closed by the caller: * closing the LocalSocket will not close it. * - * @hide - used by BluetoothSocket. + * TODO: delete this method when Bluetooth is no longer using it. + * + * @hide */ public static LocalSocket createConnectedLocalSocket(FileDescriptor fd) { - return createConnectedLocalSocket(new LocalSocketImpl(fd), SOCKET_UNKNOWN); + return new LocalSocket(fd); } /** * for use with LocalServerSocket.accept() */ static LocalSocket createLocalSocketForAccept(LocalSocketImpl impl) { - return createConnectedLocalSocket(impl, SOCKET_UNKNOWN); - } - - /** - * Creates a LocalSocket from an existing LocalSocketImpl that is already connected. - */ - private static LocalSocket createConnectedLocalSocket(LocalSocketImpl impl, int sockType) { - LocalSocket socket = new LocalSocket(impl, sockType); - socket.isConnected = true; - socket.isBound = true; - socket.implCreated = true; + LocalSocket socket = new LocalSocket(impl, SOCKET_UNKNOWN); + socket.checkConnected(); return socket; } From d1c55809403ac4962a6a0484b2a1d462d5e9046b Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Tue, 25 Jan 2022 10:01:04 +0900 Subject: [PATCH 2/2] Delete LocalSocket#createConnectedLocalSocket. The only caller of this method was BluetoothSocket, and that is being removed in this topic. Test: m Bug: 200200870 Change-Id: Ic211448bc805c6f74852a8813317444bfb33c9dd --- core/java/android/net/LocalSocket.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java index e9b3f4bc6db24..b69410cf7d732 100644 --- a/core/java/android/net/LocalSocket.java +++ b/core/java/android/net/LocalSocket.java @@ -108,19 +108,6 @@ public class LocalSocket implements Closeable { checkConnected(); } - /** - * Creates a LocalSocket instances using the FileDescriptor for an already-connected - * AF_LOCAL/UNIX domain stream socket. Note: the FileDescriptor must be closed by the caller: - * closing the LocalSocket will not close it. - * - * TODO: delete this method when Bluetooth is no longer using it. - * - * @hide - */ - public static LocalSocket createConnectedLocalSocket(FileDescriptor fd) { - return new LocalSocket(fd); - } - /** * for use with LocalServerSocket.accept() */