<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>DMSG on Skycoin Blog</title><link>https://blog.theskywirenetwork.net/tags/dmsg/</link><description>Recent content in DMSG on Skycoin Blog</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 10 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.theskywirenetwork.net/tags/dmsg/index.xml" rel="self" type="application/rss+xml"/><item><title>DMSG-First, HTTP Fallback: The Default Is Now the Encrypted Overlay</title><link>https://blog.theskywirenetwork.net/posts/skywire-dmsg-first-http-fallback/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.theskywirenetwork.net/posts/skywire-dmsg-first-http-fallback/</guid><description>&lt;h3 id="the-default-changed-quietly"&gt;The Default Changed, Quietly&lt;/h3&gt;
&lt;p&gt;For most of Skywire&amp;rsquo;s history, the visor talked to the network&amp;rsquo;s infrastructure services — Transport Discovery, Service Discovery, Address Resolver, Route Finder, Uptime Tracker, and the config bootstrapper — over plain HTTP. You could configure DMSG-HTTP transport instead, but it was opt-in, and relatively few visors used it. The majority of traffic between visors and services flowed over HTTPS on the public internet.&lt;/p&gt;
&lt;p&gt;With the dual-endpoint &lt;code&gt;services-config.json&lt;/code&gt; that landed over the past two weeks, &lt;strong&gt;that default has flipped&lt;/strong&gt;. Every visor is now configured with both DMSG and HTTP endpoints for every service, and the visor tries DMSG first. HTTP requests happen only when DMSG is unavailable — as a fallback, not as the primary path. For operators who don&amp;rsquo;t change anything, the practical effect is that service requests stop leaving the encrypted overlay entirely.&lt;/p&gt;</description></item><item><title>DMSG Server Mesh and DMSG Server-Hosted Route Setup</title><link>https://blog.theskywirenetwork.net/posts/dmsg-server-mesh-and-route-setup/</link><pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.theskywirenetwork.net/posts/dmsg-server-mesh-and-route-setup/</guid><description>&lt;h3 id="two-architectural-changes-that-belong-together"&gt;Two Architectural Changes That Belong Together&lt;/h3&gt;
&lt;p&gt;Over the past two weeks, two changes landed in the DMSG layer that together offer significant flexibility in how Skywire deployments can be structured: &lt;strong&gt;DMSG servers can now peer with each other&lt;/strong&gt; to form a mesh, and &lt;strong&gt;a DMSG server can optionally run a route setup-node as an integrated service&lt;/strong&gt; on one of its DMSG ports.&lt;/p&gt;
&lt;p&gt;The first change is deployed and in active use. The second is deployed in the DMSG server binary behind an &lt;code&gt;enable_route_setup&lt;/code&gt; config flag, but visors on the public Skywire network are not currently configured to use DMSG servers as their route setup nodes. The existing standalone setup-node continues to serve public network traffic, and it has been doing so reliably — at the time of writing, the production setup-node has been online for 53,080 seconds (about 14.7 hours) without restarts or ephemeral port exhaustion, following the cumulative effect of the port leak fixes from &lt;a href="https://blog.theskywirenetwork.net/posts/the-great-dmsg-bug-hunt/"&gt;the great DMSG bug hunt&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>The Great DMSG Bug Hunt</title><link>https://blog.theskywirenetwork.net/posts/the-great-dmsg-bug-hunt/</link><pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.theskywirenetwork.net/posts/the-great-dmsg-bug-hunt/</guid><description>&lt;h3 id="how-we-discovered-and-fixed-thousands-of-leaked-goroutines-per-day"&gt;How We Discovered and Fixed Thousands of Leaked Goroutines Per Day&lt;/h3&gt;
&lt;p&gt;For most of its existence, DMSG &amp;ldquo;worked.&amp;rdquo; Clients connected, streams opened, frames flowed, servers relayed traffic. But under real production load over long periods, something was quietly going wrong — goroutines accumulated, ephemeral ports stayed reserved past their natural lifetime, memory grew, and servers eventually needed to be restarted to clear the cruft.&lt;/p&gt;
&lt;p&gt;Over the past three weeks, a systematic audit found and fixed &lt;strong&gt;thirty-two distinct bugs&lt;/strong&gt; in the DMSG codebase, ranging from tiny off-by-one errors to fundamental resource management failures that were leaking tens of thousands of goroutines per day on production servers. This is a narrative account of that hunt: what was broken, how it was found, and what the pattern of the bugs reveals about the codebase.&lt;/p&gt;</description></item><item><title>Skywire Development Update — April 7, 2026</title><link>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-07/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-07/</guid><description>&lt;h3 id="dmsg-two-more-server-goroutine-leaks"&gt;DMSG: Two More Server Goroutine Leaks&lt;/h3&gt;
&lt;p&gt;The DMSG server goroutine hunt continued — &lt;strong&gt;two more leaks found and fixed&lt;/strong&gt;, both involving the server&amp;rsquo;s forwarding logic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bridged streams idle timeout&lt;/strong&gt; (#372) — bridged streams (bidirectional copy between two clients through the server) were blocking forever on &lt;code&gt;io.Copy Read&lt;/code&gt; when one side disconnected without cleanly closing the connection. This caused goroutines to accumulate — &lt;strong&gt;observed as 55,000+ stuck goroutines in production&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The fix added an &lt;code&gt;idleTimeoutConn&lt;/code&gt; wrapper that resets a per-operation deadline on each Read/Write. If no data flows for 5 minutes, the deadline fires, &lt;code&gt;io.Copy&lt;/code&gt; returns an error, &lt;code&gt;CopyReadWriteCloser&lt;/code&gt; closes both streams, and the goroutine exits. The timeout resets on each successful read/write, so active streams are unaffected — only truly idle/dead streams are cleaned up.&lt;/p&gt;</description></item><item><title>Skywire Development Update — April 6, 2026</title><link>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-06/</link><pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-06/</guid><description>&lt;h3 id="skywire-setup-node-goroutine-leak-fix"&gt;Skywire: Setup-Node Goroutine Leak Fix&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Route setup-node goroutine leak&lt;/strong&gt; (#2280) — a serious production issue: the setup-node was accumulating 500+ leaked goroutines within minutes of restart.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Root cause&lt;/strong&gt; — &lt;code&gt;MakeMap&lt;/code&gt; used an &lt;strong&gt;unbuffered&lt;/strong&gt; results channel, causing goroutines to block forever on send when the reader stopped after the first error. Combined with no dial timeout, unreachable visors caused indefinite blocking in &lt;code&gt;DialStream.readResponse&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt; — added buffered channels and explicit dial/handler timeouts so stuck dials can&amp;rsquo;t accumulate. The setup-node now cleanly errors out and cleans up goroutines when it can&amp;rsquo;t reach a visor.&lt;/p&gt;</description></item><item><title>Skywire Development Update — April 4, 2026</title><link>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-04/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-04/</guid><description>&lt;h3 id="skywire-regional-saturation-scaling-for-rewards"&gt;Skywire: Regional Saturation Scaling for Rewards&lt;/h3&gt;
&lt;p&gt;A significant economic change to the reward system: &lt;strong&gt;regional saturation scaling&lt;/strong&gt; (#2278).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt; — the presence pool distributes rewards equally across all uptime-eligible visors. If a single country has 1,000 visors, it receives 1,000 shares. This creates an incentive to flood a single region with cheap VPS instances to maximize reward extraction, which distorts the geographic distribution of the network.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt; — apply diminishing returns to the presence pool based on unique IP addresses per country. Countries with more unique IPs still receive a larger total allocation, but each additional IP contributes less. Default is square-root scaling (configurable via &lt;code&gt;--sat-exp&lt;/code&gt; flag). A country with 100 IPs gets &lt;code&gt;sqrt(100) = 10&lt;/code&gt; units of weight per IP instead of 1 per IP; a country with 4 IPs gets &lt;code&gt;sqrt(4) = 2&lt;/code&gt; units per IP — so the 100-IP country gets 5× the weight of the 4-IP country, not 25×.&lt;/p&gt;</description></item><item><title>Skywire Development Update — April 3, 2026</title><link>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-03/</link><pubDate>Fri, 03 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-03/</guid><description>&lt;h3 id="skywire-skydeploy-override"&gt;Skywire: SKYDEPLOY Override&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;New environment variable&lt;/strong&gt; (#2276) — &lt;code&gt;SKYDEPLOY=/path/to/config.json&lt;/code&gt; overrides the embedded &lt;code&gt;services-config.json&lt;/code&gt; deployment configuration. This supports:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Private networks&lt;/strong&gt; — point Skywire at a custom deployment without rebuilding&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Corporate deployments&lt;/strong&gt; — run a private Skywire network with your own TPD, DMSG, Address Resolver, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing&lt;/strong&gt; — quickly switch between test and production deployments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The embedded config is still used as the default, so nothing changes for users on the public network. But operators running private deployments no longer need to patch and rebuild Skywire to change the discovery URLs.&lt;/p&gt;</description></item><item><title>Skywire Development Update — April 2, 2026</title><link>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-02/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.theskywirenetwork.net/posts/dev-update-2026-04-02/</guid><description>&lt;h3 id="skywire-dmsg-grpc-listener"&gt;Skywire: DMSG gRPC Listener&lt;/h3&gt;
&lt;p&gt;A new remote-management capability: &lt;strong&gt;DMSG gRPC listener for remote gotop and stats&lt;/strong&gt; (#2271).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Design&lt;/strong&gt; — a new &lt;code&gt;DmsgGRPCPort&lt;/code&gt; (49) serves gRPC over DMSG alongside the existing local CLI gRPC. The &lt;code&gt;DialDmsgRPC&lt;/code&gt; function was updated to dial the new port instead of &lt;code&gt;DmsgHypervisorPort&lt;/code&gt;. This enables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remote &lt;code&gt;gotop&lt;/code&gt; (system activity monitor) over DMSG&lt;/li&gt;
&lt;li&gt;Stats streaming from any visor to any other visor&lt;/li&gt;
&lt;li&gt;Ping and latency measurements between visors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both visors need the update — the local visor dials the new port and the remote visor listens on it. Once deployed, operators can run &lt;code&gt;skywire cli visor ping&lt;/code&gt; or stream system activity from any visor they have authorized access to, all over the encrypted DMSG overlay.&lt;/p&gt;</description></item></channel></rss>