Pass around struct android_net_context for better behaviour
Group network context elements in to a single struct and
add a version of android_getaddrinfofornet() that accepts it.
The introduction of UID-based routing means that the UID is an
integral part of the network context when evaluating connectivity,
sorting addresses, etc.
Also, introduce a distinction between DNS netids/marks and those
expected to be used by the application. This can be important
when the network an application is using is not the same as the
network on which DNS queries will be issued.
Additionally, de-duplicate the UDP connect logic (collapse both
_test_connect() and _find_src_addr() into just the latter).
Bug: 19470192
Bug: 20733156
Bug: 21832279
Change-Id: If16c2f4744695f507993afdac078ca105eb5d3e4
diff --git a/libc/dns/include/resolv_netid.h b/libc/dns/include/resolv_netid.h
index 1d0f869..d364645 100644
--- a/libc/dns/include/resolv_netid.h
+++ b/libc/dns/include/resolv_netid.h
@@ -53,10 +53,37 @@
#define __used_in_netd __attribute__((visibility ("default")))
+/*
+ * A struct to capture context relevant to network operations.
+ *
+ * Application and DNS netids/marks can differ from one another under certain
+ * circumstances, notably when a VPN applies to the given uid's traffic but the
+ * VPN network does not have its own DNS servers explicitly provisioned.
+ *
+ * The introduction of per-UID routing means the uid is also an essential part
+ * of the evaluation context. Its proper uninitialized value is
+ * NET_CONTEXT_INVALID_UID.
+ */
+struct android_net_context {
+ unsigned app_netid;
+ unsigned app_mark;
+ unsigned dns_netid;
+ unsigned dns_mark;
+ uid_t uid;
+} __attribute__((packed));
+
+#define NET_CONTEXT_INVALID_UID ((uid_t)-1)
+
struct hostent *android_gethostbyaddrfornet(const void *, socklen_t, int, unsigned, unsigned) __used_in_netd;
struct hostent *android_gethostbynamefornet(const char *, int, unsigned, unsigned) __used_in_netd;
int android_getaddrinfofornet(const char *, const char *, const struct addrinfo *, unsigned,
- unsigned, struct addrinfo **) __used_in_netd;
+ unsigned, struct addrinfo **) __used_in_netd;
+/*
+ * TODO: consider refactoring android_getaddrinfo_proxy() to serve as an
+ * explore_fqdn() dispatch table method, with the below function only making DNS calls.
+ */
+int android_getaddrinfofornetcontext(const char *, const char *, const struct addrinfo *,
+ const struct android_net_context *, struct addrinfo **) __used_in_netd;
/* set name servers for a network */
extern void _resolv_set_nameservers_for_net(unsigned netid,