# noiseonwires/yac-ws-bridge architecture

> Architecture diagram of the GitHub repository noiseonwires/yac-ws-bridge, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-03). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/noiseonwires/yac-ws-bridge
- Repository: https://github.com/noiseonwires/yac-ws-bridge

## Overview

#### Purpose and topology
Bridge to Freedom is a multiplexed raw-TCP tunnel using Yandex Cloud (YC) API Gateway WebSockets. A server-side Go adapter reaches a target TCP service; a client-side Go helper or MAUI app exposes a local TCP listener. YC’s serverless function performs authenticated peer discovery, while direct YC WebSocket-management gRPC carries most data.

#### Executable entry points
- Go adapter: `adapter-and-helper/cmd/adapter/main.go`
- Go helper: `adapter-and-helper/cmd/helper/main.go`
- YC Node.js Cloud Function handler: `bridge-cloud/index.js`
- Cross-platform GUI client: `maui-client/MauiProgram.cs`, `maui-client/MainPage.xaml.cs`
- Linux MAUI head: `maui-client-linux/Program.cs`

#### Go tunnel core
Both Go binaries share internal packages for configuration, framing, stream lifecycle, upstream WebSocket connectivity, and YC send APIs:
- Configuration and runtime options: `adapter-and-helper/internal/config/config.go`
- Tunnel frame/wire protocol: `adapter-and-helper/internal/protocol/protocol.go`
- Multiplexed stream management, FIN/open/data processing, ordering, and write coalescing: `adapter-and-helper/internal/streams/streams.go`
- Persistent authenticated upstream WebSocket connection and reconnect/ping behavior: `adapter-and-helper/internal/upstream/upstream.go`

The helper accepts local TCP connections, allocates stream IDs, and emits OPEN/DATA/FIN frames. The adapter receives frames, opens a TCP connection to its configured target, and returns response/data frames. Multiple streams share each peer’s upstream WebSocket session.

#### YC transport boundary
`adapter-and-helper/internal/wsapi/wsapi.go` abstracts outbound delivery. `adapter-and-helper/internal/wsapi/grpc.go` uses YC’s WebSocket-management gRPC `wsSend` path for direct peer delivery; `adapter-and-helper/internal/wsapi/rest.go` provides the REST-side integration surface. In normal mode, Cloud Function traffic is control-plane discovery only. In helper relay mode, helper-to-adapter frames instead traverse its upstream WebSocket and the function relays them.

YC limits shape transport behavior: periodic pings preserve WebSocket sessions; frame/message limits motivate coalescing and stream framing; reconnect loops handle Gateway connection churn.

#### Discovery and recovery control plane
The Cloud Function at `bridge-cloud/index.js` authenticates adapter and helper HELLO handshakes, associates their Gateway connection IDs, and notifies peers when both are present. `bridge-cloud/spec.yaml` binds the adapter/helper WebSocket routes to that function through YC API Gateway.

The adapter additionally exposes an authenticated HTTP recovery endpoint containing current adapter/helper connection IDs. The function calls it through `HTTP_URL` after cold starts or instance changes, allowing discovery state restoration. Endpoint URL, shared token, and route names must align across deployed function, Gateway, and clients.

#### Native and GUI client boundary
The MAUI client is a functional alternative to the Go helper: `maui-client/Services/TunnelService.cs` owns local tunnel behavior and `maui-client/Services/Protocol.cs` implements compatible framing. Platform hosts include Android foreground-service support in `maui-client/Platforms/Android/TunnelForegroundService.cs` and iOS background-audio support in `maui-client/Platforms/iOS/SilentAudioService.cs`.

#### Deployment/runtime configuration
Go 1.21+ builds the adapter/helper module in `adapter-and-helper/go.mod`; Node.js 18 is the documented YC function runtime, with dependencies in `bridge-cloud/package.json`; MAUI/.NET builds native client variants. Deployment-critical example configuration lives in `adapter-and-helper/adapter.config.yaml` and `adapter-and-helper/helper.config.yaml`. These configure Gateway URLs, shared authentication, TCP listen/target addresses, reconnect/ping policy, coalescing, and relay behavior.

Main entry points: [`adapter-and-helper/cmd/adapter/main.go`](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/cmd/adapter/main.go) (Go adapter), [`maui-client/Services/TunnelService.cs`](https://github.com/noiseonwires/yac-ws-bridge/blob/main/maui-client/Services/TunnelService.cs) (MAUI tunnel client), [`adapter-and-helper/internal/streams/streams.go`](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/streams/streams.go) (Multiplexed streams), [`bridge-cloud/spec.yaml`](https://github.com/noiseonwires/yac-ws-bridge/blob/main/bridge-cloud/spec.yaml) (YC API Gateway WebSockets)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_go["Go tunnel runtime"]
  node_adapter["Go adapter<br/>entry point<br/>[main.go]"]
  node_helper["Go helper<br/>entry point<br/>[main.go]"]
  node_config["Runtime configuration<br/>Go package<br/>[config.go]"]
  node_protocol["Tunnel framing<br/>Go package<br/>[protocol.go]"]
  node_streams["Multiplexed streams<br/>Go package<br/>[streams.go]"]
  node_upstream["Upstream WebSocket<br/>Go package<br/>[upstream.go]"]
  node_wsapi["Outbound delivery API<br/>Go package<br/>[wsapi.go]"]
  node_grpc["YC gRPC sender<br/>Go package<br/>[grpc.go]"]
  node_rest["REST integration<br/>Go package<br/>[rest.go]"]
  node_recovery["Adapter recovery endpoint<br/>authenticated HTTP endpoint<br/>[main.go]"]
end

subgraph group_yc["Yandex Cloud control and transport"]
  node_gateway{{"YC API Gateway WebSockets<br/>managed gateway<br/>[spec.yaml]"}}
  node_function{{"Discovery function<br/>Node.js cloud function<br/>[index.js]"}}
end

subgraph group_native["Native client"]
  node_maui["MAUI tunnel client<br/>GUI client<br/>[TunnelService.cs]"]
  node_maui_protocol["MAUI framing<br/>C&#35; protocol<br/>[Protocol.cs]"]
  node_android_service["Android foreground service<br/>platform host"]
  node_ios_service["iOS background audio<br/>platform host"]
end

node_target["Target TCP service<br/>external service"]

node_helper -->|"loads"| node_config
node_adapter -->|"loads"| node_config
node_helper -->|"allocates local streams"| node_streams
node_adapter -->|"processes streams"| node_streams
node_streams -->|"encodes frames"| node_protocol
node_adapter -->|"opens TCP connections"| node_target
node_helper -->|"connects"| node_upstream
node_adapter -->|"connects"| node_upstream
node_upstream -->|"persistent WebSocket session"| node_gateway
node_streams -->|"delivers frames"| node_wsapi
node_wsapi -->|"normal direct mode"| node_grpc
node_wsapi -.->|"REST surface"| node_rest
node_grpc -->|"wsSend to peer"| node_gateway
node_gateway -->|"routes HELLO handshakes"| node_function
node_function -.->|"restores discovery state"| node_recovery
node_maui -->|"uses"| node_maui_protocol
node_maui -->|"WebSocket tunnel session"| node_gateway
node_maui -.->|"compatible peer tunnel"| node_adapter
node_android_service -->|"keeps tunnel active"| node_maui
node_ios_service -->|"keeps tunnel active"| node_maui

click node_adapter "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/cmd/adapter/main.go"
click node_helper "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/cmd/helper/main.go"
click node_config "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/config/config.go"
click node_protocol "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/protocol/protocol.go"
click node_streams "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/streams/streams.go"
click node_upstream "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/upstream/upstream.go"
click node_wsapi "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/wsapi/wsapi.go"
click node_grpc "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/wsapi/grpc.go"
click node_rest "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/wsapi/rest.go"
click node_gateway "https://github.com/noiseonwires/yac-ws-bridge/blob/main/bridge-cloud/spec.yaml"
click node_function "https://github.com/noiseonwires/yac-ws-bridge/blob/main/bridge-cloud/index.js"
click node_recovery "https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/cmd/adapter/main.go"
click node_maui "https://github.com/noiseonwires/yac-ws-bridge/blob/main/maui-client/Services/TunnelService.cs"
click node_maui_protocol "https://github.com/noiseonwires/yac-ws-bridge/blob/main/maui-client/Services/Protocol.cs"
click node_android_service "https://github.com/noiseonwires/yac-ws-bridge/blob/main/maui-client/Platforms/Android/TunnelForegroundService.cs"
click node_ios_service "https://github.com/noiseonwires/yac-ws-bridge/blob/main/maui-client/Platforms/iOS/SilentAudioService.cs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_adapter,node_helper,node_config,node_protocol,node_streams,node_upstream,node_wsapi,node_grpc,node_rest,node_recovery toneBlue
class node_gateway,node_function toneAmber
class node_maui,node_maui_protocol,node_android_service,node_ios_service toneMint
class node_target toneNeutral
```

## Components

### Go tunnel runtime

- [Go adapter](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/cmd/adapter/main.go): entry point · Connects tunnel streams to the configured target TCP service. · `adapter-and-helper/cmd/adapter/main.go`
- [Go helper](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/cmd/helper/main.go): entry point · Exposes a local TCP listener for tunnel clients. · `adapter-and-helper/cmd/helper/main.go`
- [Runtime configuration](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/config/config.go): Go package · `adapter-and-helper/internal/config/config.go`
- [Tunnel framing](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/protocol/protocol.go): Go package · Defines OPEN, DATA, and FIN wire frames. · `adapter-and-helper/internal/protocol/protocol.go`
- [Multiplexed streams](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/streams/streams.go): Go package · Handles stream lifecycle, ordering, and coalesced writes. · `adapter-and-helper/internal/streams/streams.go`
- [Upstream WebSocket](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/upstream/upstream.go): Go package · Maintains authenticated sessions with reconnect and ping behavior. · `adapter-and-helper/internal/upstream/upstream.go`
- [Outbound delivery API](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/wsapi/wsapi.go): Go package · `adapter-and-helper/internal/wsapi/wsapi.go`
- [YC gRPC sender](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/wsapi/grpc.go): Go package · Directly sends frames to a peer Gateway connection. · `adapter-and-helper/internal/wsapi/grpc.go`
- [REST integration](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/internal/wsapi/rest.go): Go package · `adapter-and-helper/internal/wsapi/rest.go`
- [Adapter recovery endpoint](https://github.com/noiseonwires/yac-ws-bridge/blob/main/adapter-and-helper/cmd/adapter/main.go): authenticated HTTP endpoint · Returns current adapter and helper connection IDs for state restoration. · `adapter-and-helper/cmd/adapter/main.go`

### Yandex Cloud control and transport

- [YC API Gateway WebSockets](https://github.com/noiseonwires/yac-ws-bridge/blob/main/bridge-cloud/spec.yaml): managed gateway · Hosts peer WebSocket connections and routes handshakes. · `bridge-cloud/spec.yaml`
- [Discovery function](https://github.com/noiseonwires/yac-ws-bridge/blob/main/bridge-cloud/index.js): Node.js cloud function · Authenticates HELLO peers, records connection IDs, and notifies matched peers. · `bridge-cloud/index.js`

### Native client

- [MAUI tunnel client](https://github.com/noiseonwires/yac-ws-bridge/blob/main/maui-client/Services/TunnelService.cs): GUI client · Alternative local TCP tunnel client compatible with the Go adapter. · `maui-client/Services/TunnelService.cs`
- [MAUI framing](https://github.com/noiseonwires/yac-ws-bridge/blob/main/maui-client/Services/Protocol.cs): C# protocol · `maui-client/Services/Protocol.cs`
- [Android foreground service](https://github.com/noiseonwires/yac-ws-bridge/blob/main/maui-client/Platforms/Android/TunnelForegroundService.cs): platform host · `maui-client/Platforms/Android/TunnelForegroundService.cs`
- [iOS background audio](https://github.com/noiseonwires/yac-ws-bridge/blob/main/maui-client/Platforms/iOS/SilentAudioService.cs): platform host · `maui-client/Platforms/iOS/SilentAudioService.cs`

### Other components

- **Target TCP service**: external service

## Connections

- Go helper → Runtime configuration: loads
- Go adapter → Runtime configuration: loads
- Go helper → Multiplexed streams: allocates local streams
- Go adapter → Multiplexed streams: processes streams
- Multiplexed streams → Tunnel framing: encodes frames
- Go adapter → Target TCP service: opens TCP connections
- Go helper → Upstream WebSocket: connects
- Go adapter → Upstream WebSocket: connects
- Upstream WebSocket → YC API Gateway WebSockets: persistent WebSocket session
- Multiplexed streams → Outbound delivery API: delivers frames
- Outbound delivery API → YC gRPC sender: normal direct mode
- Outbound delivery API → REST integration: REST surface
- YC gRPC sender → YC API Gateway WebSockets: wsSend to peer
- YC API Gateway WebSockets → Discovery function: routes HELLO handshakes
- Discovery function → Adapter recovery endpoint: restores discovery state
- MAUI tunnel client → MAUI framing: uses
- MAUI tunnel client → YC API Gateway WebSockets: WebSocket tunnel session
- MAUI tunnel client → Go adapter: compatible peer tunnel
- Android foreground service → MAUI tunnel client: keeps tunnel active
- iOS background audio → MAUI tunnel client: keeps tunnel active
