topology

package
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2024 License: Apache-2.0 Imports: 23 Imported by: 1

Documentation

Overview

Package topology wraps two versions of the topology. The first is RWTopology, which permits other packages to change topology information. The second topology type is Topology. It is used by packages that only need read access to the topology.

The full JSON format for a SCION address looks like the following:

"Addrs":{
  "IPv4": {
    "Public": {
      "Addr": "192.168.1.1",
      "L4Port": 31000,
      "OverlayPort": 30041,
    },
    "Bind": {
      "Addr": "127.0.0.1",
      "L4Port": 31000,
      "OverlayPort": 30041,
    }
  },
  "IPv6": {
    "Public": {
      "Addr": "2001:db8:f00:b43::1",
      "L4Port": 31000,
      "OverlayPort": 30041,
    },
    "Bind": {
      "Addr": "2001:db8:f00:b43::1",
      "L4Port": 31000,
      "OverlayPort": 30041,
    }
  }
}

Go applications parse the above in the following manner:

  • Properties not listed in the above are ignored;
  • If a "Bind" property is found, parsing will return an error; bind addresses for SCION sockets are currently not supported.
  • If an "OverlayPort" property is found, parsing will return an error; custom underlay ports for SCION sockets are currently not supported. NOTE: the JSON file uses the old "Overlay" term for the AS-level UDP fabric that forwards traffic. The new term for this (which is also used in the Go code base) is "Underlay".
  • If both property "IPv4" and "IPv6" are present, the address is assumed to be IPv6 and only that address is used (in other words, the IPv4 property contents are discarded); dual stacked addresses are currently not supported.

The full JSON format for a BR data-plane AS-external underlay socket looks like the following:

{
  "Overlay": "UDP/IPv4",
  "ISD_AS": "1-ff00:0:1",
  "Bandwidth": 1000,
  "PublicOverlay": {
    "Addr": "192.168.0.1",
    "OverlayPort": 50000,
  },
  "BindOverlay": {
    "Addr": "127.0.0.1",
  },
  "RemoteOverlay": {
    "Addr": "192.168.0.2",
    "OverlayPort": 50000,
  },
  "LinkTo": "CORE",
  "MTU": 1472,
}

To construct a BR data-plane AS-external underlay socket address out of the above, the following rules are used:

  • Properties "ISD_AS", "Bandwidth", "LinkTo", and "MTU" are ignored. All unknown properties not included in the above example are silently ignored.
  • Properties "PublicOverlay" and "RemoteOverlay" must exist. An error is returned if one of them is missing.
  • Property "BindOverlay" is optional. If it is not present, then the address checks below do not apply to property "Addr" under "BindOverlay". If it is present, the address is subject to all format constraints below.
  • If property "Overlay" is "UDP/IPv4", all "Addr" properties are checked to be IPv4. If one cannot be parsed as an IPv4 address, an error is returned. If the address is the empty string, an error is returned.
  • If property "Overlay" is "UDP/IPv6", all "Addr" properties are checked to be IPv6. If one cannot be parsed as an IPv6 address, an error is returned. If the address is the empty string, an error is returned.
  • If a port property is missing, it is assumed to be 0. The application is free to interpret this however it sees fit.

The full JSON format for a BR data-plane AS-internal underlay socket address looks like the following:

{
  "IPv4": {
    "PublicOverlay": {
      "Addr": "192.168.0.1",
      "OverlayPort": 31000,
    },
    BindOverlay": {
      "Addr": "127.0.0.1"
    }
  },
  "IPv6": {
    "PublicOverlay": {
      "Addr": "2001:db8:f00:b43::1",
      "OverlayPort": 31000
    },
    "BindOverlay": {
      "Addr": "::1"
    }
  }
}

