router

package
v0.0.12 Latest Latest
Warning

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

Go to latest
Published: Mar 5, 2025 License: Apache-2.0 Imports: 35 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AARPMachine

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

AARPMachine maintains both an Address Mapping Table and handles AARP packets (sending and receiving requests, responses, and probes). This process assumes a particular network range rather than using the startup range, since this program is a seed router.

func NewAARPMachine

func NewAARPMachine(port *EtherTalkPort, myHWAddr ethernet.Addr) *AARPMachine

NewAARPMachine creates a new AARPMachine.

func (*AARPMachine) Address

func (a *AARPMachine) Address() (aarp.AddrPair, bool)

Address returns the address of this node, and reports if the address is valid (i.e. not tentative).

func (*AARPMachine) Assigned

func (a *AARPMachine) Assigned() <-chan struct{}

Assigned returns a channel that is closed when the local address is valid.

func (AARPMachine) Dump

func (t AARPMachine) Dump() map[ddp.Addr]AMTEntry

Dump returns a copy of the table at a point in time.

func (*AARPMachine) Handle

func (a *AARPMachine) Handle(ctx context.Context, pkt *ethertalk.Packet)

Handle handles a packet.

func (AARPMachine) Learn

func (t AARPMachine) Learn(ddpAddr ddp.Addr, hwAddr ethernet.Addr)

Learn adds or updates an AMT entry.

func (*AARPMachine) Resolve

func (a *AARPMachine) Resolve(ctx context.Context, ddpAddr ddp.Addr) (ethernet.Addr, error)

Resolve resolves an AppleTalk node address to an Ethernet address. If the address is in the cache (AMT) and is still valid, that is used. Otherwise, the address is resolved using AARP.

func (*AARPMachine) Run

func (a *AARPMachine) Run(ctx context.Context) error

Run executes the machine.

type AMTEntry

type AMTEntry struct {
	// The hardware address that the entry maps to.
	HWAddr ethernet.Addr

	// The last time this entry was updated.
	LastUpdated time.Time

	// Whether the address is being resolved.
	Resolving bool
	// contains filtered or unexported fields
}

AMTEntry is an entry in an address mapping table.

func (AMTEntry) LastUpdatedAgo

func (e AMTEntry) LastUpdatedAgo() string

LastUpdatedAgo is a friendly string reporting how long ago the entry was updated/resolved.

func (AMTEntry) Valid

func (e AMTEntry) Valid() bool

Valid reports if the entry is valid.

type AURPPeer

type AURPPeer struct {
	// AURP-Tr state for producing packets.
	Transport *aurp.Transport

	// Connection to reply to packets on.
	UDPConn *net.UDPConn

	// The string that appeared in the config file / peer list file.
	// May be empty if this peer was not configured (it connected to us, with
	// open_peering enabled).
	ConfiguredAddr string

	// The resolved address of the peer.
	// NOTE: The UDP port is always assumed to be 387.
	RemoteAddr net.IP

	// Incoming packet channel.
	ReceiveCh chan aurp.Packet

	// Route table (the peer will add/remove/update routes and zones)
	RouteTable *RouteTable
	// contains filtered or unexported fields
}

AURPPeer handles the peering with a peer AURP router.

func NewAURPPeer

func NewAURPPeer(routes *RouteTable, udpConn *net.UDPConn, peerAddr string, raddr net.IP, localDI, remoteDI aurp.DomainIdentifier, connID uint16) *AURPPeer

func (*AURPPeer) BestNetworkChanged added in v0.0.12

func (p *AURPPeer) BestNetworkChanged(oldBest, newBest Route)

BestNetworkChanged implements RouteTableObserver.

func (*AURPPeer) Class added in v0.0.12

func (p *AURPPeer) Class() TargetClass

Class returns TargetClassAURPPeer.

func (*AURPPeer) Forward

func (p *AURPPeer) Forward(_ context.Context, ddpkt *ddp.ExtPacket) error

Forward encapsulates the DDP packet in an AURP AppleTalkPacket and sends it to the remote peer router.

func (*AURPPeer) Handle

func (p *AURPPeer) Handle(ctx context.Context) error

func (*AURPPeer) LastHeardFromAgo

func (p *AURPPeer) LastHeardFromAgo() string

func (*AURPPeer) LastReconnectAgo

func (p *AURPPeer) LastReconnectAgo() string

func (*AURPPeer) LastSendAgo

func (p *AURPPeer) LastSendAgo() string

func (*AURPPeer) LastUpdateAgo

func (p *AURPPeer) LastUpdateAgo() string

func (*AURPPeer) NetworkAdded added in v0.0.12

func (p *AURPPeer) NetworkAdded(newBest Route)

NetworkAdded implements RouteTableObserver.

func (*AURPPeer) NetworkDeleted added in v0.0.12

func (p *AURPPeer) NetworkDeleted(oldBest Route)

NetworkDeleted implements RouteTableObserver.

func (*AURPPeer) ReceiverState

func (p *AURPPeer) ReceiverState() ReceiverState

func (*AURPPeer) RouteTargetKey added in v0.0.9

func (p *AURPPeer) RouteTargetKey() string

RouteTargetKey returns "AURPPeer|peer's IP address".

func (*AURPPeer) SendRetries

func (p *AURPPeer) SendRetries() int

func (*AURPPeer) SenderState

func (p *AURPPeer) SenderState() SenderState

func (*AURPPeer) String added in v0.0.9

func (p *AURPPeer) String() string

type Config

type Config struct {
	// ListenPort is the AURP service port. Optional: default is 387.
	ListenPort uint16 `yaml:"listen_port"`

	// MonitoringAddr is used for hosting /status server and /metrics.
	// Example: ":9459" (listen on port 9459 on all interfaces).
	// Optional: when left empty, the monitoring HTTP server is disabled.
	MonitoringAddr string `yaml:"monitoring_addr"`

	// LocalIP configures the Domain Identifier used by this router.
	// Note: this does not "bind" the IP side of the router to a particular
	// interface; it will listen on all interfaces with IP addresses.
	// Optional: defaults to the first global unicast address on any local
	// network interface.
	LocalIP string `yaml:"local_ip"`

	// EtherTalk is required for routing one or more local EtherTalk networks.
	EtherTalk EtherTalkConfigs `yaml:"ethertalk"`

	// OpenPeering allowsrouters other than those listed under peers.
	OpenPeering bool `yaml:"open_peering"`

	// Peers sets a list of peer routers to connect to and allow connections
	// from.
	Peers []string `yaml:"peers"`

	// PeerListURL sets a URL to fetch a list of peers from (plain text, one
	// peer per line).
	PeerListURL string `yaml:"peerlist_url"`
}

func LoadConfig

func LoadConfig(cfgPath string) (*Config, error)

type EtherTalkConfig added in v0.0.7

type EtherTalkConfig struct {
	// EthAddr overrides the hardware address used by jrouter. Optional.
	EthAddr string `yaml:"ethernet_addr"`

	// Device is the Ethernet device name (e.g. eth0, enp2s0, en3). Required.
	Device string `yaml:"device"`

	// ZoneName is the AppleTalk zone name for the network on this interface.
	// Required.
	ZoneName string `yaml:"zone_name"`

	// NetStart and NetEnd control the network number range for the AppleTalk
	// network on this interface (inclusive). Required.
	NetStart ddp.Network `yaml:"net_start"`
	NetEnd   ddp.Network `yaml:"net_end"`
}

EtherTalkConfig configures EtherTalk for a specific Ethernet interface.

type EtherTalkConfigs added in v0.0.7

type EtherTalkConfigs []*EtherTalkConfig

func (*EtherTalkConfigs) UnmarshalYAML added in v0.0.7

func (cs *EtherTalkConfigs) UnmarshalYAML(n *yaml.Node) error

type EtherTalkPeer

type EtherTalkPeer struct {
	Port     *EtherTalkPort
	PeerAddr ddp.Addr
}

EtherTalkPeer holds data needed to forward packets to another router on the EtherTalk network.

func (*EtherTalkPeer) Class added in v0.0.12

func (p *EtherTalkPeer) Class() TargetClass

Class returns TargetClassAppleTalkPeer.

func (*EtherTalkPeer) Forward

func (p *EtherTalkPeer) Forward(ctx context.Context, pkt *ddp.ExtPacket) error

Forward forwards a DDP packet to the next router.

func (*EtherTalkPeer) RouteTargetKey added in v0.0.9

func (p *EtherTalkPeer) RouteTargetKey() string

RouteTargetKey returns "EtherTalkPeer|device name|peer address".

func (*EtherTalkPeer) String added in v0.0.9

func (p *EtherTalkPeer) String() string

type EtherTalkPort

type EtherTalkPort struct {
	Device          string
	EthernetAddr    ethernet.Addr
	NetStart        ddp.Network
	NetEnd          ddp.Network
	MyAddr          ddp.Addr
	DefaultZoneName string
	AvailableZones  StringSet
	PcapHandle      *pcap.Handle
	AARPMachine     *AARPMachine
	Router          *Router
}

EtherTalkPort is all the data and helpers needed for EtherTalk on one port.

func (*EtherTalkPort) Broadcast

func (port *EtherTalkPort) Broadcast(pkt *ddp.ExtPacket) error

Broadcast broadcasts the DDP packet on this port.

func (*EtherTalkPort) Class added in v0.0.12

func (port *EtherTalkPort) Class() TargetClass

Class returns TargetClassDirect.

func (*EtherTalkPort) Forward added in v0.0.9

func (port *EtherTalkPort) Forward(ctx context.Context, pkt *ddp.ExtPacket) error

Forward is another name for Send. (EtherTalk ports can be used as a route target.)

func (*EtherTalkPort) HandleNBP

func (port *EtherTalkPort) HandleNBP(ctx context.Context, ddpkt *ddp.ExtPacket) error

func (*EtherTalkPort) HandleRTMP

func (port *EtherTalkPort) HandleRTMP(ctx context.Context, pkt *ddp.ExtPacket) error

RTMPMachine implements RTMP on an AppleTalk network attached to the router.

func (*EtherTalkPort) HandleZIP

func (port *EtherTalkPort) HandleZIP(ctx context.Context, ddpkt *ddp.ExtPacket) error

func (*EtherTalkPort) RouteTargetKey added in v0.0.9

func (port *EtherTalkPort) RouteTargetKey() string

RouteTargetKey returns "EtherTalkPort|device name".

func (*EtherTalkPort) RunRTMP

func (port *EtherTalkPort) RunRTMP(ctx context.Context) (err error)

RunRTMP makes periodic RTMP Data broadcasts on this port.

func (*EtherTalkPort) Send

func (port *EtherTalkPort) Send(ctx context.Context, pkt *ddp.ExtPacket) error

Send sends a DDP packet out this port to the destination node. If pkt.DstNode = 0xFF, then the packet is broadcast.

func (*EtherTalkPort) Serve

func (port *EtherTalkPort) Serve(ctx context.Context)

Serve runs a loop that reads AARP or AppleTalk packets from the network device, and handles them.

func (*EtherTalkPort) String added in v0.0.9

func (port *EtherTalkPort) String() string

func (*EtherTalkPort) ZoneMulticast

func (port *EtherTalkPort) ZoneMulticast(zone string, pkt *ddp.ExtPacket) error

ZoneMulticast broadcasts the DDP packet to a zone multicast hwaddr. The specific address used is computed from the zone name.

type ReceiverState

type ReceiverState int
const (
	ReceiverUnconnected ReceiverState = iota
	ReceiverConnected
	ReceiverWaitForOpenRsp
	ReceiverWaitForRIRsp
	ReceiverWaitForTickleAck
)

func (ReceiverState) String

func (rs ReceiverState) String() string

type Route

type Route struct {
	RouteKey // embeds TargetKey and NetStart

	Extended bool
	NetEnd   ddp.Network

	// Target provides a way to forward packets using this route
	Target RouteTarget

	Distance uint8
	LastSeen time.Time
	// contains filtered or unexported fields
}

Route represents a route: a destination network range, a way to send packets towards the destination, and some other data that affects whether the route is used.

func (Route) LastSeenAgo

func (r Route) LastSeenAgo() string

func (Route) Valid

func (r Route) Valid() bool

Valid reports whether the route is valid. A valid route has a target, one or more zone names, and if it is learned from an AppleTalk router, the last data update is not too old.

func (Route) Zero added in v0.0.12

func (r Route) Zero() bool

Zero reports whether the route is a zero value for Route (trivially invalid).

func (Route) ZoneNames

func (r Route) ZoneNames() []string

ZoneNames returns the zone names for the network associated with this route.

type RouteKey added in v0.0.9

type RouteKey struct {
	TargetKey string
	NetStart  ddp.Network
}

RouteKey is a comparable struct for identifying a specific route. A route can be specified by the target and the start of the network range.

type RouteTable

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

RouteTable is an in-memory database of routes.

func NewRouteTable

func NewRouteTable() *RouteTable

NewRouteTable initialises a new empty route table.

func (*RouteTable) AddObserver

func (rt *RouteTable) AddObserver(obs RouteTableObserver)

AddObserver adds a route table observer.

func (*RouteTable) AddZonesToNetwork

func (rt *RouteTable) AddZonesToNetwork(n ddp.Network, zs ...string) error

AddZonesToRoute adds zone names to the network.

func (*RouteTable) AllZoneNames

func (rt *RouteTable) AllZoneNames() []string

AllZoneNames returns all zone names known to the router having at least one valid route. This is used by the ZIP GetZoneList function.

func (*RouteTable) DeleteRoute added in v0.0.9

func (rt *RouteTable) DeleteRoute(target RouteTarget, netStart ddp.Network) error

DeleteRoute deletes the route specified by the (target, netStart) tuple.

func (*RouteTable) DeleteTarget added in v0.0.9

func (rt *RouteTable) DeleteTarget(target RouteTarget)

DeleteTarget deletes the route target and all its routes.

func (*RouteTable) Dump

func (rt *RouteTable) Dump() (allRoutes []Route)

Dump returns all routes in the table.

func (*RouteTable) Lookup added in v0.0.9

func (rt *RouteTable) Lookup(network ddp.Network) Route

Lookup returns the best valid route for the network number. If there is no valid route, the zero Route is returned (it will have nil Target).

func (*RouteTable) RemoveObserver

func (rt *RouteTable) RemoveObserver(obs RouteTableObserver)

RemoveObserver removes a route table observer.

func (*RouteTable) RoutesForZone

func (rt *RouteTable) RoutesForZone(zone string) []Route

RoutesForZone returns best routes for the zone name. (Zones can span multiple different networks.) This is used for handling NBP BrRq.

func (*RouteTable) UpdateDistance added in v0.0.12

func (rt *RouteTable) UpdateDistance(target RouteTarget, netStart ddp.Network, distance uint8) error

UpdateDistance updates the distance for an existing route.

func (*RouteTable) UpsertRoute added in v0.0.9

func (rt *RouteTable) UpsertRoute(target RouteTarget, extended bool, netStart, netEnd ddp.Network, metric uint8) (Route, error)

UpsertRoute inserts a new route or updates an existing route. It always returns a new Route.

func (*RouteTable) ValidRoutes

func (rt *RouteTable) ValidRoutes(yield func(Route) bool)

ValidRoutes yields all valid routes.

func (*RouteTable) ValidRoutesForClass added in v0.0.12

func (rt *RouteTable) ValidRoutesForClass(class TargetClass) iter.Seq[Route]

ValidRoutesForClass returns an iterator that yields all valid routes for a given target class.

func (*RouteTable) ZonesForNetworks

func (rt *RouteTable) ZonesForNetworks(networks []ddp.Network) map[ddp.Network][]string

ZonesForNetworks returns a map of network numbers to zone names in each. It only considers valid routes.

type RouteTableObserver

type RouteTableObserver interface {
	// NetworkAdded is called when a network becomes routable.
	NetworkAdded(best Route)

	// NetworkDeleted is called when a network becomes _un_routable.
	NetworkDeleted(oldBest Route)

	// BestNetworkChanged is called when the best routing distance
	// or route for a network has changed (from e.g. a direct EtherTalk
	// connection to an AURP peer).
	BestNetworkChanged(from, to Route)
}

RouteTableObserver implementations can receive notifications of route table changes. (TODO, not yet implemented)

type RouteTarget added in v0.0.9

type RouteTarget interface {
	// Forward should send the packet to the route target.
	Forward(context.Context, *ddp.ExtPacket) error

	// Class returns the target class for this target.
	Class() TargetClass

	// RouteTargetKey is used for determining if two targets are the same.
	RouteTargetKey() string
}

RouteTarget implementations can forward packets somewhere.

type Router

type Router struct {
	Config     *Config
	RouteTable *RouteTable
	Ports      []*EtherTalkPort
}

func (*Router) Forward

func (rtr *Router) Forward(ctx context.Context, ddpkt *ddp.ExtPacket) error

Forward increments the hop count, then outputs the packet in the direction of the destination.

func (*Router) HandleAEP

func (rtr *Router) HandleAEP(ctx context.Context, ddpkt *ddp.ExtPacket) error

func (*Router) HandleNBPFromAURP

func (rtr *Router) HandleNBPFromAURP(ctx context.Context, ddpkt *ddp.ExtPacket) error

func (*Router) Output

func (rtr *Router) Output(ctx context.Context, ddpkt *ddp.ExtPacket) error

Output outputs the packet in the direction of the destination. (It does not check or adjust the hop count.)

type SenderState

type SenderState int
const (
	SenderUnconnected SenderState = iota
	SenderConnected
	SenderWaitForRIRspAck
	SenderWaitForRIUpdAck
	SenderWaitForRDAck
)

func (SenderState) String

func (ss SenderState) String() string

type StringSet

type StringSet map[string]struct{}

StringSet is a set of strings. Yep, yet another string set implementation. Took me 2 minutes to write *shrug*

func SetFromSlice

func SetFromSlice(ss []string) StringSet

func (StringSet) Add

func (set StringSet) Add(t StringSet)

func (StringSet) Contains

func (set StringSet) Contains(s string) bool

func (StringSet) Insert

func (set StringSet) Insert(ss ...string)

func (StringSet) ToSlice

func (set StringSet) ToSlice() []string

type TargetClass added in v0.0.12

type TargetClass int

TargetClass is an enum type for representing the broad classes of route targets.

const (
	TargetClassDirect        TargetClass = iota // directly attached EtherTalk / LocalTalk / etc network
	TargetClassAURPPeer                         // another router over AURP
	TargetClassAppleTalkPeer                    // another router via EtherTalk / LocalTalk / etc
	TargetClassCount                            // how many valid target types there are - insert new classes above.
)

Target class values.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
JackTT - Gopher 🇻🇳