Netd callbacks for socket calls in Bionic

Netd callbacks for socket calls sendto(), sendmsg()
and sendmmsg(). It's controlled by two system properties:

[1] ro.vendor.redirect_socket_calls set once in vendor_init context,
read by libnetd_client. It determines if socket calls are shimmed.

[2] net.redirect_socket_calls.hooked set by System Server, read by
shimmed functions. It determines if shimmed functions dispatch
FwmarkCommands.

Bug: 141611769

Change-Id: I3b4a613469bb2b6c9673219217dab121cf392cd5
diff --git a/server/FwmarkServer.cpp b/server/FwmarkServer.cpp
index bf7fe95..885db91 100644
--- a/server/FwmarkServer.cpp
+++ b/server/FwmarkServer.cpp
@@ -85,6 +85,15 @@
     return false;
 }
 
+static bool hasDestinationAddress(FwmarkCommand::CmdId cmdId) {
+    if (cmdId == FwmarkCommand::ON_SENDTO || cmdId == FwmarkCommand::ON_CONNECT ||
+        cmdId == FwmarkCommand::ON_SENDMSG || cmdId == FwmarkCommand::ON_SENDMMSG ||
+        cmdId == FwmarkCommand::ON_CONNECT_COMPLETE) {
+        return true;
+    }
+    return false;
+}
+
 int FwmarkServer::processClient(SocketClient* client, int* socketFd) {
     FwmarkCommand command;
     FwmarkConnectInfo connectInfo;
@@ -103,9 +112,12 @@
     memcpy(&command, buf, sizeof(command));
     memcpy(&connectInfo, buf + sizeof(command), sizeof(connectInfo));
 
-    if (!((command.cmdId != FwmarkCommand::ON_CONNECT_COMPLETE && messageLength == sizeof(command))
-            || (command.cmdId == FwmarkCommand::ON_CONNECT_COMPLETE
-            && messageLength == sizeof(command) + sizeof(connectInfo)))) {
+    size_t expected_len = sizeof(command);
+    if (hasDestinationAddress(command.cmdId)) {
+        expected_len += sizeof(connectInfo);
+    }
+
+    if (messageLength != static_cast<ssize_t>(expected_len)) {
         return -EBADMSG;
     }
 
@@ -234,6 +246,18 @@
             break;
         }
 
+        case FwmarkCommand::ON_SENDMMSG: {
+            return 0;
+        }
+
+        case FwmarkCommand::ON_SENDMSG: {
+            return 0;
+        }
+
+        case FwmarkCommand::ON_SENDTO: {
+            return 0;
+        }
+
         case FwmarkCommand::SELECT_NETWORK: {
             fwmark.netId = command.netId;
             if (command.netId == NETID_UNSET) {