Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a7fbc4c52 | ||
|
|
6623c6f9f1 |
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>0.5.0</Version>
|
<Version>0.5.2</Version>
|
||||||
<Product>me-web?</Product>
|
<Product>me-web?</Product>
|
||||||
<Company>Arasaka di Hvozdikov Yevheniy</Company>
|
<Company>Arasaka di Hvozdikov Yevheniy</Company>
|
||||||
<Copyright>© 2026 Arasaka di Hvozdikov Yevheniy</Copyright>
|
<Copyright>© 2026 Arasaka di Hvozdikov Yevheniy</Copyright>
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ public partial class MainViewModel : ObservableObject
|
|||||||
readonly Leftovers leftovers;
|
readonly Leftovers leftovers;
|
||||||
readonly Submissions submissions;
|
readonly Submissions submissions;
|
||||||
RunReport lastRun;
|
RunReport lastRun;
|
||||||
|
int checks;
|
||||||
|
bool sent;
|
||||||
bool revealing;
|
bool revealing;
|
||||||
bool instant;
|
bool instant;
|
||||||
|
|
||||||
@@ -198,15 +200,20 @@ public partial class MainViewModel : ObservableObject
|
|||||||
HistoryCleared = false;
|
HistoryCleared = false;
|
||||||
AskReach = false;
|
AskReach = false;
|
||||||
OfferShare = false;
|
OfferShare = false;
|
||||||
|
sent = false;
|
||||||
ShareResult = null;
|
ShareResult = null;
|
||||||
|
var generation = ++checks;
|
||||||
foreach (var card in Cards) card.Finding = card.Id == CheckId.Reach ? null : Finding.Running(card.Id);
|
foreach (var card in Cards) card.Finding = card.Id == CheckId.Reach ? null : Finding.Running(card.Id);
|
||||||
Uses.Clear();
|
Uses.Clear();
|
||||||
ResetPath(platform.Device);
|
ResetPath(platform.Device);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lastRun = await runner.Run((finding, run) => Dispatcher.UIThread.Post(() => Apply(finding, run)), ct);
|
lastRun = await runner.Run((finding, run) => Dispatcher.UIThread.Post(() =>
|
||||||
|
{
|
||||||
|
if (generation == checks) Apply(finding, run);
|
||||||
|
}), ct);
|
||||||
ShowUses(lastRun);
|
ShowUses(lastRun);
|
||||||
OfferShare = true;
|
OfferShare = lastRun.Stun?.Ports?.LifetimeDone != false;
|
||||||
OnPropertyChanged(nameof(CanOpenPorts));
|
OnPropertyChanged(nameof(CanOpenPorts));
|
||||||
AskReach = lastRun.PublicV4 is not null || lastRun.PublicV6 is not null;
|
AskReach = lastRun.PublicV4 is not null || lastRun.PublicV6 is not null;
|
||||||
if (!AskReach) SettleReach(null);
|
if (!AskReach) SettleReach(null);
|
||||||
@@ -296,6 +303,7 @@ public partial class MainViewModel : ObservableObject
|
|||||||
Shared.Add(new SubmissionViewModel(submission, Unshare));
|
Shared.Add(new SubmissionViewModel(submission, Unshare));
|
||||||
OnPropertyChanged(nameof(ShowShared));
|
OnPropertyChanged(nameof(ShowShared));
|
||||||
ShareResult = Localizer.Instance.Format("ShareSent", shared.Id, Texts.Date(shared.KeepUntil));
|
ShareResult = Localizer.Instance.Format("ShareSent", shared.Id, Texts.Date(shared.KeepUntil));
|
||||||
|
sent = true;
|
||||||
OfferShare = false;
|
OfferShare = false;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -474,6 +482,7 @@ public partial class MainViewModel : ObservableObject
|
|||||||
var ports = run.Stun?.Ports;
|
var ports = run.Stun?.Ports;
|
||||||
if (exit is not null && run.Nat == NatKind.Shared && run.PublicV4 is not null && ports?.Pattern is PortPattern.InOrder or PortPattern.Block)
|
if (exit is not null && run.Nat == NatKind.Shared && run.PublicV4 is not null && ports?.Pattern is PortPattern.InOrder or PortPattern.Block)
|
||||||
exit.Details = Lines(Address($"{run.PublicV4}:{ports.Low}–{ports.High}"));
|
exit.Details = Lines(Address($"{run.PublicV4}:{ports.Low}–{ports.High}"));
|
||||||
|
if (ports?.LifetimeDone == true && run == lastRun && !IsChecking && !sent) OfferShare = true;
|
||||||
break;
|
break;
|
||||||
case CheckId.Addresses:
|
case CheckId.Addresses:
|
||||||
var internet = Node(NodeRole.Internet);
|
var internet = Node(NodeRole.Internet);
|
||||||
|
|||||||
@@ -95,18 +95,21 @@ public partial class ProbeService(IOptionsMonitor<ProbeOptions> options, ILogger
|
|||||||
await tracing.WaitAsync(ct);
|
await tracing.WaitAsync(ct);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var info = new ProcessStartInfo("tracepath") { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false };
|
var info = new ProcessStartInfo("stdbuf") { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false };
|
||||||
foreach (var argument in new[] { "-n", "-m", "16", target.ToString() }) info.ArgumentList.Add(argument);
|
foreach (var argument in new[] { "-oL", "tracepath", "-n", "-m", "16", target.ToString() }) info.ArgumentList.Add(argument);
|
||||||
using var process = Process.Start(info);
|
using var process = Process.Start(info);
|
||||||
if (process is null) return hops;
|
if (process is null) return hops;
|
||||||
using var timeout = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
using var timeout = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
||||||
timeout.CancelAfter(TimeSpan.FromSeconds(25));
|
timeout.CancelAfter(TimeSpan.FromSeconds(25));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var silent = 0;
|
||||||
while (await process.StandardOutput.ReadLineAsync(timeout.Token) is { } line)
|
while (await process.StandardOutput.ReadLineAsync(timeout.Token) is { } line)
|
||||||
{
|
{
|
||||||
|
if (SilentLine().IsMatch(line) && ++silent >= 3) break;
|
||||||
var match = HopLine().Match(line);
|
var match = HopLine().Match(line);
|
||||||
if (!match.Success || !IPAddress.TryParse(match.Groups[2].Value, out var address)) continue;
|
if (!match.Success || !IPAddress.TryParse(match.Groups[2].Value, out var address)) continue;
|
||||||
|
silent = 0;
|
||||||
var distance = int.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
|
var distance = int.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
|
||||||
if (hops.Any(h => h.Distance == distance)) continue;
|
if (hops.Any(h => h.Distance == distance)) continue;
|
||||||
if (!IsPublic(address) || Refuse(address) is not null) continue;
|
if (!IsPublic(address) || Refuse(address) is not null) continue;
|
||||||
@@ -148,6 +151,9 @@ public partial class ProbeService(IOptionsMonitor<ProbeOptions> options, ILogger
|
|||||||
[GeneratedRegex(@"^\s*(\d+):\s+([0-9a-fA-F.:]+)\s+([\d.]+)ms")]
|
[GeneratedRegex(@"^\s*(\d+):\s+([0-9a-fA-F.:]+)\s+([\d.]+)ms")]
|
||||||
internal static partial Regex HopLine();
|
internal static partial Regex HopLine();
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^\s*\d+:\s+no reply")]
|
||||||
|
internal static partial Regex SilentLine();
|
||||||
|
|
||||||
async Task<ProbeOutcome> Knock(Ticket ticket, int port, CancellationToken ct)
|
async Task<ProbeOutcome> Knock(Ticket ticket, int port, CancellationToken ct)
|
||||||
{
|
{
|
||||||
await outbound.WaitAsync(ct);
|
await outbound.WaitAsync(ct);
|
||||||
|
|||||||
Reference in new issue
Block a user