← Back to Blog
Engineering Notes Performance

ProxiFyre 2.0.1: Deferred Process Lookup and Catch-All SOCKS5 Routing

Packet cards wait for an identity tag before continuing through a common proxy route.

In recent months, I’ve continued to encounter cases where traditional VPN connections are becoming less reliable or outright blocked. For users who rely on remote access to home infrastructure or private networks, especially from regions with increasing traffic inspection or censorship, this creates a tangible threat to continuity. My own setup, a home server behind a WireGuard endpoint, has on more than one occasion suffered from unexplained throughput drops and UDP packet loss, particularly on mobile connections.

The pattern is familiar: your tunnel connects, then stalls, or appears fine but performs suspiciously poorly. In those cases, I found an SSH-based TCP tunnel through a local SOCKS5 listener a useful fallback. But even SOCKS5 isn’t a silver bullet unless you have a mechanism for redirecting arbitrary application traffic through it. Many applications lack built-in proxy support, and system-wide proxying is cumbersome, particularly on Windows.

This is where ProxiFyre comes in: a lightweight traffic redirection tool that enables per-application SOCKS5 routing for TCP and UDP connections, all without modifying application binaries or OS-wide proxy settings. With version 2.0.1, we’ve made some important architectural improvements and introduced system-wide redirection via wildcard configuration.


🆕 Wildcard Redirection: SOCKS5 for Everything

Until now, users had to specify appNames for each process whose traffic should be proxied. This offered precision, but at the cost of complexity. Version 2.0.1 introduces a catch-all rule: an empty string ("") in appNames matches outgoing IPv4 traffic from applications covered by the configured protocols. DNS over UDP port 53 remains direct, and this version does not proxy IPv6 destinations.

For example, this rule sends matched IPv4 TCP/UDP traffic to a SOCKS5 endpoint. Replace the example endpoint and credentials with your own:

{
  "logLevel": "Error",
  "proxies": [
    {
      "appNames": [""],
      "socks5ProxyEndpoint": "proxy.example.org:1080",
      "username": "user1",
      "password": "pass1",
      "supportedProtocols": ["TCP", "UDP"]
    }
  ]
}

⚠️ Note: DNS queries over UDP port 53 bypass this proxy. Also check the application’s IPv6 traffic and any other traffic outside the selected protocols before treating the setup as a privacy boundary.

A catch-all rule also needs a path for the proxy carrier itself. With a local SSH or SOCKS server, the carrier’s own outgoing connection can be captured again and loop back into the proxy. ProxiFyre 2.0.1 did not yet have process exclusions; use a targeted application rule for that setup. Later versions added excludes for the carrier process. A working proxy backend alone does not make the catch-all equivalent to a leak-proof VPN.


⚙️ Addressing Performance Under Load

Users reported latency under load, including a high-ping report in issue #62. We traced one source of delay to how ProxiFyre resolved process context for packets. The issue report describes a symptom; it does not by itself establish a deadlock or quantify throughput.

Before 2.0.1, determining the originating process could run synchronously in the packet-processing path. Under load, that could:

  • Block the fast-path packet processing thread
  • Increase the risk of stalls or races during callbacks
  • Reduce throughput as packet queues back up

The 2.0.1 release notes describe the deferred resolution change and its intended effect on the critical packet path.

✅ Deferred Process Context Resolution

In v2.0.1, the context lookup logic is now asynchronous and deferred. This means:

  • The core packet handler no longer waits for the process name to be resolved
  • Packets are enqueued and processed in background threads
  • The critical packet path spends less time waiting for process lookup

Here’s a simplified flow comparison:

VersionContext LookupEffect on packet path
≤ 2.0.0Synchronous (inline)Process lookup could delay processing
2.0.1Deferred executionLookup moved out of the critical path

The change addresses a concrete source of delay, although its end-to-end benefit depends on the workload and proxy.


🔄 Windows Packet Filter Compatibility

ProxiFyre relies on the Windows Packet Filter driver to intercept and reinject network packets. Install a driver compatible with the ProxiFyre build you are using. For a current installation, follow the maintained installer requirements, which specify a compatible 3.x driver with version 3.6.1.0 or later.

The driver supplies the packet-filter API used by the application:

  • queued_multi_interface_packet_filter builds on the Windows Packet Filter library to process packets across interfaces. Keep the application, library and installed driver versions compatible.

You can download the latest version of the driver from github.com.

If the driver is missing or incompatible, install the architecture-matched package specified by the release before troubleshooting routing behavior.


🧱 Internals: Better Structure, Better Debugging

As part of the 2.0.1 effort, the project structure also received a long-overdue cleanup:

  • Replaced inline logic with the new queued_multi_interface_packet_filter, enabling consistent packet filtering across multiple interfaces without duplicating logic.
  • Refreshed netlib headers with upstream fixes and enhancements.
  • On the C# side, logging is now fully structured. Log levels include:
    • Error, Warning, Info, Debug, and All
  • Removed obsolete legacy fragments that had accumulated over earlier experimental builds.

These changes reduce noise, improve build consistency, and make debugging misconfigurations much more straightforward.


🧪 Real-World Scenarios

The per-app rules remain particularly useful with a local SSH dynamic tunnel, because they leave the SSH carrier outside the proxy. For example, to send a browser and RDP client through that tunnel:

{
  "logLevel": "Info",
  "proxies": [
    {
      "appNames": ["chrome", "mstsc"],
      "socks5ProxyEndpoint": "127.0.0.1:8080",
      "supportedProtocols": ["TCP"]
    }
  ]
}

This pairs with PuTTY dynamic forwarding or ssh -D. The example selects TCP only: UDP, DNS resolution and IPv6 need separate checks, and a local SSH tunnel must be kept running.


🔧 Under the Hood

To recap, ProxiFyre is composed of:

  • ndisapi.lib – A static library built on Windows Packet Filter, which provides raw Ethernet packet interception and injection at the NDIS layer.
  • socksify – A C++/CLI .NET class library that performs protocol translation and flow handling for SOCKS5.
  • ProxiFyre – A lightweight .NET console wrapper for parsing configs and coordinating per-process routing.

The application uses an existing kernel driver rather than requiring a new one in the ProxiFyre project. Performance depends on the driver, proxy and traffic mix; this release note is not a benchmark.


📦 Getting the Release

The version discussed here is available on GitHub:

👉 ProxiFyre v2.0.1 – Release Page

The tag provides source and binaries for this historical release. Check its dependencies before running it; for a current installation, use the maintained release and driver instructions above.


In an era where access to information and infrastructure can no longer be taken for granted, simple and reliable tools like ProxiFyre serve a vital role. v2.0.1 is a step toward broader usability and improved performance, as well as a foundation for even more flexible tunneling in the future.


P.S. At the time of this release, I wanted to highlight a limitation of ordinary browser SOCKS5 settings: they did not provide native QUIC (HTTP/3) proxying. ProxiFyre could redirect selected application UDP flows without relying on those settings.

Selected non-DNS IPv4 UDP flows, including QUIC, can be proxied only when the SOCKS5 backend supports UDP ASSOCIATE and its UDP relay is reachable. The ssh -D and PuTTY dynamic-forwarding example above carries TCP only, so it cannot carry QUIC. DNS over UDP port 53 remains direct in ProxiFyre 2.0.1.

Whether this helps against a particular DPI system depends on the SOCKS5 transport and what the network observes. A plain SOCKS5 connection is not encrypted by SOCKS5 itself; the proxy endpoint and traffic pattern may still be recognizable.