To construct a BR data-plane AS-internal underlay socket address out of the above, the following rules are used:

  • Properties not listed in the above are ignored.
  • If both property "IPv4" and "IPv6" are present, the address is assumed to be IPv6 and only that address is used (in other words, the IPv4 property contents are discarded); dual stacked addresses are currently not supported.
  • For the chosen address, the underlay address is taken from the "BindOverlay" property; if this is the case, the "PublicOverlay" address is never parsed. The address must match the address type in the top-level property (IPv4 or IPv6), otherwise an error is returned. If the "BindOverlay" property does not exist, the underlay address is taken from the "PublicOverlay" property. The address must match the address type in the top-level property, otherwise an error is returned. No matter which address is used, the port is always taken from the "PublicOverlay" property". An unset port is interpreted as 0.

Index

Constants

View Source
const (
	// EndhostPort is the underlay port that SCION binds to on non-routers.
	EndhostPort = underlay.EndhostPort
)

Variables

View Source
var ErrAddressNotFound = serrors.New("address not found")

ErrAddressNotFound indicates the address was not found.

Functions

func Digest

func Digest(t interface{}) ([]byte, error)

Types

type BFD

type BFD struct {
	Disable               *bool
	DetectMult            uint8
	DesiredMinTxInterval  time.Duration
	RequiredMinRxInterval time.Duration
}

BFD is the configuration for a BFD session Disable can be set from two sources: the topology configuration for the link (here), and the dataplane's bfd global configuration. This is actually a pointer to boolean. nil means unspecified.

type BRInfo

type BRInfo struct {
	Name string
	// InternalAddr is the local data-plane address.
	InternalAddr netip.AddrPort
	// IfIDs is a sorted list of the interface IDs.
	IfIDs []iface.ID
	// IFs is a map of interface IDs.
	IFs map[iface.ID]*IFInfo
}

BRInfo is a list of AS-wide unique interface IDs for a router. These IDs are also used to point to the specific internal address clients should send their traffic to in order to use that interface, via the IFInfoMap member of the Topo struct.

type ControlValidator

type ControlValidator struct {
	ID string
	// contains filtered or unexported fields
}

func (*ControlValidator) Validate

func (v *ControlValidator) Validate(new, old *RWTopology) error

type DefaultValidator

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

DefaultValidator is the default topology update validator.

func (*DefaultValidator) Validate

func (v *DefaultValidator) Validate(new, old *RWTopology) error

type GatewayInfo

type GatewayInfo struct {
	CtrlAddr        *TopoAddr
	DataAddr        *net.UDPAddr
	ProbeAddr       *net.UDPAddr
	AllowInterfaces []uint64
}

GatewayInfo describes a scion gateway.

type IDAddrMap

type IDAddrMap map[string]TopoAddr

IDAddrMap maps process IDs to their topology addresses.

func (IDAddrMap) GetByID

func (m IDAddrMap) GetByID(id string) *TopoAddr

GetByID returns the TopoAddr for the given ID, or nil if there is none.

type IFInfo

type IFInfo struct {
	// ID is the interface ID. It is unique per AS.
	ID           iface.ID
	BRName       string
	InternalAddr netip.AddrPort
	Local        netip.AddrPort
	Remote       netip.AddrPort
	RemoteIfID   iface.ID
	IA           addr.IA
	LinkType     LinkType
	MTU          int
	BFD          BFD
}

IFInfo describes a border router link to another AS, including the internal data-plane address applications should send traffic to and information about the link itself and the remote side of it.

func (i IFInfo) CheckLinks(isCore bool, brName string) error

CheckLinks checks whether the link types are compatible with whether the AS is core or not.

func (IFInfo) String

func (i IFInfo) String() string

type IfInfoMap

type IfInfoMap map[iface.ID]IFInfo

IfInfoMap maps interface ids to the interface information.

type LinkType

type LinkType int

LinkType describes inter-AS links.

const (
	// Unset is used for unknown link types.
	Unset LinkType = 0
	// Core links connect core ASes.
	Core LinkType = 1
	// Parent links are configured on non-core links pointing towards the core of an ISD.
	Parent LinkType = 2
	// Child links are configured on non-core links pointing away from the core of an ISD.
	Child LinkType = 3
	// Peer links are configured for peering relationships.
	Peer LinkType = 4
)

func LinkTypeFromString

func LinkTypeFromString(s string) LinkType

LinkTypeFromString returns the numerical link type associated with a string description. If the string is not recognized, an Unset link type is returned. The matching is case-insensitive.

func (LinkType) MarshalText

func (l LinkType) MarshalText() ([]byte, error)

func (LinkType) String

func (l LinkType) String() string

func (*LinkType) UnmarshalText

func (l *LinkType) UnmarshalText(data []byte) error

type Loader

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

Loader can be used to reload the topology transparently. The default object is not usable and the loaded should be constructed with the NewLoader function.

func NewLoader

func NewLoader(cfg LoaderCfg) (*Loader, error)

NewLoader creates a topology loader from the given configuration. This method tries to load the file initially and if that doesn't succeeds an error is returned.

func (*Loader) ControlServiceAddress

func (l *Loader) ControlServiceAddress(id string) *net.UDPAddr

func (*Loader) ControlServiceAddresses

func (l *Loader) ControlServiceAddresses() []*net.UDPAddr

func (*Loader) Core

func (l *Loader) Core() bool

func (*Loader) Gateways

func (l *Loader) Gateways() ([]GatewayInfo, error)

TODO(lukedirtwalker): remove error and simplify struct in the return type.

func (*Loader) Get deprecated

func (l *Loader) Get() Topology

Get gets the instance of the topology.

Deprecated: New code should use accessor methods instead.

func (*Loader) GetUnderlay

func (l *Loader) GetUnderlay(svc addr.SVC) (*net.UDPAddr, error)

TODO(lukedirtwalker): remove error / cleanup.

func (*Loader) HandleHTTP

func (l *Loader) HandleHTTP(w http.ResponseWriter, r *http.Request)

func (*Loader) HiddenSegmentLookupAddresses

func (l *Loader) HiddenSegmentLookupAddresses() ([]*net.UDPAddr, error)

TODO(lukedirtwalker): remove error.

func (*Loader) HiddenSegmentRegistrationAddresses

func (l *Loader) HiddenSegmentRegistrationAddresses() ([]*net.UDPAddr, error)

TODO(lukedirtwalker): remove error.

func (*Loader) IA

func (l *Loader) IA() addr.IA

func (*Loader) IfIDs added in v0.12.0

func (l *Loader) IfIDs() []uint16

func (*Loader) InterfaceInfoMap

func (l *Loader) InterfaceInfoMap() map[iface.ID]IFInfo

func (*Loader) MTU

func (l *Loader) MTU() uint16

func (*Loader) PortRange added in v0.12.0

func (l *Loader) PortRange() (uint16, uint16)

func (*Loader) Run

func (l *Loader) Run(ctx context.Context) error

Run runs the topology reloader. It makes sure that the topology is reloaded when the configured signal channel is filled. A topology that can't be parsed or doesn't validate will be ignored.

func (*Loader) Subscribe

func (l *Loader) Subscribe() *Subscription

Subscribe can be used to subscribe to updates.

func (*Loader) UnderlayNextHop

func (l *Loader) UnderlayNextHop(ifID uint16) *net.UDPAddr

type LoaderCfg

type LoaderCfg struct {
	// File is the file from which the topology should be loaded.
	File string
	// Reload is the channel on which reloads can be triggered.
	Reload <-chan struct{}
	// Validator is used to validate topology updates. If this field is not set,
	// update is permissible. If the validation is error a reload is discarded
	Validator Validator
	// Metrics are the metrics of the loader, if left empty no metrics are
	// reported.
	Metrics LoaderMetrics
}

LoaderCfg is the configuration for the topology loader.

type LoaderMetrics

type LoaderMetrics struct {
	// ValidationErrors counts the amount of validation errors.
	ValidationErrors metrics.Counter
	// ReadErrors counts the amount of file read or parse errors.
	ReadErrors metrics.Counter
	// LastUpdate indicates the timestamp of the last successful update.
	LastUpdate metrics.Gauge
	// Updates counts the amount of successful updates.
	Updates metrics.Counter
}

LoaderMetrics are the metrics exposed by the topology loader. Individual values can be nil, which means they will not be exposed.

type RWTopology

type RWTopology struct {
	Timestamp           time.Time
	IA                  addr.IA
	IsCore              bool
	MTU                 int
	DispatchedPortStart uint16
	DispatchedPortEnd   uint16

	BR        map[string]BRInfo
	IFInfoMap IfInfoMap

	CS                        IDAddrMap
	DS                        IDAddrMap
	HiddenSegmentLookup       IDAddrMap
	HiddenSegmentRegistration IDAddrMap
	SIG                       map[string]GatewayInfo
}

RWTopology is the topology type for applications and libraries that need write access to AS topology information (e.g., discovery, topology reloaders).

The first section contains metadata about the topology. All of these fields should be self-explanatory. The unit of TTL is seconds, with the zero value indicating an infinite TTL.

The second section concerns the Border routers. The BR map points from border router names to BRInfo structs, which in turn are lists of IfID type slices, thus defines the IfIDs that belong to a particular border router. The IFInfoMap points from interface IDs to IFInfo structs.

The third section in RWTopology concerns the SCION-specific services in the topology. The structure is identical between the various elements. For each service, there is again a sorted slice of names of the servers that provide the service. Additionally, there is a map from those names to TopoAddr structs.

func NewRWTopology

func NewRWTopology() *RWTopology

NewRWTopology creates new empty Topo object, including all possible service maps etc.

func RWTopologyFromJSONBytes

func RWTopologyFromJSONBytes(b []byte) (*RWTopology, error)

RWTopologyFromJSONBytes extracts the topology from a JSON representation in raw byte format.

func RWTopologyFromJSONFile

func RWTopologyFromJSONFile(path string) (*RWTopology, error)

RWTopologyFromJSONFile extracts the topology from a file containing the JSON representation of the topology.

func RWTopologyFromJSONTopology

func RWTopologyFromJSONTopology(raw *jsontopo.Topology) (*RWTopology, error)

RWTopologyFromJSONTopology converts a parsed JSON struct topology to a topology usable by Go code.

func (*RWTopology) Active

func (t *RWTopology) Active(now time.Time) bool

Active returns whether the topology is active at the point in time specified by the argument. A topology is active if now is after the timestamp.

func (*RWTopology) Copy

func (t *RWTopology) Copy() *RWTopology

Copy creates a deep copy of the object.

func (*RWTopology) GetTopoAddr

func (t *RWTopology) GetTopoAddr(id string, svc ServiceType) (*TopoAddr, error)

GetTopoAddr returns the address information for the process of the requested type with the requested ID.

type RouterValidator

type RouterValidator struct {
	ID string
	// contains filtered or unexported fields
}

func (*RouterValidator) Validate

func (v *RouterValidator) Validate(new, old *RWTopology) error

type ServiceNames

type ServiceNames []string

ServiceNames is a slice of process names (e.g., "bs-1", "bs-2").

func (ServiceNames) GetRandom

func (s ServiceNames) GetRandom() (string, error)

GetRandom returns a random entry, or an error if the slice is empty.

type ServiceType

type ServiceType int

ServiceType describes the type of servce.

const (
	Unknown ServiceType = iota
	Router
	Control
	Discovery
	Gateway
	HiddenSegmentLookup
	HiddenSegmentRegistration
)

Service types

func ServiceTypeFromString

func ServiceTypeFromString(s string) ServiceType

ServiceTypeFromString parses the service type.

func (ServiceType) String

func (t ServiceType) String() string

type Subscription

type Subscription struct {
	Updates <-chan struct{}
	// contains filtered or unexported fields
}

Subscription is a subscription for topology updates. It should be Closed whenever it's no longer used. When the context of the Loader is cancelled the Subscription will no longer be served, but the subscription channel is not closed. It is the user responsibility to stop using the Subscription if the Loader context is cancelled.

func (*Subscription) Close

func (s *Subscription) Close()

type TopoAddr

type TopoAddr struct {
	SCIONAddress    *net.UDPAddr
	UnderlayAddress *net.UDPAddr
}

TopoAddr wraps the possible addresses of a SCION service and describes the underlay to be used for contacting said service. XXX: this has become redundant. Replace with single address (and netip.AddrPort)

func (*TopoAddr) String

func (a *TopoAddr) String() string

func (*TopoAddr) UnderlayAddr

func (a *TopoAddr) UnderlayAddr() *net.UDPAddr

UnderlayAddr returns the underlay address interpreted as a net.UDPAddr.

FIXME(scrye): This should be removed; applications should not need to look into the underlay concrete type.

type Topology

type Topology interface {
	// IA returns the local ISD-AS number.
	IA() addr.IA
	// MTU returns the MTU of the local AS.
	MTU() uint16
	// Core returns whether the local AS is core.
	Core() bool
	// InterfaceIDs returns all interface IDS from the local AS.
	IfIDs() []iface.ID
	// PortRange returns the first and last ports of the port range (both included),
	// in which endhost listen for SCION/UDP application using the UDP/IP underlay.
	PortRange() (uint16, uint16)

	// PublicAddress gets the public address of a server with the requested type and name, and nil
	// if no such server exists.
	PublicAddress(svc addr.SVC, name string) *net.UDPAddr

	// Anycast returns the address for an arbitrary server of the requested type.
	Anycast(svc addr.SVC) (*net.UDPAddr, error)
	// Multicast returns all addresses for the requested type.
	Multicast(svc addr.SVC) ([]*net.UDPAddr, error)

	// UnderlayAnycast returns the underlay address for an arbitrary server of the requested type.
	UnderlayAnycast(svc addr.SVC) (*net.UDPAddr, error)
	// UnderlayMulticast returns all underlay addresses for the requested type.
	UnderlayMulticast(svc addr.SVC) ([]*net.UDPAddr, error)
	// UnderlayNextHop returns the internal underlay address of the router
	// containing the interface ID.
	UnderlayNextHop(ifID iface.ID) (*net.UDPAddr, bool)

	// MakeHostInfos returns the underlay addresses of all services for the specified service type.
	MakeHostInfos(st ServiceType) ([]*net.UDPAddr, error)

	// Gateways returns an array of all gateways.
	Gateways() ([]GatewayInfo, error)

	// BR returns information for a specific border router
	//
	// FIXME(scrye): Simplify return type and make it topology format agnostic.
	//
	// XXX(scrye): Return value is a shallow copy.
	BR(name string) (BRInfo, bool)
	// IFInfoMap returns the mapping between interface IDs an internal addresses.
	//
	// FIXME(scrye): Simplify return type and make it topology format agnostic.
	//
	// XXX(scrye): Return value is a shallow copy.
	IFInfoMap() IfInfoMap

	// SVCNames returns the names of all servers in the topology for the specified service.
	//
	// FIXME(scrye): Remove this, callers shouldn't care about names.
	//
	// XXX(scrye): Return value is a shallow copy.
	SVCNames(svc addr.SVC) ServiceNames

	// Writable returns a pointer to the underlying topology object. This is included for legacy
	// reasons and should never be used.
	//
	// FIXME(scrye): Remove this.
	//
	// XXX(scrye): Return value is a shallow copy.
	Writable() *RWTopology
}

Topology is the topology type for applications and libraries that only need read access to AS topology information. This is the case of most applications and libraries that use the topology file to discover information about the local AS. Libraries that need to edit the topology (e.g., a topology reloading library that computes a new topology file based on information found on disk) should instead use the writable topology type present in this package.

func FromJSONBytes

func FromJSONBytes(raw []byte) (Topology, error)

func FromJSONFile

func FromJSONFile(path string) (Topology, error)

FromJSONFile extracts the topology from a file containing the JSON representation of the topology.

func FromRWTopology

func FromRWTopology(topo *RWTopology) Topology

FromRWTopology wraps the high level topology interface API around a raw topology object.

func NewTopology

func NewTopology() Topology

NewTopology creates a new empty topology.

type Validator

type Validator interface {
	// Validate checks that the topology update is valid. Note that old might be
	// nil.
	Validate(new, old *RWTopology) error
}

Validator is used to validate that the topology update is permissible.

Directories

Path Synopsis
Package json encodes AS topology information via JSON.
Package json encodes AS topology information via JSON.
Package mock_topology is a generated GoMock package.
Package mock_topology is a generated GoMock package.

Jump to

Keyboard shortcuts

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