"me-web?" 0.11.0: the name of the block your address belongs to
Build / Desktop, server and tools (push) Successful in 1m4s
Release / Every platform, the server, the release (push) Successful in 21m49s

- The provider card now shows the address block your connection belongs to, as the RIPE Database names it, for
  example "MOBILE-USERS-BLOCK (IT)" on Iliad mobile or "FASTWEB-L3-PAT_NAT (IT)" on a Fastweb shared address. The
  path shows it under your provider too.
- No block is left out: the server keeps every block in the RIPE Database, small and unique ones included, and tells
  the app the block of the address it sees, never anyone else's. The app also carries about 430,000 of the larger
  blocks, for when the server can't be reached.
- Only each block's range, name and country are used, nothing about people. The data comes from the RIPE NCC's RIPE
  Database, used with the RIPE NCC's permission; it may lag behind the live database, and the "What this app
  contacts" sheet gives its date.
- The privacy page says that the server's answer now includes that block name; nothing new is stored or sent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-16 18:10:19 +02:00
1 parent 340b2678ef
commit aa031c6012
132 files changed
+825 -29

No files matched your search

+12 -4
View File
@@ -15,6 +15,8 @@ public class RunReport
public string PublicV6 { get; set; }
public AsnEntry NetworkV4 { get; set; }
public AsnEntry NetworkV6 { get; set; }
public RegistryBlock BlockV4 { get; set; }
public RegistryBlock BlockV6 { get; set; }
public ProviderProfile Provider { get; set; }
public RouterReport Router { get; set; }
public List<Hop> Hops { get; set; } = [];
@@ -94,8 +96,12 @@ public class CheckRunner(IPlatform platform, ServerProbe server, KnowledgeBase k
var addresses = Step(CheckId.Addresses, async () =>
{
run.PublicV4 = await v4;
run.PublicV6 = await v6;
var echo4 = await v4;
var echo6 = await v6;
run.PublicV4 = echo4?.Address;
run.PublicV6 = echo6?.Address;
run.BlockV4 = echo4?.Block is null ? null : new RegistryBlock { Name = echo4.Block, Country = echo4.BlockCountry };
run.BlockV6 = echo6?.Block is null ? null : new RegistryBlock { Name = echo6.Block, Country = echo6.BlockCountry };
await Task.WhenAll(connection, router);
run.OwnNetwork = Addresses.SameNetwork(await ServerProbe.ServerAddresses(ct), run.PublicV4, run.PublicV6);
Settle(Verdicts.Addresses(run.PublicV4, run.PublicV6, run.Local, run.Router));
@@ -107,8 +113,10 @@ public class CheckRunner(IPlatform platform, ServerProbe server, KnowledgeBase k
var table = knowledge.Asn;
run.NetworkV4 = table?.Find(Addresses.Parse(run.PublicV4));
run.NetworkV6 = table?.Find(Addresses.Parse(run.PublicV6));
run.BlockV4 ??= knowledge.Registry?.Find(Addresses.Parse(run.PublicV4));
run.BlockV6 ??= knowledge.Registry?.Find(Addresses.Parse(run.PublicV6));
run.Provider = knowledge.ProviderFor((run.NetworkV4 ?? run.NetworkV6)?.Number ?? 0);
Settle(Verdicts.Provider(knowledge, run.NetworkV4, run.NetworkV6, run.PublicV4 is not null || run.PublicV6 is not null, run.Local?.Active?.Kind == LinkKind.Mobile));
Settle(Verdicts.Provider(knowledge, run.NetworkV4, run.NetworkV6, run.BlockV4, run.BlockV6, run.PublicV4 is not null || run.PublicV6 is not null, run.Local?.Active?.Kind == LinkKind.Mobile));
});
var nat = Step(CheckId.Nat, async () =>
@@ -195,7 +203,7 @@ public class CheckRunner(IPlatform platform, ServerProbe server, KnowledgeBase k
PortLow = run.Stun?.Ports?.Pattern is PortPattern.InOrder or PortPattern.Block ? run.Stun.Ports.Low : 0,
PortHigh = run.Stun?.Ports?.Pattern is PortPattern.InOrder or PortPattern.Block ? run.Stun.Ports.High : 0,
});
Settle(Verdicts.Provider(knowledge, run.NetworkV4, run.NetworkV6, run.PublicV4 is not null || run.PublicV6 is not null, run.Local?.Active?.Kind == LinkKind.Mobile, run));
Settle(Verdicts.Provider(knowledge, run.NetworkV4, run.NetworkV6, run.BlockV4, run.BlockV6, run.PublicV4 is not null || run.PublicV6 is not null, run.Local?.Active?.Kind == LinkKind.Mobile, run));
Settle(Verdicts.History(run.History));
run.Uses = Uses.Decide(run);
});
+2 -3
View File
@@ -40,15 +40,14 @@ public class ServerProbe(HttpClient https, HttpClient plain)
return new OnlineReport { State = names.Result ? OnlineState.Offline : OnlineState.NoNames };
}
public async Task<string> Echo(bool v6, CancellationToken ct)
public async Task<ViewIp> Echo(bool v6, CancellationToken ct)
{
try
{
using var timeout = CancellationTokenSource.CreateLinkedTokenSource(ct);
timeout.CancelAfter(Patience);
var origin = v6 ? Endpoints.BaseV6 : Endpoints.BaseV4;
var answer = await https.GetFromJsonAsync(origin + Endpoints.Server.GET_Ip, MeWebJsonContext.Default.ViewIp, timeout.Token);
return answer?.Address;
return await https.GetFromJsonAsync(origin + Endpoints.Server.GET_Ip, MeWebJsonContext.Default.ViewIp, timeout.Token);
}
catch (Exception) when (!ct.IsCancellationRequested)
{
+6 -1
View File
@@ -97,7 +97,7 @@ public static class Verdicts
return finding;
}
public static Finding Provider(KnowledgeBase knowledge, AsnEntry v4, AsnEntry v6, bool anyAddress, bool mobile, RunReport run = null)
public static Finding Provider(KnowledgeBase knowledge, AsnEntry v4, AsnEntry v6, RegistryBlock blockV4, RegistryBlock blockV6, bool anyAddress, bool mobile, RunReport run = null)
{
var finding = new Finding { Id = CheckId.Provider };
if (!anyAddress)
@@ -127,6 +127,9 @@ public static class Verdicts
finding.Args = [profile?.Name ?? Display(main)];
finding.With("FactNetwork", Describe(main));
if (v6 is not null && v4 is not null && v6.Number != v4.Number) finding.With("FactNetworkIpv6", Describe(v6));
var block = v4 is not null ? blockV4 : blockV6;
finding.With("FactBlock", Describe(block));
if (v4 is not null && blockV6 is not null && blockV6.Name != blockV4?.Name) finding.With("FactBlockIpv6", Describe(blockV6));
var upstreams = knowledge.NetworkFor(main.Number)?.Upstreams ?? [];
if (upstreams.Count > 0) finding.With("FactUpstreams", string.Join("\n", upstreams.Select(u => $"{knowledge.NameOf(u) ?? "AS" + u} (AS{u})")));
if (hand is null && observed is null) return finding;
@@ -483,6 +486,8 @@ public static class Verdicts
static string Describe(AsnEntry entry) => $"{Display(entry)} (AS{entry.Number})";
static string Describe(RegistryBlock block) => block is null ? null : string.IsNullOrEmpty(block.Country) ? block.Name : $"{block.Name} ({block.Country})";
static string Join(string make, string label)
{
if (string.IsNullOrWhiteSpace(make)) return label;