Tag network sockets.

This patch tags all update_engine network sockets with 0x55417243
("CrAU" in little-endian) so its network data usage can be tracked.

Bug: 35721166
Test: Ran uniitetst; /proc/net/xt_qtaguid/stats shows this tag.
Change-Id: I8a4076f2958d493a59a5e73af0b6b54f1733e7f2
diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
index 63c67c0..9dcd654 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -16,6 +16,9 @@
 
 #include "update_engine/libcurl_http_fetcher.h"
 
+#include <sys/types.h>
+#include <unistd.h>
+
 #include <algorithm>
 #include <string>
 
@@ -26,6 +29,10 @@
 #include <base/strings/string_util.h>
 #include <base/strings/stringprintf.h>
 
+#ifdef __ANDROID__
+#include <cutils/qtaguid.h>
+#endif  // __ANDROID__
+
 #include "update_engine/certificate_checker.h"
 #include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/platform_constants.h"
@@ -41,7 +48,24 @@
 namespace chromeos_update_engine {
 
 namespace {
+
 const int kNoNetworkRetrySeconds = 10;
+
+// Socket tag used by all network sockets. See qtaguid kernel module for stats.
+const int kUpdateEngineSocketTag = 0x55417243;  // "CrAU" in little-endian.
+
+// libcurl's CURLOPT_SOCKOPTFUNCTION callback function. Called after the socket
+// is created but before it is connected. This callback tags the created socket
+// so the network usage can be tracked in Android.
+int LibcurlSockoptCallback(void* /* clientp */,
+                           curl_socket_t curlfd,
+                           curlsocktype /* purpose */) {
+#ifdef __ANDROID__
+  qtaguid_tagSocket(curlfd, kUpdateEngineSocketTag, getuid());
+#endif  // __ANDROID__
+  return CURL_SOCKOPT_OK;
+}
+
 }  // namespace
 
 LibcurlHttpFetcher::LibcurlHttpFetcher(ProxyResolver* proxy_resolver,
@@ -102,6 +126,10 @@
   CHECK(curl_handle_);
   ignore_failure_ = false;
 
+  // Tag the socket for network usage stats.
+  curl_easy_setopt(
+      curl_handle_, CURLOPT_SOCKOPTFUNCTION, LibcurlSockoptCallback);
+
   CHECK(HasProxy());
   bool is_direct = (GetCurrentProxy() == kNoProxy);
   LOG(INFO) << "Using proxy: " << (is_direct ? "no" : "yes");