Releases: Mahdi-mortazavi/relay
Release list
Relay 2.7.1
یک باگ که بهعنوان مشکل فیلترشکن گزارش شد، و فیلترشکن اصلاً مقصرش نبود.
پیام «اجازه میدهید؟» حالا به شما میرسد
گزارش این بود: وقتی روی گوشی VPN روشن است و از کامپیوتر Connect میزنید، پیام تأیید
هیچوقت نمیآید — ولی اگر VPN را خاموش کنید میآید. روی گوشی بازتولید شد و معلوم شد
دو مشکل جدا پشت آن پنهان بوده.
پیام تأیید فقط داخل صفحهی خود برنامه بود. یعنی فقط به کسی میرسید که همان لحظه
به گوشی نگاه میکرد — و این دقیقاً برعکس حالت عادی است: شما Connect را روی لپتاپ
میزنید، چون آنجا هستید، در حالی که گوشی روی میز افتاده. اندازهگیری شد: با Relay در
پسزمینه، درخواست بعد از بیست ثانیه منقضی میشد بدون اینکه اصلاً چیزی نشان داده شود —
نه دیالوگ، نه نوتیفیکیشن، نه صدا.
حالا این سؤال در نوار نوتیفیکیشن هم پرسیده میشود، با دکمههای اجازه بده و
رد کن، تا بدون باز کردن برنامه بتوانید جواب بدهید.
و یک پیامِ ازدسترفته، بهعنوان «رد کردم» ثبت میشد. رد کردن وقتی کسی جواب نمیدهد
عمدی است و تغییر نکرده — گوشیای که در جیب است باید بسته بماند. ولی ثبتکردنش اشتباه
بود: هیچکس تصمیمی نگرفته بود، و با این حال هر تلاش بعدیِ آن کامپیوتر در چند میلیثانیه
رد میشد بدون اینکه از کسی پرسیده شود. تنها پیامی که از دست رفته بود، تنها پیامی بود که
اصلاً قرار بود بیاید.
تنها راه خروج، ریاستارتکردن اشتراکگذاری بود — و قطع/وصل کردن VPN اتفاقاً همین کار را
میکند. تمام ارتباط این باگ با فیلترشکن همین بود.
جواب خودِ شما همچنان به خاطر سپرده میشود. سکوت دیگر نه.
ویندوز خودش بهروز میشود. روی اندروید arm64-v8a را بگیرید، مگر اینکه بگوید برنامه
سازگار نیست که در آن صورت universal.
Relay 2.7.0
Four defects on the path every byte takes, found by reading it end to end and
then measuring it — plus benchmarks that now run on every change, so the next
regression here is visible instead of silent.
Your downloads no longer die after five minutes
Relay set a timer when a connection opened and called it an idle timeout. It
wasn't one: it fired five minutes later no matter how busy the connection was.
Large downloads, video calls, SSH sessions and anything long-lived all broke at
the same mark — which looks exactly like a flaky network, and was reported as
one.
The timer now moves with your traffic, and it belongs to the connection as a
whole rather than to each direction. That second part matters: a download sends
almost nothing upstream from start to finish, so timing each direction
separately would have killed the very transfers the timer exists to protect.
Leak protection no longer breaks localhost
Blocking IPv6 blocked all of it, including the loopback address your own
machine uses to talk to itself. Windows tries ::1 before 127.0.0.1, so while
Relay was connected, anything using localhost — a development server, a
database client, an app talking to its own helper — failed or stalled first.
That was unrelated software breaking and Relay getting the blame, and it made
"turn leak protection off" look like the fix for a slow machine. Loopback is now
allowed. This cannot leak anything: loopback traffic never reaches a network
adapter, so there is nowhere for it to escape to.
The phone does less work for the same traffic
For every packet in either direction, Relay borrowed a buffer from the network
stack's memory pool and never returned it. The pool never got to reuse anything
and the garbage collector cleaned up the difference — continuously, on the phone,
on the one processor that has repeatedly turned out to be the limit.
That path is now 3.3× faster and allocates 57% less memory. A redundant
queue and a thread hand-off per packet went with it, which also restores the
buffering to the size it was meant to be — it had quietly been double, which is
what makes a tunnel feel sluggish while a transfer is running.
Being straight about this: it does not make downloads faster. Speed through
the tunnel is limited by encryption, and measured the same before and after.
What you get is lower latency while something is downloading, and a phone that
uses less battery and memory doing it.
Fewer resources held for nothing
Every DNS lookup opens a short-lived flow, and each one was holding two threads,
a socket and a 64 KB buffer for five minutes after it finished. A browsing
session piled up hundreds. Now released after a minute.
You are told when the tunnel is not protected
If Relay cannot install the filters, it still connects — a leak is bad, but an
app that refuses to work is worse. Until now the only record of that was a log
nobody reads, while the switch still said "on". You had been told you were
protected and would act on it. It now says so on screen instead.
Windows updates itself from here; nothing to do. On Android, take arm64-v8a
unless it says the app is not compatible, then take universal. Windows will
warn on first run because the installer is not code-signed yet — More info →
Run anyway.
Relay 2.6.1
2.6.0 connected Relay's updater for the first time. Testing it on real hardware
showed it still could not finish — for two reasons that never appear on a build
server, only on the kind of connection Relay is actually used on.
It waited to be disconnected before downloading
On the machine this was tested from, api.github.com answers in under a second
and GitHub's release CDN returns zero bytes in five minutes. That is not an
unlucky network. That is the network Relay exists for.
The updater waited for the tunnel to be down before downloading — which on that
connection means waiting for the exact moment the file cannot be reached. It
found the new version every single day and never got a byte of it.
Relay now downloads whenever it can, and waits only to install. Installing
is the part that would cost you your connection; downloading is not. The
download can use your phone's data — once per release, for an app that has no
other way to stay current, that is the better of the two mistakes.
It held the whole installer in memory, on a single deadline
Fifty megabytes buffered in RAM, with one ten-minute timeout covering the entire
transfer. A slow link simply ran out of time, and because this path is silent by
design, it gave up quietly until the next day. Every day.
It streams to disk now, hashing as it goes, under a name nothing will run until
the hash matches what the release published.
Nothing else changed
Everything from 2.6.0 and 2.5.0 is here: automatic updates on both platforms,
the DNS and IPv6 leak fixes, and the speed regression.
If you are on 2.6.0, this is the update that lets the next one arrive on its
own. Grab it below.
Relay 2.6.0
Relay could not update itself. That is fixed.
Updates now actually happen
Every piece of the update path existed already — check GitHub, compare versions,
download, verify the checksum, run the installer — and nothing called any of it.
On Windows that machinery had been sitting unused since 2.2, so if you installed
Relay once you stayed on that version forever while the README told you updates
were offered. On Android the in-app update banner has never appeared for anyone,
because the check behind it had no callers at all.
On Windows, Relay now updates itself. It looks a couple of minutes after
launch and then once a day, tells you what it found, and installs it the next
time your tunnel is down. It will not interrupt a connection: installing means
stopping Relay, and doing that mid-call would drop the call. It closes, updates,
and comes back on its own.
On Android, Relay tells you and offers it. It checks when you open the app
and also when sharing starts — so if you only ever use the Quick Settings tile or
the home screen widget, you still find out. Android does not allow a sideloaded
app to install anything silently, so the final tap is always yours. That is a
platform rule, not a choice we made.
Either way, nothing is installed that was not verified byte-for-byte against the
SHA256SUMS.txt published in that same release. A download that fails the check
is deleted, not kept. Relay carries your whole connection, so replacing itself
has to mean replacing itself with exactly what was published.
Upgrading to this one
This is the last release you have to install by hand on Windows. From here
Relay keeps itself current.
Download below, or from the buttons in the
README. Windows will warn on
first run because the installer is not code-signed yet — More info → Run
anyway. On Android, take arm64-v8a unless it says the app is not compatible,
in which case take universal.
Everything in 2.5.0 — the DNS and IPv6 leak fixes, and the speed regression —
is included.
Relay 2.5.0
Relay 2.5.0
Share your phone's internet with your PC. Tap Start Sharing on
the phone, click your phone in the list on the PC, tap Allow.
That is the whole setup.
Everything runs between your two devices: no account, no server, no
telemetry. The connection is an encrypted WireGuard tunnel, and
every application on the PC goes through it -- not only the browser.
Download
| Platform | File | Requirements |
|---|---|---|
| Windows | Relay-Setup-x64.exe |
Windows 10/11. Per-user install, no admin prompt. |
| Windows (32-bit) | Relay-Setup-x86.exe |
Only if you know you need it. |
| Android | Relay-android-arm64-v8a.apk |
Android 8.0+, 64-bit ARM — almost every phone since 2017. |
| Android (any device) | Relay-android-universal.apk |
Same app, every CPU type. Larger. Use this if the one above says "app not compatible". |
| Android (stores) | Relay-android.aab |
Not directly installable. |
Install
- Install both apps.
- On the phone, turn on the hotspot -- or put both devices on the
same Wi-Fi -- and tap Start Sharing. - On the PC, open Relay. Your phone is already in the list. Click it.
- Tap Allow on the phone.
No camera on the laptop? The two-digit code works on its own. Prefer
the QR? It is still there.
Windows SmartScreen warns on first run because the installer is not
code-signed yet: More info -> Run anyway. See docs/release.md.
If Android says "App not installed", that one message covers
several unrelated causes. The two most common: an older copy built
from source is still installed (uninstall it first - a different
signing key blocks the upgrade), or Play Protect blocked the
sideload (Install anyway in its dialog).
docs/install-troubleshooting.md
covers the rest, starting with how to see the platform's real error.
Verify your download
SHA256SUMS.txt is attached.
sha256sum -c SHA256SUMS.txtPrivacy and security
- Nothing leaves your two devices. No accounts, no servers, no
telemetry, no analytics. - The tunnel is WireGuard. Its keys are minted for each pairing and
destroyed when sharing stops. - Keys are never broadcast. The phone announces only enough to be
found; the keys travel over a short exchange that you approve on the
phone, with the requesting computer's address shown. - DNS and IPv6 cannot go around the tunnel. While connected, Relay
blocks name lookups to any resolver but the tunnel's, and refuses
IPv6 outright because the tunnel carries IPv4 only. Without this, a
laptop sharing a Wi-Fi with the phone leaks the local ISP. - Nothing outlives the app. No system-wide setting is changed, and
those filters are destroyed by Windows the moment Relay stops -- even
if it is killed -- so a crash cannot leave you unable to browse.
Anyone on your network can see the phone is sharing and can ask to
pair -- that request is what the Allow prompt is for, so do not
approve one you did not start.
SECURITY.md
has the full threat model.
What changed
The readable version, written for people rather than for git, is in
the changelog.
Every commit in this release
- Write down 2.5.0 and 2.2.0, and correct a comment that had gone stale (#97)
- Stop claiming leak protection that is not there (#96)
- Stop redrawing two surfaces once a second for a change neither shows (#95)
- Close the two ways traffic went around the tunnel (#94)
- Stop paying the batch cost for every single packet (#92)
- List what Relay actually does, and what is still missing (#91)