perf: network tables Android refuses are served from the synthesized copy without retrying the open (#1275)

This commit is contained in:
MaxsTechReview authored and GitHub committed 2026-10-21 17:18:11 -04:00
1 parent e04727dbaf
commit 7fa8008944
1 file changed
+52 -11
+52 -11
View File
@@ -506,19 +506,55 @@ static void write_table(FILE *out, const char *table, const struct link *link) {
}
}
static const char *denied_table(const char *path) {
static const char *const tables[] = { "route", "ipv6_route", "if_inet6", "dev", "arp" };
#define CARRIER_TABLE 5
static const char *const net_tables[] = { "route", "ipv6_route", "if_inet6", "dev", "arp", "carrier" };
static long long net_denied_at[sizeof(net_tables) / sizeof(net_tables[0])];
#define CARRIER_SLOTS 8
static struct { char path[64]; long long at; } carrier_denied[CARRIER_SLOTS];
static int denied_recently(int table, const char *path) {
if (table != CARRIER_TABLE) return fresh(&net_denied_at[table]);
int hit = 0;
pthread_mutex_lock(&link_lock);
for (int i = 0; i < CARRIER_SLOTS && !hit; i++) {
hit = strcmp(carrier_denied[i].path, path) == 0 && fresh(&carrier_denied[i].at);
}
pthread_mutex_unlock(&link_lock);
return hit;
}
static void remember_denial(int table, const char *path) {
if (table != CARRIER_TABLE) {
__atomic_store_n(&net_denied_at[table], now_ns(), __ATOMIC_RELAXED);
return;
}
if (strlen(path) >= sizeof(carrier_denied[0].path)) return;
pthread_mutex_lock(&link_lock);
int slot = 0;
for (int i = 0; i < CARRIER_SLOTS; i++) {
if (strcmp(carrier_denied[i].path, path) == 0) { slot = i; break; }
if (carrier_denied[i].at < carrier_denied[slot].at) slot = i;
}
snprintf(carrier_denied[slot].path, sizeof(carrier_denied[slot].path), "%s", path);
carrier_denied[slot].at = now_ns();
pthread_mutex_unlock(&link_lock);
}
static int denied_table(const char *path) {
if (strncmp(path, "/proc/net/", 10) == 0) {
for (size_t i = 0; i < sizeof(tables) / sizeof(tables[0]); i++) {
if (strcmp(path + 10, tables[i]) == 0) return tables[i];
for (int i = 0; i < CARRIER_TABLE; i++) {
if (strcmp(path + 10, net_tables[i]) == 0) return i;
}
return NULL;
return -1;
}
size_t len = strlen(path);
if (strncmp(path, "/sys/class/net/", 15) == 0 && len > 8 && strcmp(path + len - 8, "/carrier") == 0) {
return "carrier";
return CARRIER_TABLE;
}
return NULL;
return -1;
}
static FILE *synthesize(const char *table) {
@@ -550,11 +586,16 @@ static FILE *open_stream(fopen_fn real, const char *path, const char *mode, cons
if (copy == NULL) close(status);
return copy;
}
FILE *f = real(path, mode);
if (f || path == NULL || mode == NULL || mode[0] != 'r') return f;
int table = path && mode && mode[0] == 'r' ? denied_table(path) : -1;
FILE *f;
if (table >= 0 && denied_recently(table, path) && (f = synthesize(net_tables[table])) != NULL) return f;
f = real(path, mode);
if (f || table < 0) return f;
int saved = errno;
const char *table = denied_table(path);
if (table && (f = synthesize(table)) != NULL) return f;
if ((f = synthesize(net_tables[table])) != NULL) {
if (saved == EACCES) remember_denial(table, path);
return f;
}
errno = saved;
return NULL;
}