Skip to content

Latest commit

 

History

History
145 lines (106 loc) · 3.96 KB

File metadata and controls

145 lines (106 loc) · 3.96 KB

mod/socks

SOCKS5 proxy over Yggdrasil. Allows regular applications to access the Yggdrasil network via the standard SOCKS5 protocol.

Contents


Overview

flowchart LR
    App["application"] -->|" SOCKS5 "| Proxy["socks.Obj"]
    Proxy -->|" DialContext "| Ygg["Yggdrasil"]

    subgraph Proxy
        Listener["TCP / Unix listener"]
        Socks5["socks5.Server"]
        Limit["limitedListener"]
    end

    Listener --> Socks5
    Socks5 -->|" connect "| Ygg
Loading

The application connects to a SOCKS5 proxy (TCP or Unix socket), the proxy resolves the address via the provided NameResolver and establishes a connection through the Yggdrasil dialer.


Initialization

s := socks.New(node) // node — proxy.ContextDialer (usually core.Obj)

Creates a SOCKS5 proxy but does not start it. Call Enable to start.


Enabling and disabling

err := s.Enable(socks.EnableConfigObj{
Addr:           "127.0.0.1:1080", // or "/tmp/ygg.sock"
Resolver:       resolver,         // name resolver (.pk.ygg, DNS)
Verbose:        false, // log every connection
Logger:          logger,
MaxConnections: 100, // 0 — unlimited
})

s.IsEnabled() // true
s.Addr()   // "127.0.0.1:1080"
s.IsUnix() // false

err := s.Disable() // stop and clean up
Method Description
Enable(cfg) Starts the proxy; error if already running
Disable() Stops the proxy; idempotent
Addr() Current listening address
IsUnix() true if listening on a Unix socket
IsEnabled() true if the proxy is running

The Enable → Disable → Enable cycle is supported.


TCP and Unix socket

The listener type is determined by the address:

Address Type
127.0.0.1:1080 TCP
[::1]:1080 TCP
/tmp/ygg.sock Unix socket
./local.sock Unix socket

Rule: if the address starts with / or . — Unix socket, otherwise TCP.


Connection limiting

When MaxConnections > 0, the listener is wrapped in a limitedListener with a semaphore based on a buffered channel.

flowchart LR
    Accept["Accept()"] --> Sem{"semaphore free?"}
    Sem -->|" yes "| Conn["accept connection"]
    Sem -->|" no "| Block["wait"]
    Conn --> Close["Close()"]
    Close --> Release["release semaphore"]
Loading
  • Accept blocks when the limit is reached
  • Close releases the slot exactly once (sync.Once)
  • Repeated Close calls are safe

Unix socket handling

On startup with a Unix socket, stale files are handled:

flowchart TB
    Listen["net.Listen(unix)"] --> OK{"success?"}
    OK -->|" yes "| Done["ready"]
    OK -->|" EADDRINUSE "| Dial["dial socket"]
    Dial --> Alive{"responds?"}
    Alive -->|" yes "| Err["ErrAlreadyListening"]
    Alive -->|" no "| Check["Lstat: symlink?"]
    Check -->|" symlink "| Refuse["ErrSymlinkRefusal"]
    Check -->|" regular file "| Remove["os.Remove → retry"]
Loading
  • If the socket is held by a live process — error
  • If the socket is stale — it is removed and recreated
  • Symlinks are not removed (protection against attacks)

On Disable, the Unix socket file is automatically removed.


Errors

Variable Description
ErrAlreadyEnabled Enable called on an already running proxy
ErrAlreadyListening Unix socket is held by another process
ErrSymlinkRefusal Refusal to remove a symlink (safety measure)