Help us shape the future of Go! Take the 2026 Go Developer Survey

servicedisc

package
v1.3.104-alpha1 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: AGPL-3.0 Imports: 21 Imported by: 5

Documentation

Overview

Package servicedisc pkg/servicedisc/client.go c2-net-discovery

Package servicedisc pkg/servicedisc/error.go c2-net-discovery

Package servicedisc pkg/servicedisc/query.go c2-net-discovery

Package servicedisc pkg/servicedisc/types.go c2-net-discovery

Index

Constants

View Source
const (
	// ServiceTypeSkysocks stands for the skysocks discovery.
	ServiceTypeSkysocks = "skysocks"
	// ServiceTypeProxy stands for the proxy discovery. Proxy and Skysocks are same
	ServiceTypeProxy = "proxy"
	// ServiceTypeVPN stands for the VPN discovery.
	ServiceTypeVPN = "vpn"
	// ServiceTypeVisor stands for visor.
	ServiceTypeVisor = "visor"
	// ServiceTypeCoin stands for a discoverable fibercoin node. Intentionally
	// GENERIC — any fibercoin, not skycoin specifically — so a (browser/wasm)
	// thin-client wallet can discover a node for the right coin/network over
	// dmsg and reach its HTTP API through the mesh, with no local full node and
	// no launch flags. The coin identity + capabilities live in Service.Coin
	// (CoinInfo); the node's dmsg address is Service.Addr.
	ServiceTypeCoin = "coin"
)

Variables

View Source
var (
	ErrInvalidSWAddr = errors.New("invalid skywire address")
)

Errors associated with service discovery types.

View Source
var ErrVisorUnreachable = errors.New("visor is unreachable")

ErrVisorUnreachable is returned when visor is not reachable

Functions

This section is empty.

Types

type CoinInfo

type CoinInfo struct {
	// BlockchainPubKey is the block-publisher public key that signs this chain —
	// the AUTHORITATIVE, cryptographic chain identifier. A wallet must verify it
	// is on the intended chain by THIS key, not by the human name, so a node can
	// never spoof another chain by calling itself "skycoin".
	BlockchainPubKey string `json:"blockchain_pubkey,omitempty"`
	// GenesisAddress + GenesisSignature anchor the chain's genesis block — an
	// independent identity check beyond the block-publisher key.
	GenesisAddress   string `json:"genesis_address,omitempty"`
	GenesisSignature string `json:"genesis_signature,omitempty"`
	// Fiber is the human-readable coin name (e.g. "skycoin", "mdl") for display +
	// coarse filtering ONLY — never the trust anchor; BlockchainPubKey is.
	Fiber string `json:"fiber,omitempty"`
	// Network is the coin network — "main" or "test".
	Network string `json:"network,omitempty"`
	// Version + Commit identify the DAEMON's OWN build, as reported by its HTTP
	// API (skycoin /api/v1/health -> version{version, commit}). This is
	// deliberately NOT the visor's compiled-in skycoin import (`skywire -d`): the
	// daemon runs independently, so its build can differ from the visor's, and the
	// advertisement must reflect the ACTUAL running node. Commit pins the exact
	// build precisely.
	Version string `json:"version,omitempty"`
	Commit  string `json:"commit,omitempty"`
	// HeadSeq is the current block-head sequence, so a wallet can prefer a
	// well-synced node. Also a freshness signal alongside the SD re-registration.
	HeadSeq uint64 `json:"head_seq,omitempty"`
}

CoinInfo describes a discoverable fibercoin node (ServiceTypeCoin). The enclosing Service.Addr is the node's dmsg address (the forwarding visor's PK + dmsg port). Every field here is DETECTED from the node's own health/metadata response — never operator-configured — so an advertisement can't be misconfigured (accidentally or maliciously) to claim the wrong chain. A wallet filters and TRUSTS on the cryptographic chain identity (BlockchainPubKey / genesis), not on the human name. Generic across fibercoins.

type Config

