-
Notifications
You must be signed in to change notification settings - Fork 173
Description
The addr.HostAddr
type hierarchy is currently organized around this base interface:
type HostAddr interface {
Size() int
Type() HostAddrType
Pack() []byte
IP() net.IP
Copy() HostAddr
Equal(HostAddr) bool
fmt.Stringer
}
This interface is implemented by the types HostNone
, HostIPv4
, HostIPv6
and HostSVC
.
The Pack
and Size
methods are not really used, as slayers
uses separate serialization logic, based on separate types. The same is true for the HostFromRaw
parsing function.
The slayers
library does not generally use these HostAddr
types. Instead, it relies on net.Addr
with explicit type assertions to net.IPAddr
and addr.HostSVC
. The net.Addr
interface here is merely a convention, none of the interface methods are actually used.
This situation is not ideal:
- creating
HostAddr
always allocates -- this cannot be fixed with the interface type. - the
HostIPv4
/HostIPv6
split is unnecessary as theIP
is already aware of the type HostAddr
is not a value type, cannot be used as map key etc.- different "world" of address types in
slayers
and everywhere else - arbitrarily pretends that
HostSVC
is anet.Addr
Proposal
Replace the HostAddr
type hierarchy with a single value type Host
.
This type is opaque, allowing to internally change or extend the representation.
type Host struct {
ip netaddr.IP
svc SVC // could squeeze this into ip, is it worth it?
t HostAddrType
}
func (h Host) Type() HostAddrType {
return h.t
}
func (h Host) IP() netaddr.IP {
if h.t != HostTypeIP {
panic("IP called on non-IP address")
}
return h.ip
}
func (h Host) SVC() SVC {
if h.t != HostTypeSVC {
panic("SVC called on non-SVC address")
}
return h.svc
}
func (h Host) String() string { ... }
// HostIP creates a Host address of type IP
func HostIP(ip netaddr.IP) Host {
return Host{t: HostTypeIP, ip: ip}
}
// HostIPFromStd is a hopefully temporary conversion function to create a Host of type IP from net.IP.
// Panics if ip does not have length 4 or 16.
// Unmaps IPv6-mapped IPv4 addresses.
func HostIPFromStd(ip net.IP) Host {
a, ok := netaddr.FromStdIP(ip)
if !ok {
panic("invalid ip")
}
return HostIP(a)
}
func HostSVC(svc SVC) Host {
return Host{t: HostTypeSVC, svc: svc}
}
type HostAddrType uint8
const (
HostTypeNone HostAddrType = iota
HostTypeIP // merged IPv4/IPv6
HostTypeSVC
)
// SVC -- renamed from HostSVC, without the HostAddr methods
type SVC uint16
const (
SvcDS SVC = 0x0001
SvcCS SVC = 0x0002
SvcWildcard SVC = 0x0010
SvcNone SVC = 0xffff
SVCMcast SVC = 0x8000
)
This Host
type is adopted in
snet.SCIONAddress
and sosnet.Packet
slayers.SCION
in{Get,Set}{Src,Dst}Addr
, getting rid of internal type assertions
The HostAddressType
enum is used in the dispatcher's "reliable" protocol. To allow combining
HostTypeIPv4
and HostTypeIPv6
without breaking compatibility, the enum is re-defined with the
old values in the dispatcher package.
This allows the router dataplane to use slayers.SCION.GetDstAddr
without allocations.
We do need to introduce a number of conversion from net.IP
to netaddr.IP
-- as we gradually adopt
netaddr.IP
et al (or in the future net/netip.Addr
), these conversions should disappear.