# How OpenFlux Integrates with iOS: Network Extension Architecture and Swift Implementation

> Discover how OpenFlux integrates with iOS using its PacketTunnelProvider, VPNController, and SwiftUI architecture for per-app SOCKS5 proxy and system-wide VPN with a Go tun2socks stack.

- Repository: [p1neappleXpress/OpenFlux](https://github.com/p1neappleXpress/OpenFlux)
- Tags: architecture
- Published: 2026-09-14

---

**OpenFlux integrates with iOS through a three-component architecture consisting of a PacketTunnelProvider system extension, a VPNController management layer, and a SwiftUI interface, enabling both per-app SOCKS5 proxy and system-wide VPN functionality via a Go-based tun2socks stack.**

The p1neappleXpress/OpenFlux repository implements a native iOS client that bridges Apple's Network Extension framework with a Go networking core. This integration allows users to route device traffic through remote exit nodes using either a local SOCKS5 proxy for specific applications or a full-device VPN tunnel that captures all network traffic.

## Three-Layer Architecture

OpenFlux integrates with iOS through tightly-coupled Swift components that handle system-level packet tunneling, VPN profile management, and user interaction.

### PacketTunnelProvider: The System Extension Core

The **`PacketTunnelProvider`** class in [`ios-app/OpenFluxTunnel/PacketTunnelProvider.swift`](https://github.com/p1neappleXpress/OpenFlux/blob/main/ios-app/OpenFluxTunnel/PacketTunnelProvider.swift) implements the `NEPacketTunnelProvider` API to create a virtual TAP interface. This system extension initializes the packet tunnel, configures network settings, and bridges raw IP packets to the Go **tun2socks** stack through C function calls.

Key responsibilities include:
- Building `NEPacketTunnelNetworkSettings` with virtual address `10.10.10.2` and DNS `198.18.0.1`
- Defining `bypassRoutes` to exclude Yandex backend ranges and public DoT DNS servers from the tunnel
- Exporting C functions `OpenFluxStartPacketTunnel`, `OpenFluxTunWritePacket`, and `OpenFluxTunReadPacket` to interface with the Go binary

### VPNController: Profile and Lifecycle Management

Located in [`ios-app/OpenFlux/VPNController.swift`](https://github.com/p1neappleXpress/OpenFlux/blob/main/ios-app/OpenFlux/VPNController.swift), the **`VPNController`** wraps `NETunnelProviderManager` to manage the system-wide VPN profile. It handles the creation, configuration, and persistence of the packet tunnel, passing transport credentials—such as Yandex Docs URLs or MAX tokens—via the `providerConfiguration` dictionary.

When users enable system-wide routing, this controller calls `startVPNTunnel()` to install the VPN profile that captures all device traffic at the operating system level.

### SwiftUI Interface Layer

The user-facing components in [`ios-app/OpenFlux/ContentView.swift`](https://github.com/p1neappleXpress/OpenFlux/blob/main/ios-app/OpenFlux/ContentView.swift) provide controls for transport selection, credential entry, and tunnel management. The interface supports two operational modes:
- **SOCKS5 Proxy Mode**: Routes specific application traffic through a local port (default `10808`)
- **VPN Mode**: Routes all device traffic through the virtual interface managed by `PacketTunnelProvider`

## Packet Flow and Data Routing

OpenFlux integrates with iOS network stacks through a bidirectional packet pumping mechanism that operates asynchronously.

### Tunnel Initialization Sequence

When a user starts the tunnel via `TunnelController.start()` or enables the VPN through `VPNController.start()`, the system triggers `PacketTunnelProvider.startTunnel`. This method:

1. Instantiates `NEPacketTunnelNetworkSettings` with the virtual IPv4 configuration
2. Sets default routes while excluding Yandex infrastructure to prevent routing loops
3. Invokes `OpenFluxStartPacketTunnel` to initialize the Go-side networking stack

### Bidirectional Packet Processing

Two concurrent loops handle packet movement between the iOS system and the Go stack:

**Read Loop (Device → Go Stack):**

```swift
packetFlow.readPackets { [weak self] packets, _ in
    for p in packets {
        p.withUnsafeBytes { raw in
            if let base = raw.bindMemory(to: CChar.self).baseAddress {
                OpenFluxTunWritePacket(UnsafeMutablePointer(mutating: base),
                                       Int32(p.count))
            }
        }
    }
    self?.startReadLoop()
}

```

**Write Loop (Go Stack → Device):**

```swift
while true {
    let n = OpenFluxTunReadPacket(buf, maxLen)
    if n <= 0 { break }
    let data = Data(bytes: buf, count: Int(n))
    self.packetFlow.writePackets([data],
                                 withProtocols: [NSNumber(value: AF_INET)])
}

```

## Implementation Examples

### Starting the SOCKS5 Proxy

To initialize the local proxy without system-wide VPN:

```swift
tunnel.start(
    transport: transport,
    url: docURL,
    maxToken: maxToken,
    maxUid: maxUid,
    port: Int(socksPort) ?? 10808
)

```

### Configuring System-Wide VPN

To route all device traffic through the exit node:

```swift
vpn.start(
    transport: transport.rawValue,
    url: docURL,
    maxToken: maxToken,
    maxUid: maxUid
)

```

### Network Settings Configuration

The virtual interface setup excludes specific routes to prevent traffic loops:

```swift
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "127.0.0.1")
let ipv4 = NEIPv4Settings(addresses: ["10.10.10.2"],
                         subnetMasks: ["255.255.255.0"])
ipv4.includedRoutes = [NEIPv4Route.default()]
ipv4.excludedRoutes = Self.bypassRoutes
settings.ipv4Settings = ipv4
settings.dnsSettings = NEDNSSettings(servers: ["198.18.0.1"])

```

## Required Capabilities and Entitlements

OpenFlux integrates with iOS system APIs through specific entitlements defined in `OpenFlux.entitlements` and `OpenFluxTunnel.entitlements`:

- **App Groups**: Enables data sharing between the main app and the packet tunnel extension
- **Network Extension**: Grants permission to create VPN configurations and packet tunnel providers
- **Background Modes**: Supports continuous packet processing while the app operates in the background

## Summary

- **OpenFlux integrates with iOS** through a `PacketTunnelProvider` system extension that implements `NEPacketTunnelProvider` to create virtual network interfaces.
- The **`VPNController`** manages the `NETunnelProviderManager` lifecycle, handling system-wide VPN profiles and credential configuration.
- **Bidirectional packet pumping** occurs through C bridge functions `OpenFluxTunWritePacket` and `OpenFluxTunReadPacket`, connecting Swift code with the Go tun2socks implementation.
- The architecture supports **dual operation modes**: a local SOCKS5 proxy for selective traffic routing and a full-device VPN capturing all network traffic with DNS-over-TCP resolution.

## Frequently Asked Questions

### How does OpenFlux handle packet routing at the system level?

OpenFlux creates a virtual TAP interface using `NEPacketTunnelNetworkSettings` with IP address `10.10.10.2`. The `PacketTunnelProvider` class reads raw IP packets from `packetFlow.readPackets` and forwards them to the Go stack via `OpenFluxTunWritePacket`, while continuously polling `OpenFluxTunReadPacket` to write processed packets back to the system.

### What transport protocols does the iOS client support?

According to the source code in [`VPNController.swift`](https://github.com/p1neappleXpress/OpenFlux/blob/main/VPNController.swift) and [`ContentView.swift`](https://github.com/p1neappleXpress/OpenFlux/blob/main/ContentView.swift), the iOS client supports **Yandex** and **MAX** transports. Users provide either a Yandex Docs URL or MAX token/UID credentials, which the app passes through `providerConfiguration` to the packet tunnel extension.

### Can OpenFlux run without enabling the system VPN?

Yes. The `TunnelController` (referenced in [`ios-app/OpenFlux/TunnelController.swift`](https://github.com/p1neappleXpress/OpenFlux/blob/main/ios-app/OpenFlux/TunnelController.swift)) allows users to start a local SOCKS5 proxy on a configurable port without installing the system VPN profile. This mode routes traffic only from applications explicitly configured to use the local proxy address, while the VPN mode routes all device traffic through `PacketTunnelProvider`.

### How does the app prevent routing loops for its own backend traffic?

The `PacketTunnelProvider` defines `bypassRoutes` that exclude Yandex backend IP ranges and public DNS-over-TLS servers from the tunnel's included routes. This exclusion prevents the tunnel from attempting to route its own control traffic back through the encrypted tunnel, which would cause connectivity failures.