Names and Numbers
The desktop client is peer-to-peer, and it still carries a short list of fixed names: the servers it contacts, the trackers it writes into new torrents, the product's own names, and the way it introduces itself to trackers and peers. This page lists each one, the file it's set in, and what uses it.
- Renaming a fork? Start with the product's names: two files hold them, and the list under them names every file that spells one out by hand.
- Checking what the client contacts? Read the servers. Today the update check and the Connection tab are the two in use, since the engine creates no libtorrent session yet.
The product's names
| Name | Value | Set in | Used for |
|---|---|---|---|
brandName | ftorrent | productName in desktop/src-tauri/tauri.conf.json | what people read: the window title, the tray, the menus, the installer, the Start menu shortcut, the Windows ProgIDs, the install folder, the default downloads folder |
brandStem | ftorrent | name in desktop/src-tauri/Cargo.toml | what files carry: the executable, the engine ftorrent-engine, the settings file ftorrent.toml, the lock file, the log folder, the .ftorrent extension, the ftorrent: scheme, the published installers |
| identifier | com.ftorrent.ftorrent | identifier in desktop/src-tauri/tauri.conf.json | the data folder, the Mac bundle, the Windows AppUserModelID, the Flatpak |
urlHome | ftorrent.com | bundle.homepage in desktop/src-tauri/tauri.conf.json | the About and Settings links, the update check's addresses |
urlHelp | docs.ftorrent.com/help | desktop/src/brand.js, from urlHome | the Help menu |
The page reads the two source files when Vite builds it, in desktop/src/brand.js, and every other page file imports the names from there. The Rust core reads them from its package info, which Tauri fills from the same two files, and the engine receives brandName in the first message the app sends it. The build scripts read the two files themselves: desktop/scripts.js for the published names, desktop/dmg.js for the .app and the dmg, desktop/win-setup/win-setup.js, which compiles both names into the setup program, and desktop/win-setup/registry.js for the uninstall list.
- The two names are the same string here, and the code keeps them apart because a fork's may differ: a product called Candy Crush may be
candycrushorcandy-crushinside, and nothing derives one from the other. - The identifier changes with the two names, and only before a fork's first release: it names the data folder and the Mac bundle, so changing it later leaves the old ones behind on every machine.
docs.ftorrent.com/helpis a fixed route that forwards to whichever page help lives on, set indocs/docs/help/index.md, so a copy that never updates still reaches current help.
These files spell a name out by hand, because nothing can read the sources there:
desktop/src-tauri/tauri.conf.json:publisher,copyright, and the signing identityftorrent. Inbundle.resources, the engine's folderftorrent-engine, on both sides of the entry, and the Start tile'sftorrent.VisualElementsManifest.xml, which Windows requires to match the executable's name, so rename the file indesktop/src-tauri/icons/tile/with it. The Linux desktop templateftorrent.desktop.hbscan keep its name, as long as the entries and the file agree.desktop/src-tauri/Cargo.toml: the libraryftorrent_libunder[lib]. Leave Tauri'smainBinaryNameunset, so the crate's name stays the executable's.desktop/src-tauri/macos/Info.plist: the type namesftorrent Fileandftorrent Link, the type identifiercom.ftorrent.file, the extensionftorrent, the schemeftorrent, and the sentence macOS shows when the client first reaches the local network.desktop/engine/ftorrent-engine.spec:ftorrent-engine, in the twoname=lines and theoutputpath. Rename the file with it, and theenginescript indesktop/package.jsonthat names it, andnameindesktop/engine/pyproject.toml.engine.rsfinds the engine by the crate's name and-engine, so a mismatch shows only when the engine fails to start.desktop/engine/engine.py: the client codeFF, infingerprint(). Pick two letters that are in none of the tables at the end of this page.desktop/icon-studio/Update-Icons.ps1:ftorrent.ico, the studio's own copy of the application icon.desktop/linux/build.js,inside-check.sh,inside-check-rpm.sh,inside-tauri.py, andinside-flatpak.py: the image tags, the package name patterns, the engine's path, and the Flatpak identifiercom.ftorrent.ftorrent.desktop/release/anddesktop/linux/release/: the sidecars of ftorrent's published files, named for them. A fork's firstpnpm hashwrites its own beside them, and the old ones can go.
Servers
The update check
https://ftorrent.com/ftorrent.app.zip.jsonon a Mac,https://ftorrent.com/ftorrent.exe.jsonon Windows: the sidecar, with the newest version's number, date, size, and hash.- The same addresses without
.json: the update itself, downloaded only when the user clicks to install it. - Built in
desktop/src/update.jsanddesktop/src/stores/update.jsfromurlHome. - Asked when the user presses the Settings page's button. With
automatic = trueunder[update]inftorrent.toml, the default, also asked at the first startup and then at a random moment one to two days after each answer, which the client looks for at startup and every hour. - Asked only by an installed copy on a Mac or Windows. A portable copy never asks, and neither do the Linux packages, which the package manager updates.
- Sent over HTTPS, checked against Mozilla's roots compiled into the client, following no redirect, with these headers and no others:
User-Agent: ureq/3.4.2
Accept: */*
Accept-Encoding: gzipThe Connection tab
https://ip4.ftorrent.com/andhttps://ip6.ftorrent.com/: each answers the address the request arrived from. The first name has only an IPv4 record and the second only an IPv6 record, so each request travels over one family. Sent over HTTPS, checked against Mozilla's roots compiled into the client, following no redirect, with the same three headers as the update check.stun.ftorrent.com:3478andstun.cloudflare.com:3478: a STUN binding request over UDP, over each family, to both at once from one local port, picked at random from 49152 to 65535 for each run. The request is STUN's twenty-byte header and nothing else, sent again half a second, a second and a half, and three and a half seconds after the first until an answer comes.ipv4only.arpa,ip4.ftorrent.com, andip6.ftorrent.com: resolved through the system's resolver. The first has only IPv4 addresses by definition, RFC 7050, so an IPv6 answer reveals DNS64; the other two show the single-family records the reflector checks rest on.- The router, at the gateway address the default route names, on UDP port 5351, two requests at once. NAT-PMP's public address request, two bytes, sent again a quarter second after the first and then at doubling intervals until the router answers, whose answer is the router's external IPv4 address and the seconds since its mapping table started. And PCP's ANNOUNCE, a 24-byte header carrying this machine's own local address and asking for nothing, sent again at STUN's intervals, whose answer is a result code and the same epoch, or, from a router that speaks only NAT-PMP, that protocol's answer that the version is unsupported. A router that refuses the port speaks neither.
239.255.255.250:1900, the SSDP multicast address, over UDP: UPnP's search for an Internet Gateway Device, a few lines of text. A router answers from its own address with the location of its device description, which the client fetches over plain HTTP on the local network, then asks that description's WAN connection service by SOAP for GetExternalIPAddress and for GetGenericPortMappingEntry by index until the router says the list has ended, and, where the description offers IPv6 firewall control, GetFirewallStatus.- Built in
desktop/src/connection.js, with ftorrent's names fromurlHome. - Asked only when the user presses Check on the Connection tab, each given four seconds to answer.
The Windows installer
https://developer.microsoft.com/microsoft-edge/webview2/, set indesktop/win-setup/setup.c: opened in the user's browser, with a dialog saying so, only on a Windows machine without the WebView2 runtime. The setup program fetches nothing itself.
The engine's table
The engine holds three lists in one table, centralized_servers in desktop/engine/engine.py, and hands them to libtorrent's settings when it creates its session. Each list puts ftorrent's own server first. The engine creates no session yet, so none of these is contacted today.
STUN. WebTorrent uses STUN to learn the public address its WebRTC connections appear from. libtorrent takes one server, in webtorrent_stun_server, and the engine gives it the first. The engine doesn't fall back to the other two yet.
| Server | Run by |
|---|---|
stun.ftorrent.com:3478 | ftorrent |
stun.cloudflare.com:3478 | Cloudflare |
stun.l.google.com:19302 | Google; libtorrent's own default |
DHT bootstrap. A DHT routing table that starts empty learns its first nodes from these. libtorrent takes all three, in dht_bootstrap_nodes.
| Node | Run by |
|---|---|
dht.ftorrent.com:51420 | ftorrent |
dht.libtorrent.org:25401 | libtorrent's author; libtorrent's own default |
dht.transmissionbt.com:6881 | the Transmission project |
Trackers. These are written into a torrent ftorrent creates. The client creates no torrents yet.
| Tracker | Run by |
|---|---|
udp://open.ftorrent.com:443/announce | ftorrent |
https://open.ftorrent.com/announce | ftorrent |
wss://open.ftorrent.com | ftorrent |
wss://tracker.webtorrent.dev | the WebTorrent project |
wss://tracker.openwebtorrent.com | OpenWebTorrent |
udp://tracker.opentrackr.org:1337/announce | not publicly named |
The system's own
- Names resolve through the system's DNS. The client sets no resolver.
- The web view is the platform's: WebKit on macOS and Linux, WebView2 on Windows.
- The Connection tab runs the system's own tools through
process_outputindesktop/src-tauri/src/process.rs, for what the system's list of interfaces leaves out: on macOS/sbin/ifconfig -L,/sbin/route -n get defaultand its-inet6form, and/usr/sbin/networksetup -listallhardwareports, and on Linuxip -o addressandip route show defaultin each family. Each reads the machine and contacts no one. On Windows,GetAdaptersAddressesanswers all of it, and no tool runs. - The web view reaches no network itself. The content security policy in
desktop/src-tauri/tauri.conf.jsonadmits only the app's own files and its calls into Rust, so every request goes throughnet_getindesktop/src-tauri/src/net.rs. The fonts ship inside the app, indesktop/public/fonts.
Addresses
192.0.2.1and2001:db8::1, indesktop/src/connection.js: addresses set aside for documentation, by RFC 5737 and RFC 3849, which name no one. The Connection tab hands each tonet_localindesktop/src-tauri/src/net.rs, which connects a UDP socket to it at port 9. Connecting sends nothing; the system picks a route, and the client reads the source address the system would send from.
No other address is written in the client, apart from the unspecified 0.0.0.0 and :: that net_local and net_stun bind their sockets to, and localhost:7100 in desktop/src-tauri/tauri.conf.json, where a development build finds Vite.
What the client calls itself
- The peer id begins
-FF0100-, fromfingerprint()indesktop/engine/engine.py.FFis ftorrent's two-letter client code, the digits are the version, one per part, and random bytes for the session follow. Clients that read only the peer id look the code up in a table, and the tables are listed at the end of this page. - The client name is
ftorrent/0.1.0 libtorrent/2.1.1.0, fromclient_name()indesktop/engine/engine.py, built frombrandName, the app's version, and libtorrent's. Trackers and web seeds see it as theUser-Agent, in libtorrent'suser_agentsetting, and peers see it in the extension handshake, inhandshake_client_version. - The DHT version tag,
v, isLTand libtorrent's version, which libtorrent writes into every DHT message itself, from no setting. - The update check sends
ureq/3.4.2, the HTTP library's own user agent. Nothing in the request names the copy, its version, or the user.
The engine reports its table, its client name, and its peer id prefix in its ready line, so the app and anyone running the engine by hand see the same values this page lists.
The tables of client codes, where FF isn't listed yet:
- BEP 20, the convention, with the original list
- the community wiki's peer_id section
- libtorrent's table, which qBittorrent and Deluge inherit
- Transmission's table
- bittorrent-peerid, the WebTorrent clients' table