mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
tstest/natlab: bit more of in-memory network testing package
Pairing with @danderson
This commit is contained in:
parent
23c93da942
commit
bb1a9e4700
@ -30,16 +30,39 @@ type PacketConner interface {
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
name string
|
||||
dhcpPool netaddr.IPPrefix
|
||||
alloced map[netaddr.IP]bool
|
||||
|
||||
pushRoute netaddr.IPPrefix
|
||||
}
|
||||
|
||||
func (n *Network) write(p []byte, dst, src netaddr.IPPort) (num int, err error) {
|
||||
panic("TODO")
|
||||
}
|
||||
|
||||
type iface struct {
|
||||
net *Network
|
||||
up bool
|
||||
ips []netaddr.IP
|
||||
net *Network
|
||||
name string // optional
|
||||
ips []netaddr.IP // static; not mutated once created
|
||||
}
|
||||
|
||||
func (f *iface) String() string {
|
||||
// TODO: make this all better
|
||||
if f.name != "" {
|
||||
return f.name
|
||||
}
|
||||
return fmt.Sprintf("unamed-interface-on-network-%p", f.net)
|
||||
}
|
||||
|
||||
// Contains reports whether f contains ip as an IP.
|
||||
func (f *iface) Contains(ip netaddr.IP) bool {
|
||||
for _, v := range f.ips {
|
||||
if ip == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type routeEntry struct {
|
||||
@ -57,6 +80,39 @@ type Machine struct {
|
||||
conns map[netaddr.IPPort]*conn
|
||||
}
|
||||
|
||||
var (
|
||||
v4unspec = netaddr.IPv4(0, 0, 0, 0)
|
||||
v6unspec = netaddr.IPv6Unspecified()
|
||||
)
|
||||
|
||||
func (m *Machine) writePacket(p []byte, dst, src netaddr.IPPort) (n int, err error) {
|
||||
iface, err := m.interfaceForIP(dst.IP)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
unspec := src.IP == v4unspec || src.IP == v6unspec
|
||||
if unspec {
|
||||
// TODO: pick a src IP
|
||||
} else {
|
||||
if !iface.Contains(src.IP) {
|
||||
return 0, fmt.Errorf("can't send to %v with src %v on interface %v", dst.IP, src.IP, iface)
|
||||
}
|
||||
}
|
||||
|
||||
return iface.net.write(p, dst, src)
|
||||
}
|
||||
|
||||
func (m *Machine) interfaceForIP(ip netaddr.IP) (*iface, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
for _, re := range m.routes {
|
||||
if re.prefix.Contains(ip) {
|
||||
return re.iface, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("no route found to %v", ip)
|
||||
}
|
||||
|
||||
func (m *Machine) hasv6() bool {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
@ -213,7 +269,11 @@ func (c *conn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
}
|
||||
|
||||
func (c *conn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
panic("TODO")
|
||||
ipp, err := netaddr.ParseIPPort(addr.String())
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("bogus addr %T %q", addr, addr.String())
|
||||
}
|
||||
return c.m.writePacket(p, ipp, c.ipp)
|
||||
}
|
||||
|
||||
func (c *conn) SetDeadline(t time.Time) error {
|
||||
|
Loading…
Reference in New Issue
Block a user