type Config struct {
	Type          string
	PK            cipher.PubKey
	SK            cipher.SecKey
	Port          uint16
	DiscAddr      string
	DisplayNodeIP bool
	// Geo, when non-nil, is attached to the entry on Register/Update.
	// The service-discovery server short-circuits its own IP→geo HTTP
	// lookup when the entry already carries Geo, so a visor that does
	// its own geoip lookup (via dmsg-server LookupIPGeo or the visor's
	// embedded MaxMind DB) eliminates the SD→geoip-service round-trip.
	Geo *geo.LocationData
	// GeoFunc, when non-nil, returns the visor's CURRENT geolocation and is
	// re-read on every RegisterEntry (heartbeat). This is what makes geo
	// RELIABLE: the visor's geoip lookup is async and usually finishes AFTER
	// the first registration, so a fixed Geo snapshot (captured at NewClient)
	// permanently registered with no country whenever it lost that race. With
	// GeoFunc, the next heartbeat after the lookup completes carries the country.
	GeoFunc func() *geo.LocationData
	// PublicIPFunc, when non-nil, returns the visor's current public IP. It is
	// re-read on every registration and request, so the entry and the
	// SW-PublicIP header follow the visor to a new network.
	PublicIPFunc func() string
	// Sink, when non-nil, is handed a copy of every entry this client
	// successfully registers, and of every entry it deregisters. It is how
	// the visor's SD-registration-over-CXO publisher learns its own live
	// service set VERBATIM — the exact Service the SD accepted and echoed
	// back, not a reconstruction. Purely additive: the HTTP register/delete
	// calls are unchanged and remain authoritative.
	Sink EntrySink
}

Config configures the HTTPClient.

type EntrySink

type EntrySink interface {
	// PutEntry records a service entry as live.
	PutEntry(entry Service)
	// DelEntry records a service entry as gone.
	DelEntry(entry Service)
}

EntrySink receives copies of the entries an HTTPClient registers and deregisters. Implementations MUST NOT block: they run inline on the caller's registration goroutine (the 90s heartbeat loop, or an app start/stop).

type GeoQuery

type GeoQuery struct {
	Lat        float64
	Lon        float64
	Radius     float64 // Format: <value><unit>
	RadiusUnit string
	Count      int64
}

GeoQuery represents query values for a proxies by geo call.

func DefaultGeoQuery

func DefaultGeoQuery() GeoQuery

DefaultGeoQuery returns GeoQuery with default values.

func (*GeoQuery) Fill

func (q *GeoQuery) Fill(v url.Values) error

Fill fills GeoQuery with query values.

type HTTPClient

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

HTTPClient is responsible for interacting with the service-discovery

func NewClient

func NewClient(log logrus.FieldLogger, mLog *logging.MasterLogger, conf Config, client *http.Client, clientPublicIP string) *HTTPClient

NewClient creates a new HTTPClient.

func (*HTTPClient) Auth

Auth returns the internal httpauthclient.Client

func (*HTTPClient) Configured

func (c *HTTPClient) Configured() bool

Configured reports whether this client can perform HTTP service discovery — it has both a non-nil http.Client and a discovery address. Callers (e.g. the autoconnector) should skip the HTTP path when this is false instead of invoking it, which would otherwise nil-deref c.client. This happens when the operator drops/blanks the service_discovery URL to force dmsg-only.

func (*HTTPClient) DeleteEntry

func (c *HTTPClient) DeleteEntry(ctx context.Context) error

DeleteEntry calls 'DELETE /api/services/{entry_addr}'.

func (*HTTPClient) Register

func (c *HTTPClient) Register(ctx context.Context) error

Register calls 'POST /api/services' to register service discovery entry it performs exponential backoff in case of errors during register, unless the error is unrecoverable from

func (*HTTPClient) RegisterEntry

func (c *HTTPClient) RegisterEntry(ctx context.Context) error

RegisterEntry calls 'POST /api/services', retrieves the entry and updates local field with the result if there are no ip addresses in the entry it also tries to fetch those from local config

func (*HTTPClient) Services

func (c *HTTPClient) Services(ctx context.Context, quantity int, version, country string) (out []Service, err error)

Services calls 'GET /api/services'.

func (*HTTPClient) SetCoinInfo

func (c *HTTPClient) SetCoinInfo(info *CoinInfo)

SetCoinInfo attaches fibercoin identity/metadata (CoinInfo) to the entry this client registers. Call before Register/RegisterEntry, and again between heartbeats to refresh volatile fields (e.g. HeadSeq). Only meaningful for a ServiceTypeCoin client; ignored by other service types on the SD server side.

type HTTPError

type HTTPError struct {
	HTTPStatus int    `json:"code,omitempty"` // HTTP Status.
	Err        string `json:"error,omitempty"`
}

HTTPError represents an HTTP error.

