Ping Warden

Technical Documentation

How Ping Warden works: AWDL events, the privileged helper, XPC, latency measurement, automation, security, diagnostics, and signed updates.

On this page
  1. 1. Overview
  2. 2. Why Not Just Run sudo ifconfig awdl0 down?
  3. 3. High-Level Architecture
  4. 4. Key Components
  5. 5. Monitoring Model and Timing Behavior
  6. 6. State Model
  7. 7. Setup and Approval Flow
  8. 8. Settings and UI Areas
  9. 9. Menu Bar and App Menu Integration
  10. 10. Sparkle Update System
  11. 11. Security Model
  12. 12. Diagnostics and Health Checks
  13. 13. Performance Characteristics
  14. 14. Build and Development
  15. 15. Release and Distribution
  16. 16. Limitations and Tradeoffs
  17. 17. Operational Best Practices
  18. 18. Related Documentation
  19. 19. Credits
  20. 20. License and Pricing

This document is the detailed technical and operational guide for Ping Warden.

Read it on the Ping Warden website. The documentation hub includes setup, pricing, privacy, troubleshooting, and release notes.

For quick setup, see Quick Start. For issue recovery, see Troubleshooting.

1. Overview

Ping Warden is a macOS utility that keeps AWDL from reactivating during latency-sensitive work.

AWDL (Apple Wireless Direct Link) is used by Apple ecosystem features such as AirDrop, AirPlay, and Handoff. On some networks and workflows, AWDL interface transitions can correlate with sudden latency jumps. Ping Warden provides a controlled, user-friendly way to keep AWDL suppressed when desired, while retaining the ability to restore the interface when protection stops.

Primary goals:

2. Why Not Just Run sudo ifconfig awdl0 down?

A one-time shell command might seem like a simple fix, but it doesn't actually solve the problem.

The core issue: macOS can bring AWDL back up automatically. A polling script reacts only after the interface is active, so it cannot prevent the transition itself.

Why Ping Warden is different: Instead of polling, the helper daemon waits for kernel route and interface events through an AF_ROUTE socket. When macOS raises AWDL while protection is active, the helper requests that the interface return down and records an intervention attempt. The count does not establish that the request succeeded or that a particular latency spike was avoided.

Additional benefits:

3. High-Level Architecture

Ping Warden uses a split architecture:

Communication boundary:

Registration model:

4. Key Components

4.1 Main App

Important files:

Responsibilities:

4.2 Helper Daemon

Important files:

Responsibilities:

5. Monitoring Model and Timing Behavior

Core behavior:

When monitoring is active and the system raises AWDL:

  1. Kernel route event arrives.
  2. Helper identifies awdl0 state change (RTM_IFINFO).
  3. The intervention-attempt counter increments.
  4. The helper attempts to clear IFF_UP on awdl0 via SIOCSIFFLAGS and reads back the resulting flag state.

This is event-driven, not a delayed periodic shell loop.

6. State Model

Two state concepts are used:

This separation allows robust behavior during reconnects, restarts, or temporary failures.

7. Setup and Approval Flow

Initial setup sequence:

  1. Launch app.
  2. App checks helper registration status via SMAppService.
  3. If unregistered or approval required, user is guided to System Settings.
  4. App polls registration status and proceeds once enabled.
  5. XPC connection is activated.

The design avoids recurring password prompts after the one-time approval step.

The welcome appears automatically once. Dismissing it leaves the free dashboard usable without helper setup; Settings → General → Finish Setup and the menu bar protection action both resume the flow later.

8. Settings and UI Areas

Settings sections:

8.1 Dashboard

Provides real-time latency visibility and tuning controls.

Cards include:

Data retention behavior:

8.2 General

Controls:

Status block:

8.3 Automation

Controls:

8.4 Advanced

Tools:

8.5 License

8.6 Targets

9. Menu Bar and App Menu Integration

Menu bar:

App menu (frontmost app state):

10. Sparkle Update System

Update stack:

Operational details:

Release wiring:

11. Security Model

Security controls include:

12. Diagnostics and Health Checks

Built-in diagnostics surface:

Export diagnostics:

13. Performance Characteristics

Design choices for low overhead:

14. Build and Development

Prerequisites:

Open in Xcode:

cd PingWarden
open PingWarden.xcodeproj

Build from CLI (example):

xcodebuild -project PingWarden.xcodeproj -scheme PingWarden -configuration Debug build

Key project areas:

15. Release and Distribution

Run the release command from a clean commit that is already pushed:

cd PingWarden/PingWarden
bash release.sh X.Y.Z ../../RELEASE_NOTES.md

Before it builds anything, the command rebuilds the website's generated pages under Site/public from RELEASE_NOTES.md, the READMEs, and the guides, and stops if the committed copies are out of step. The website deploys only when those pages match their sources, so a release that edits the notes must commit the rebuilt Site/public/docs/releases.html alongside the version bump. The release then creates a fresh unsigned archive and dSYMs, validates and signs the app, helper, and widget, notarizes and staples the app and DMG, mount-tests the DMG, signs the Sparkle archive and appcast, publishes the GitHub release and Sentry dSYMs, updates gh-pages, and attaches the DMG to the Gumroad product.

Release files: PingWarden/PingWarden/release.sh, PingWarden/PingWarden/notarize.sh, and appcast.xml.

Important:

16. Limitations and Tradeoffs

Behavioral tradeoff while blocking AWDL:

Other practical limits:

17. Operational Best Practices

Recommended usage:

19. Credits

20. License and Pricing

Source code: MIT, Copyright (c) 2025-2026 Oliver Ames. Building from source under MIT does not require a license. See the repository LICENSE.

Prebuilt app: free to download, with Ping Protection gated behind a one-time purchased key. Section 8.5 describes the License pane and the verification behavior the app implements. The root README is the canonical statement of the price, the existing-user transition, and the donor path.

View this guide on GitHub