libbinder: Session ID implemented directly.

In preparation for removing RpcAddress.

Bug: 182940634
Test: binderRpcTest (w & w/o LOG_RPC_DETAIL)
Change-Id: I945e650bbab9f8df4f785b689983b62c59bb8674
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index ad9ba96..ad04702 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -23,6 +23,8 @@
 #include <thread>
 #include <vector>
 
+#include <android-base/file.h>
+#include <android-base/hex.h>
 #include <android-base/scopeguard.h>
 #include <binder/Parcel.h>
 #include <binder/RpcServer.h>
@@ -290,17 +292,29 @@
         }
     }
 
+    std::vector<uint8_t> sessionId;
+    if (status == OK) {
+        if (header.sessionIdSize > 0) {
+            sessionId.resize(header.sessionIdSize);
+            status = client->interruptableReadFully(server->mShutdownTrigger.get(),
+                                                    sessionId.data(), sessionId.size());
+            if (status != OK) {
+                ALOGE("Failed to read session ID for client connecting to RPC server: %s",
+                      statusToString(status).c_str());
+                // still need to cleanup before we can return
+            }
+        }
+    }
+
     bool incoming = false;
     uint32_t protocolVersion = 0;
-    RpcAddress sessionId = RpcAddress::zero();
     bool requestingNewSession = false;
 
     if (status == OK) {
         incoming = header.options & RPC_CONNECTION_OPTION_INCOMING;
         protocolVersion = std::min(header.version,
                                    server->mProtocolVersion.value_or(RPC_WIRE_PROTOCOL_VERSION));
-        sessionId = RpcAddress::fromRawEmbedded(&header.sessionId);
-        requestingNewSession = sessionId.isZero();
+        requestingNewSession = sessionId.empty();
 
         if (requestingNewSession) {
             RpcNewSessionResponse response{
@@ -342,15 +356,26 @@
                 return;
             }
 
+            // Uniquely identify session at the application layer. Even if a
+            // client/server use the same certificates, if they create multiple
+            // sessions, we still want to distinguish between them.
+            constexpr size_t kSessionIdSize = 32;
+            sessionId.resize(kSessionIdSize);
             size_t tries = 0;
             do {
                 // don't block if there is some entropy issue
                 if (tries++ > 5) {
-                    ALOGE("Cannot find new address: %s", sessionId.toString().c_str());
+                    ALOGE("Cannot find new address: %s",
+                          base::HexString(sessionId.data(), sessionId.size()).c_str());
                     return;
                 }
 
-                sessionId = RpcAddress::random(true /*forServer*/);
+                base::unique_fd fd(TEMP_FAILURE_RETRY(
+                        open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW)));
+                if (!base::ReadFully(fd, sessionId.data(), sessionId.size())) {
+                    ALOGE("Could not read from /dev/urandom to create session ID");
+                    return;
+                }
             } while (server->mSessions.end() != server->mSessions.find(sessionId));
 
             session = RpcSession::make();
@@ -370,7 +395,7 @@
             auto it = server->mSessions.find(sessionId);
             if (it == server->mSessions.end()) {
                 ALOGE("Cannot add thread, no record of session with ID %s",
-                      sessionId.toString().c_str());
+                      base::HexString(sessionId.data(), sessionId.size()).c_str());
                 return;
             }
             session = it->second;
@@ -432,16 +457,17 @@
 }
 
 void RpcServer::onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) {
-    auto id = session->mId;
-    LOG_ALWAYS_FATAL_IF(id == std::nullopt, "Server sessions must be initialized with ID");
-    LOG_RPC_DETAIL("Dropping session with address %s", id->toString().c_str());
+    const std::vector<uint8_t>& id = session->mId;
+    LOG_ALWAYS_FATAL_IF(id.empty(), "Server sessions must be initialized with ID");
+    LOG_RPC_DETAIL("Dropping session with address %s",
+                   base::HexString(id.data(), id.size()).c_str());
 
     std::lock_guard<std::mutex> _l(mLock);
-    auto it = mSessions.find(*id);
+    auto it = mSessions.find(id);
     LOG_ALWAYS_FATAL_IF(it == mSessions.end(), "Bad state, unknown session id %s",
-                        id->toString().c_str());
+                        base::HexString(id.data(), id.size()).c_str());
     LOG_ALWAYS_FATAL_IF(it->second != session, "Bad state, session has id mismatch %s",
-                        id->toString().c_str());
+                        base::HexString(id.data(), id.size()).c_str());
     (void)mSessions.erase(it);
 }