func (*HTTPError) Error

func (err *HTTPError) Error() string

Error implements error.

func (*HTTPError) Log

func (err *HTTPError) Log(log logrus.FieldLogger)

Log prints a log message for the HTTP error.

func (*HTTPError) Temporary

func (err *HTTPError) Temporary() bool

Temporary implements net.Error.

func (*HTTPError) Timeout

func (err *HTTPError) Timeout() bool

Timeout implements net.Error.

type KeepaliveSink added in v1.3.98

type KeepaliveSink interface {
	EntrySink
	KeepaliveHealthy() (healthy bool, epoch uint64)
}

KeepaliveSink is an EntrySink that can also keep the registered entries alive by itself (the visor's SD-registration-over-CXO feed, whose Roots refresh the SD's stored entries). While KeepaliveHealthy reports healthy on the epoch of the last HTTP registration, an unchanged heartbeat skips HTTP. A new epoch (the SD resubscribed, possibly after losing its store) makes the next heartbeat register over HTTP once.

type SWAddr

type SWAddr [len(cipher.PubKey{}) + 2]byte

SWAddr represents a skywire address.

func NewSWAddr

func NewSWAddr(pk cipher.PubKey, port uint16) SWAddr

NewSWAddr creates a new SWAddr.

func (*SWAddr) MarshalBinary

func (a *SWAddr) MarshalBinary() ([]byte, error)

MarshalBinary implements encoding.BinaryMarshaller

func (*SWAddr) MarshalText

func (a *SWAddr) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler

func (*SWAddr) Port

func (a *SWAddr) Port() uint16

Port returns the contained port.

func (*SWAddr) PubKey

func (a *SWAddr) PubKey() (pk cipher.PubKey)

PubKey returns the contained public key.

func (*SWAddr) Scan

func (a *SWAddr) Scan(value interface{}) error

Scan implement a scanner to get data from database

func (*SWAddr) String

func (a *SWAddr) String() string

String implements io.Stringer

func (*SWAddr) UnmarshalBinary

func (a *SWAddr) UnmarshalBinary(data []byte) error

UnmarshalBinary implements encoding.BinaryUnmarshaler

func (*SWAddr) UnmarshalText

func (a *SWAddr) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaller

func (SWAddr) Value

func (a SWAddr) Value() (driver.Value, error)

Value is a method to get value of data fetched from database

type Service

type Service struct {
	ID            uint              `json:"-" gorm:"primarykey"`
	CreatedAt     time.Time         `json:"-"`
	Addr          SWAddr            `json:"address"`
	Type          string            `json:"type"`
	Geo           *geo.LocationData `json:"geo,omitempty" gorm:"embedded"`
	DisplayNodeIP bool              `json:"display_node_ip,omitempty"`
	Version       string            `json:"version,omitempty"`
	LocalIPs      []string          `json:"local_ips,omitempty"`
	Info          *VPNInfo          `json:"info,omitempty" gorm:"-"`
	// Coin, set for ServiceTypeCoin entries, carries the fibercoin identity +
	// capabilities so a thin-client wallet can filter discovery by coin/network
	// without launch flags. Transient (gorm:"-"), like Info.
	Coin *CoinInfo `json:"coin,omitempty" gorm:"-"`
}

Service represents a service entry in service-discovery.

func (Service) Check

func (p Service) Check() error

Check ensures fields are valid.

func (*Service) MarshalBinary

func (p *Service) MarshalBinary() ([]byte, error)

MarshalBinary implements encoding.BinaryMarshaller

func (Service) String

func (p Service) String() string

func (*Service) UnmarshalBinary

func (p *Service) UnmarshalBinary(data []byte) error

UnmarshalBinary implements encoding.BinaryUnmarshaler

type ServicesQuery

type ServicesQuery struct {
	Count  int64  // <=0 : no limit
	Cursor uint64 // <=0 : 0 offset
}

ServicesQuery represents query values for a proxies call.

func (*ServicesQuery) Fill

func (q *ServicesQuery) Fill(v url.Values) error

Fill fills ServicesQuery with query values.

type VPNInfo

type VPNInfo struct {
	Latency     float64 `json:"latency,omitempty"`
	Uptime      float64 `json:"uptime,omitempty"`
	Connections int     `json:"connections,omitempty"`
}

VPNInfo used for showing VPN metrics info, like latency, uptime and count of connections

Jump to

Keyboard shortcuts

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