yggpeers

package module
v0.0.0-...-2809de6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 16, 2025 License: GPL-3.0 Imports: 13 Imported by: 1

README

yggpeers

Go library for discovering and checking Yggdrasil Network public peers with mobile support (Android/iOS).

Features

  • 🌐 Load public peers from official sources with automatic fallback
  • ✅ Check peer availability for all protocols: TCP, TLS, QUIC, WS, WSS
  • ⚡ Measure RTT (Round Trip Time) for each peer
  • 🔍 Filter peers by protocol, region, RTT, availability
  • 📊 Sort peers by RTT, response time, or last seen
  • 💾 Cache with configurable TTL to reduce network load
  • 📱 Mobile bindings for Android/iOS via gomobile

Installation

Requirements: Go 1.25.5 or later

go get github.com/jbselfcompany/yggpeers

Quick Start

package main

import (
    "context"
    "fmt"
    "github.com/jbselfcompany/yggpeers"
)

func main() {
    mgr := yggpeers.NewManager()

    // Get best 5 TLS peers
    filter := &yggpeers.FilterOptions{
        Protocols:     []yggpeers.Protocol{yggpeers.ProtocolTLS},
        OnlyAvailable: true,
    }

    peers, _ := mgr.GetBestPeers(context.Background(), 5, filter)

    for _, peer := range peers {
        fmt.Printf("%s (RTT: %v)\n", peer.Address, peer.RTT)
    }
}

Usage

Create Manager
// Default settings (30 min cache, 5s timeout)
mgr := yggpeers.NewManager()

// Custom settings
mgr := yggpeers.NewManager(
    yggpeers.WithCacheTTL(15 * time.Minute),
    yggpeers.WithTimeout(3 * time.Second),
)
Get Peers
// Get all peers (cached)
peers, err := mgr.GetPeers(context.Background())

// Get available peers with filter
filter := &yggpeers.FilterOptions{
    Protocols:     []yggpeers.Protocol{yggpeers.ProtocolTLS, yggpeers.ProtocolQUIC},
    Regions:       []string{"germany", "france"},
    MaxRTT:        200 * time.Millisecond,
    OnlyAvailable: true,
}
peers, err := mgr.GetAvailablePeers(context.Background(), filter)

// Get best N peers
bestPeers, err := mgr.GetBestPeers(context.Background(), 10, filter)
Check Peer Availability
// Check single peer
err := mgr.CheckPeer(context.Background(), peer)
if peer.Available {
    fmt.Printf("RTT: %v\n", peer.RTT)
}

// Check multiple peers in parallel
err := mgr.CheckPeers(context.Background(), peers, 10) // 10 concurrent checks
Filter and Sort
// Filter peers
filtered := mgr.FilterPeers(peers, filter, yggpeers.SortByRTT)

// Get available regions
regions := yggpeers.GetRegions(peers)
Cache Management
// Refresh cache
err := mgr.RefreshCache(context.Background())

// Clear cache
mgr.ClearCache()

Mobile Usage

Android (Kotlin)

First, add the AAR to your Android project (place yggpeers.aar in app/libs/ and add to build.gradle):

dependencies {
    implementation files('libs/yggpeers.aar')
}

Then use in your code:

import yggpeers.Mobile

val manager = Mobile.newManager()

// Set log callback
manager.setLogCallback(object : Mobile.LogCallback {
    override fun onLog(level: String, message: String) {
        Log.d("YggPeers", "[$level] $message")
    }
})

// Get best peers
val peersJSON = manager.getBestPeers(10, "tls,quic")
val peers = JSONArray(peersJSON)

// Check peers asynchronously
manager.checkPeersAsync(peersJSON, object : Mobile.CheckCallback {
    override fun onPeerChecked(address: String, available: Boolean, rtt: Long) {
        Log.d("YggPeers", "$address: ${if (available) "✓" else "✗"}")
    }

    override fun onCheckComplete(available: Int, total: Int) {
        Log.i("YggPeers", "Complete: $available/$total available")
    }
})
Building AAR

Windows:

cd mobile
build-android.bat

Unix/Linux/macOS:

cd mobile
gomobile bind -target=android -androidapi 23 -ldflags="-checklinkname=0" -o yggpeers.aar github.com/jbselfcompany/yggpeers/mobile

Output: yggpeers.aar and yggpeers-sources.jar

Prerequisites:

  • Android SDK installed and ANDROID_HOME environment variable set
  • gomobile installed: go install golang.org/x/mobile/cmd/gomobile@latest
  • gomobile initialized: gomobile init

API Reference

Manager
  • NewManager(opts ...SetupOption) *Manager - Create new manager
  • GetPeers(ctx) ([]*Peer, error) - Get all peers (cached)
  • GetAvailablePeers(ctx, filter) ([]*Peer, error) - Get checked available peers
  • GetBestPeers(ctx, count, filter) ([]*Peer, error) - Get N best peers by RTT
  • CheckPeer(ctx, peer) error - Check single peer availability
  • CheckPeers(ctx, peers, concurrency) error - Check multiple peers in parallel
  • FilterPeers(peers, filter, sortBy) []*Peer - Filter and sort peers
  • RefreshCache(ctx) error - Force cache refresh
  • ClearCache() - Clear cache
Setup Options
  • WithCacheTTL(ttl) - Set cache TTL
  • WithTimeout(timeout) - Set check timeout
  • WithHTTPClient(client) - Set custom HTTP client
  • WithCustomURLs(primary, fallback) - Set custom JSON sources
Types
type Peer struct {
    Address    string        // "tls://host:port"
    Protocol   Protocol      // tcp, tls, quic, ws, wss, unix, socks
    Host       string
    Port       string
    Region     string        // "germany"

    // From JSON
    Up         bool
    Key        string
    ResponseMS int
    LastSeen   int64
    Updated    int64
    Imported   int64
    ProtoMinor int
    Priority   *int

    // Check results
    Available  bool
    RTT        time.Duration
    CheckedAt  time.Time
    CheckError error
}

type FilterOptions struct {
    Protocols     []Protocol
    Regions       []string
    MinRTT        time.Duration
    MaxRTT        time.Duration
    OnlyUp        bool
    OnlyAvailable bool
}

Examples

See examples/ directory:

Data Sources

License

GNU General Public License v3.0 (GPL-3.0)

Contributing

Contributions are welcome! Please open an issue or pull request.

  • yggdrasil-go - Yggdrasil Network core
  • yggquic - QUIC transport for Yggdrasil
  • yggmail - Mail over Yggdrasil
  • Tyr - True P2P Email on top of Yggdrasil Network for Android

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetRegions

func GetRegions(peers []*Peer) []string

GetRegions returns a list of all unique regions

Types

type Cache

type Cache struct {
	// contains filtered or unexported fields
}

Cache stores cached peers with TTL

func NewCache

func NewCache(ttl time.Duration) *Cache

NewCache creates a new cache with the given TTL

func (*Cache) Clear

func (c *Cache) Clear()

Clear clears the cache

func (*Cache) Get

func (c *Cache) Get() ([]*Peer, bool)

Get returns cached peers or nil if cache has expired

func (*Cache) IsValid

func (c *Cache) IsValid() bool

IsValid checks if cache is valid

func (*Cache) Set

func (c *Cache) Set(peers []*Peer)

Set saves peers to cache

type FilterOptions

type FilterOptions struct {
	Protocols     []Protocol    // Filter by protocols
	Regions       []string      // Filter by regions
	MinRTT        time.Duration // Minimum RTT
	MaxRTT        time.Duration // Maximum RTT
	OnlyUp        bool          // Only "up" peers from JSON
	OnlyAvailable bool          // Only checked available peers
}

FilterOptions defines filtering criteria

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager manages the list of peers and cache

func NewManager

func NewManager(opts ...SetupOption) *Manager

NewManager creates a new peers manager

func (*Manager) CheckPeer

func (m *Manager) CheckPeer(ctx context.Context, peer *Peer) error

CheckPeer checks peer availability based on protocol

