Reese Norris 69627b0f89 fix: race-safe FacilityType, Docker Go 1.25, geo cell tests
Make Session.FacilityType atomic.Int32 so concurrent handleATCPosition
writes and HTTP online-users reads no longer race under -race. Bump the
Dockerfile build image to golang:1.25 to match go.mod. Add CellIndex/
CellCover unit tests so internal/geo meets the 98% coverage floor.
2026-07-19 15:43:47 -04:00
2025-05-25 11:56:38 -07:00
2025-05-24 08:47:26 -07:00

openfsd

license

openfsd is an open-source multiplayer flight simulation server implementing the modern VATSIM FSD protocol. It connects pilots and air traffic controllers in a shared virtual environment.

About

Flight Sim Daemon (colloquially known as FSD) is the software/protocol responsible for connecting home flight simulator clients to a single, shared multiplayer world on hobbyist networks such as VATSIM and IVAO. FSD was originally written in the late 90's by Marty Bochane for SATCO, later to be forked and taken closed-source by VATSIM in 2001. As of May 2025, FSD is still used to facilitate over 140,000 active members connecting their flight simulators to the network.

Features

  • Multiplayer flight simulation with VATSIM protocol compatibility
  • Web-based management for users, settings, and connections
  • SQLite for persistent storage (single file; easy backups)
  • Single binary — FSD and web share one process and one database; enable services with CLI flags

Package layout

cmd/openfsd/          # Binary entrypoint (FSD + web; image CMD is /openfsd)
pkg/protocol/         # Pure wire format (parse/marshal; no I/O)
pkg/fsdclient/        # Mock/real FSD client for e2e and tools
internal/server/      # TCP accept, login, handlers, service HTTP
internal/session/     # Per-connection state + outbound send worker
internal/postoffice/  # Callsign registry + geospatial index
internal/geo/         # Pure haversine / bounding box
internal/auth/        # JWT + VATSIM client auth
internal/metar/       # METAR worker pool (injectable HTTP)
internal/db/          # Shared repositories + migrations
internal/web/         # Gin MPA + /api/v1

Build and run

go build -o openfsd ./cmd/openfsd

./openfsd              # both FSD and web (default)
./openfsd -fsd         # FSD only (:6809 + service HTTP :13618)
./openfsd -web         # web only (:8000)
Flag Effect
(none) Both services
-fsd FSD only
-web Web only
-fsd -web Both (same as default)

Environment

Variable Default Notes
DATABASE_SOURCE_NAME :memory: SQLite path or :memory:; shared by both services
DATABASE_DRIVER sqlite Compatibility only; must be sqlite or unset (Postgres removed)
DATABASE_AUTO_MIGRATE true FSD applies migrations on startup
FSD_LISTEN_ADDRS :6809 FSD TCP listen address(es)
SERVICE_HTTP_LISTEN_ADDR :13618 Internal FSD admin HTTP
FSD_HTTP_SERVICE_ADDRESS http://127.0.0.1:13618 Web → FSD service HTTP
LISTEN_ADDR :8000 Web UI + /api/v1
LOG_DEBUG (unset) Set true for debug logging

Colocated mode (default) uses the shared DB and in-process service HTTP. For -web against a remote FSD, set FSD_HTTP_SERVICE_ADDRESS.

Quick start (Docker)

Preferred for operators. See the Deployment Wiki (source: wiki/).

Images: ghcr.io/renorris/openfsd (:latest, :dev, sha-*) published by CI on every push to main and dev.

Upgrading from PostgreSQL? openfsd is SQLite-only. Use openfsd-migrate-to-sqlite and follow Migrating from PostgreSQL.

git clone https://github.com/renorris/openfsd.git
cd openfsd
docker compose up -d          # pull/build single image; both services
# or: docker compose up -d --build
  1. Open http://localhost:8000
  2. Log in with the default admin credentials (printed in container logs on first startup)
  3. Configure Server — see the Configuration wiki
  4. Connect a client — Client Connection Wiki

Service selection

# Both (default CMD)
docker run --rm -p 6809:6809 -p 8000:8000 ghcr.io/renorris/openfsd:latest

# FSD only
docker run --rm -p 6809:6809 ghcr.io/renorris/openfsd:latest /openfsd -fsd

# Web only (remote FSD)
docker run --rm -p 8000:8000 \
  -e FSD_HTTP_SERVICE_ADDRESS=http://fsd-host:13618 \
  ghcr.io/renorris/openfsd:latest /openfsd -web

Local smoke

docker compose up -d --build
curl -fsS -o /dev/null -w "%{http_code}\n" http://localhost:8000/login
nc -z localhost 6809 && echo "fsd:6809 open"
docker compose down

Tests

go test -race ./...
bash scripts/check-coverage.sh 80    # overall ≥80%; pure-pkg floors (see AGENTS.md)
go test -bench=. -benchmem ./internal/postoffice/ ./pkg/protocol/
go test -tags=stress -count=1 -timeout=120s ./internal/server/ -run TestStress -v

E2E: internal/server/e2e_test.go via pkg/fsdclient + StartTestServer. Stress is optional (CI schedule / workflow_dispatch).

API

/api/v1 covers auth, users, config, and FSD connections. See internal/web.

Protocol docs

Unofficial reverse-engineered FSD protocol docs live under docs/:

pip install mkdocs
mkdocs serve
Description
No description provided
Readme MIT 4.5 MiB
Languages
Go 71%
JavaScript 12.1%
HTML 10%
CSS 6.6%
Batchfile 0.3%