func (*Manager) CheckPeers

func (m *Manager) CheckPeers(ctx context.Context, peers []*Peer, concurrency int) error

CheckPeers checks multiple peers in parallel

func (*Manager) ClearCache

func (m *Manager) ClearCache()

ClearCache clears the cache

func (*Manager) FilterPeers

func (m *Manager) FilterPeers(peers []*Peer, filter *FilterOptions, sortBy SortBy) []*Peer

FilterPeers filters and sorts peers

func (*Manager) GetAvailablePeers

func (m *Manager) GetAvailablePeers(ctx context.Context, filter *FilterOptions) ([]*Peer, error)

GetAvailablePeers returns checked available peers

func (*Manager) GetBestPeers

func (m *Manager) GetBestPeers(ctx context.Context, count int, filter *FilterOptions) ([]*Peer, error)

GetBestPeers returns N best peers by RTT

func (*Manager) GetPeers

func (m *Manager) GetPeers(ctx context.Context) ([]*Peer, error)

GetPeers returns all peers (using cache)

func (*Manager) RefreshCache

func (m *Manager) RefreshCache(ctx context.Context) error

RefreshCache forces cache refresh

type Peer

type Peer struct {
	Address  string   // Full address: "tcp://host:port"
	Protocol Protocol // Extracted protocol
	Host     string   // Host without protocol
	Port     string   // Port

	Region string // Region from JSON key: "germany.md" -> "germany"

	// Fields from JSON
	Up         bool   `json:"up"`
	Key        string `json:"key"`
	ResponseMS int    `json:"response_ms"`
	LastSeen   int64  `json:"last_seen"`
	Updated    int64  `json:"updated"`
	Imported   int64  `json:"imported"`
	ProtoMinor int    `json:"proto_minor"`
	Priority   *int   `json:"priority,omitempty"`

	// Check results
	Available  bool          // Is the peer available now
	RTT        time.Duration // Measured RTT
	CheckedAt  time.Time     // Time of check
	CheckError error         // Check error if any
}

Peer represents information about a Yggdrasil peer from the public list

type Protocol

type Protocol string

Protocol represents the type of peer protocol

const (
	ProtocolTCP      Protocol = "tcp"
	ProtocolTLS      Protocol = "tls"
	ProtocolQUIC     Protocol = "quic"
	ProtocolWS       Protocol = "ws"
	ProtocolWSS      Protocol = "wss"
	ProtocolUNIX     Protocol = "unix"
	ProtocolSOCKS    Protocol = "socks"
	ProtocolSOCKSTLS Protocol = "sockstls"
)

type RawPeersJSON

type RawPeersJSON map[string]map[string]struct {
	Up         bool   `json:"up"`
	Key        string `json:"key"`
	ResponseMS int    `json:"response_ms"`
	LastSeen   int64  `json:"last_seen"`
	Updated    int64  `json:"updated"`
	Imported   int64  `json:"imported"`
	ProtoMinor int    `json:"proto_minor"`
	Priority   *int   `json:"priority,omitempty"`
}

RawPeersJSON represents the structure of JSON from publicnodes.json Format: map["country.md"]map["address"]{up, key, response_ms, ...}

type SetupOption

type SetupOption func(*Manager)

SetupOption is a functional option for Manager

func WithCacheTTL

func WithCacheTTL(ttl time.Duration) SetupOption

WithCacheTTL sets the cache TTL

func WithCustomURLs

func WithCustomURLs(primary, fallback string) SetupOption

WithCustomURLs sets custom primary and fallback URLs

func WithHTTPClient

func WithHTTPClient(client *http.Client) SetupOption

WithHTTPClient sets a custom HTTP client

func WithTimeout

func WithTimeout(timeout time.Duration) SetupOption

WithTimeout sets the timeout for availability checks

type SortBy

type SortBy int

SortBy defines the sorting method

const (
	SortByRTT SortBy = iota
	SortByResponseMS
	SortByAvailability
	SortByLastSeen
)

Directories

Path Synopsis
examples
basic command
filter command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL