Browse Source

net/tstun: rename TUN to Wrapper.

The tstun packagen contains both constructors for generic tun
Devices, and a wrapper that provides additional functionality.

Signed-off-by: David Anderson <[email protected]>
David Anderson 5 years ago
parent
commit
016de16b2e

+ 35 - 38
net/tstun/wrap.go

@@ -31,11 +31,11 @@ const maxBufferSize = device.MaxMessageSize
 const PacketStartOffset = device.MessageTransportHeaderSize
 
 // MaxPacketSize is the maximum size (in bytes)
-// of a packet that can be injected into a tstun.TUN.
+// of a packet that can be injected into a tstun.Wrapper.
 const MaxPacketSize = device.MaxContentSize
 
 var (
-	// ErrClosed is returned when attempting an operation on a closed TUN.
+	// ErrClosed is returned when attempting an operation on a closed Wrapper.
 	ErrClosed = errors.New("device closed")
 	// ErrFiltered is returned when the acted-on packet is rejected by a filter.
 	ErrFiltered = errors.New("packet dropped by filter")
@@ -52,17 +52,14 @@ var (
 // do not escape through {Pre,Post}Filter{In,Out}.
 var parsedPacketPool = sync.Pool{New: func() interface{} { return new(packet.Parsed) }}
 
-// FilterFunc is a packet-filtering function with access to the TUN device.
+// FilterFunc is a packet-filtering function with access to the Wrapper device.
 // It must not hold onto the packet struct, as its backing storage will be reused.
-type FilterFunc func(*packet.Parsed, *TUN) filter.Response
+type FilterFunc func(*packet.Parsed, *Wrapper) filter.Response
 
-// TUN wraps a tun.Device from wireguard-go,
-// augmenting it with filtering and packet injection.
-// All the added work happens in Read and Write:
-// the other methods delegate to the underlying tdev.
-type TUN struct {
+// Wrapper augments a tun.Device with packet filtering and injection.
+type Wrapper struct {
 	logf logger.Logf
-	// tdev is the underlying TUN device.
+	// tdev is the underlying Wrapper device.
 	tdev tun.Device
 
 	closeOnce sync.Once
@@ -116,8 +113,8 @@ type TUN struct {
 	disableFilter bool
 }
 
-func WrapTUN(logf logger.Logf, tdev tun.Device) *TUN {
-	tun := &TUN{
+func Wrap(logf logger.Logf, tdev tun.Device) *Wrapper {
+	tun := &Wrapper{
 		logf: logger.WithPrefix(logf, "tstun: "),
 		tdev: tdev,
 		// bufferConsumed is conceptually a condition variable:
@@ -140,12 +137,12 @@ func WrapTUN(logf logger.Logf, tdev tun.Device) *TUN {
 // SetDestIPActivityFuncs sets a map of funcs to run per packet
 // destination (the map keys).
 //
-// The map ownership passes to the TUN. It must be non-nil.
-func (t *TUN) SetDestIPActivityFuncs(m map[netaddr.IP]func()) {
+// The map ownership passes to the Wrapper. It must be non-nil.
+func (t *Wrapper) SetDestIPActivityFuncs(m map[netaddr.IP]func()) {
 	t.destIPActivity.Store(m)
 }
 
-func (t *TUN) Close() error {
+func (t *Wrapper) Close() error {
 	var err error
 	t.closeOnce.Do(func() {
 		// Other channels need not be closed: poll will exit gracefully after this.
@@ -156,30 +153,30 @@ func (t *TUN) Close() error {
 	return err
 }
 
-func (t *TUN) Events() chan tun.Event {
+func (t *Wrapper) Events() chan tun.Event {
 	return t.tdev.Events()
 }
 
-func (t *TUN) File() *os.File {
+func (t *Wrapper) File() *os.File {
 	return t.tdev.File()
 }
 
-func (t *TUN) Flush() error {
+func (t *Wrapper) Flush() error {
 	return t.tdev.Flush()
 }
 
-func (t *TUN) MTU() (int, error) {
+func (t *Wrapper) MTU() (int, error) {
 	return t.tdev.MTU()
 }
 
-func (t *TUN) Name() (string, error) {
+func (t *Wrapper) Name() (string, error) {
 	return t.tdev.Name()
 }
 
 // poll polls t.tdev.Read, placing the oldest unconsumed packet into t.buffer.
 // This is needed because t.tdev.Read in general may block (it does on Windows),
 // so packets may be stuck in t.outbound if t.Read called t.tdev.Read directly.
-func (t *TUN) poll() {
+func (t *Wrapper) poll() {
 	for {
 		select {
 		case <-t.closed:
@@ -189,7 +186,7 @@ func (t *TUN) poll() {
 		}
 
 		// Read may use memory in t.buffer before PacketStartOffset for mandatory headers.
-		// This is the rationale behind the tun.TUN.{Read,Write} interfaces
+		// This is the rationale behind the tun.Wrapper.{Read,Write} interfaces
 		// and the reason t.buffer has size MaxMessageSize and not MaxContentSize.
 		n, err := t.tdev.Read(t.buffer[:], PacketStartOffset)
 		if err != nil {
@@ -221,7 +218,7 @@ func (t *TUN) poll() {
 
 var magicDNSIPPort = netaddr.MustParseIPPort("100.100.100.100:0")
 
-func (t *TUN) filterOut(p *packet.Parsed) filter.Response {
+func (t *Wrapper) filterOut(p *packet.Parsed) filter.Response {
 	// Fake ICMP echo responses to MagicDNS (100.100.100.100).
 	if p.IsEchoRequest() && p.Dst == magicDNSIPPort {
 		header := p.ICMP4Header()
@@ -257,7 +254,7 @@ func (t *TUN) filterOut(p *packet.Parsed) filter.Response {
 }
 
 // noteActivity records that there was a read or write at the current time.
-func (t *TUN) noteActivity() {
+func (t *Wrapper) noteActivity() {
 	atomic.StoreInt64(&t.lastActivityAtomic, time.Now().Unix())
 }
 
@@ -265,12 +262,12 @@ func (t *TUN) noteActivity() {
 //
 // Its value is only accurate to roughly second granularity.
 // If there's never been activity, the duration is since 1970.
-func (t *TUN) IdleDuration() time.Duration {
+func (t *Wrapper) IdleDuration() time.Duration {
 	sec := atomic.LoadInt64(&t.lastActivityAtomic)
 	return time.Since(time.Unix(sec, 0))
 }
 
-func (t *TUN) Read(buf []byte, offset int) (int, error) {
+func (t *Wrapper) Read(buf []byte, offset int) (int, error) {
 	var n int
 
 	wasInjectedPacket := false
@@ -321,7 +318,7 @@ func (t *TUN) Read(buf []byte, offset int) (int, error) {
 	return n, nil
 }
 
-func (t *TUN) filterIn(buf []byte) filter.Response {
+func (t *Wrapper) filterIn(buf []byte) filter.Response {
 	p := parsedPacketPool.Get().(*packet.Parsed)
 	defer parsedPacketPool.Put(p)
 	p.Decode(buf)
@@ -388,7 +385,7 @@ func (t *TUN) filterIn(buf []byte) filter.Response {
 
 // Write accepts an incoming packet. The packet begins at buf[offset:],
 // like wireguard-go/tun.Device.Write.
-func (t *TUN) Write(buf []byte, offset int) (int, error) {
+func (t *Wrapper) Write(buf []byte, offset int) (int, error) {
 	if !t.disableFilter {
 		res := t.filterIn(buf[offset:])
 		if res == filter.DropSilently {
@@ -403,16 +400,16 @@ func (t *TUN) Write(buf []byte, offset int) (int, error) {
 	return t.tdev.Write(buf, offset)
 }
 
-func (t *TUN) GetFilter() *filter.Filter {
+func (t *Wrapper) GetFilter() *filter.Filter {
 	filt, _ := t.filter.Load().(*filter.Filter)
 	return filt
 }
 
-func (t *TUN) SetFilter(filt *filter.Filter) {
+func (t *Wrapper) SetFilter(filt *filter.Filter) {
 	t.filter.Store(filt)
 }
 
-// InjectInboundDirect makes the TUN device behave as if a packet
+// InjectInboundDirect makes the Wrapper device behave as if a packet
 // with the given contents was received from the network.
 // It blocks and does not take ownership of the packet.
 // The injected packet will not pass through inbound filters.
@@ -420,7 +417,7 @@ func (t *TUN) SetFilter(filt *filter.Filter) {
 // The packet contents are to start at &buf[offset].
 // offset must be greater or equal to PacketStartOffset.
 // The space before &buf[offset] will be used by Wireguard.
-func (t *TUN) InjectInboundDirect(buf []byte, offset int) error {
+func (t *Wrapper) InjectInboundDirect(buf []byte, offset int) error {
 	if len(buf) > MaxPacketSize {
 		return errPacketTooBig
 	}
@@ -439,7 +436,7 @@ func (t *TUN) InjectInboundDirect(buf []byte, offset int) error {
 // InjectInboundCopy takes a packet without leading space,
 // reallocates it to conform to the InjectInboundDirect interface
 // and calls InjectInboundDirect on it. Injecting a nil packet is a no-op.
-func (t *TUN) InjectInboundCopy(packet []byte) error {
+func (t *Wrapper) InjectInboundCopy(packet []byte) error {
 	// We duplicate this check from InjectInboundDirect here
 	// to avoid wasting an allocation on an oversized packet.
 	if len(packet) > MaxPacketSize {
@@ -455,7 +452,7 @@ func (t *TUN) InjectInboundCopy(packet []byte) error {
 	return t.InjectInboundDirect(buf, PacketStartOffset)
 }
 
-func (t *TUN) injectOutboundPong(pp *packet.Parsed, req packet.TSMPPingRequest) {
+func (t *Wrapper) injectOutboundPong(pp *packet.Parsed, req packet.TSMPPingRequest) {
 	pong := packet.TSMPPongReply{
 		Data: req.Data,
 	}
@@ -475,12 +472,12 @@ func (t *TUN) injectOutboundPong(pp *packet.Parsed, req packet.TSMPPingRequest)
 	t.InjectOutbound(packet.Generate(pong, nil))
 }
 
-// InjectOutbound makes the TUN device behave as if a packet
+// InjectOutbound makes the Wrapper device behave as if a packet
 // with the given contents was sent to the network.
 // It does not block, but takes ownership of the packet.
 // The injected packet will not pass through outbound filters.
 // Injecting an empty packet is a no-op.
-func (t *TUN) InjectOutbound(packet []byte) error {
+func (t *Wrapper) InjectOutbound(packet []byte) error {
 	if len(packet) > MaxPacketSize {
 		return errPacketTooBig
 	}
@@ -495,7 +492,7 @@ func (t *TUN) InjectOutbound(packet []byte) error {
 	}
 }
 
-// Unwrap returns the underlying TUN device.
-func (t *TUN) Unwrap() tun.Device {
+// Unwrap returns the underlying tun.Device.
+func (t *Wrapper) Unwrap() tun.Device {
 	return t.tdev
 }

+ 8 - 8
net/tstun/wrap_test.go

@@ -106,7 +106,7 @@ func netports(netPorts ...string) (ret []filter.NetPortRange) {
 	return ret
 }
 
-func setfilter(logf logger.Logf, tun *TUN) {
+func setfilter(logf logger.Logf, tun *Wrapper) {
 	protos := []ipproto.Proto{
 		ipproto.TCP,
 		ipproto.UDP,
@@ -120,9 +120,9 @@ func setfilter(logf logger.Logf, tun *TUN) {
 	tun.SetFilter(filter.New(matches, sb.IPSet(), sb.IPSet(), nil, logf))
 }
 
-func newChannelTUN(logf logger.Logf, secure bool) (*tuntest.ChannelTUN, *TUN) {
+func newChannelTUN(logf logger.Logf, secure bool) (*tuntest.ChannelTUN, *Wrapper) {
 	chtun := tuntest.NewChannelTUN()
-	tun := WrapTUN(logf, chtun.TUN())
+	tun := Wrap(logf, chtun.TUN())
 	if secure {
 		setfilter(logf, tun)
 	} else {
@@ -131,9 +131,9 @@ func newChannelTUN(logf logger.Logf, secure bool) (*tuntest.ChannelTUN, *TUN) {
 	return chtun, tun
 }
 
-func newFakeTUN(logf logger.Logf, secure bool) (*fakeTUN, *TUN) {
+func newFakeTUN(logf logger.Logf, secure bool) (*fakeTUN, *Wrapper) {
 	ftun := NewFake()
-	tun := WrapTUN(logf, ftun)
+	tun := Wrap(logf, ftun)
 	if secure {
 		setfilter(logf, tun)
 	} else {
@@ -274,7 +274,7 @@ func TestFilter(t *testing.T) {
 		{"good_packet_out", out, false, udp4("1.2.3.4", "5.6.7.8", 98, 98)},
 	}
 
-	// A reader on the other end of the TUN.
+	// A reader on the other end of the tun.
 	go func() {
 		var recvbuf []byte
 		for {
@@ -377,11 +377,11 @@ func BenchmarkWrite(b *testing.B) {
 }
 
 func TestAtomic64Alignment(t *testing.T) {
-	off := unsafe.Offsetof(TUN{}.lastActivityAtomic)
+	off := unsafe.Offsetof(Wrapper{}.lastActivityAtomic)
 	if off%8 != 0 {
 		t.Errorf("offset %v not 8-byte aligned", off)
 	}
 
-	c := new(TUN)
+	c := new(Wrapper)
 	atomic.StoreInt64(&c.lastActivityAtomic, 123)
 }

+ 2 - 2
wgengine/magicsock/magicsock_test.go

@@ -130,7 +130,7 @@ type magicStack struct {
 	epCh       chan []string       // endpoint updates produced by this peer
 	conn       *Conn               // the magicsock itself
 	tun        *tuntest.ChannelTUN // TUN device to send/receive packets
-	tsTun      *tstun.TUN          // wrapped tun that implements filtering and wgengine hooks
+	tsTun      *tstun.Wrapper      // wrapped tun that implements filtering and wgengine hooks
 	dev        *device.Device      // the wireguard-go Device that connects the previous things
 	wgLogger   *wglog.Logger       // wireguard-go log wrapper
 }
@@ -166,7 +166,7 @@ func newMagicStack(t testing.TB, logf logger.Logf, l nettype.PacketListener, der
 	}
 
 	tun := tuntest.NewChannelTUN()
-	tsTun := tstun.WrapTUN(logf, tun.TUN())
+	tsTun := tstun.Wrap(logf, tun.TUN())
 	tsTun.SetFilter(filter.NewAllowAllForTest(logf))
 
 	wgLogger := wglog.NewLogger(logf)

+ 3 - 3
wgengine/netstack/netstack.go

@@ -48,7 +48,7 @@ const debugNetstack = false
 type Impl struct {
 	ipstack *stack.Stack
 	linkEP  *channel.Endpoint
-	tundev  *tstun.TUN
+	tundev  *tstun.Wrapper
 	e       wgengine.Engine
 	mc      *magicsock.Conn
 	logf    logger.Logf
@@ -61,7 +61,7 @@ const nicID = 1
 const mtu = 1500
 
 // Create creates and populates a new Impl.
-func Create(logf logger.Logf, tundev *tstun.TUN, e wgengine.Engine, mc *magicsock.Conn) (*Impl, error) {
+func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magicsock.Conn) (*Impl, error) {
 	if mc == nil {
 		return nil, errors.New("nil magicsock.Conn")
 	}
@@ -297,7 +297,7 @@ func (ns *Impl) injectOutbound() {
 	}
 }
 
-func (ns *Impl) injectInbound(p *packet.Parsed, t *tstun.TUN) filter.Response {
+func (ns *Impl) injectInbound(p *packet.Parsed, t *tstun.Wrapper) filter.Response {
 	var pn tcpip.NetworkProtocolNumber
 	switch p.IPVersion {
 	case 4:

+ 2 - 2
wgengine/pendopen.go

@@ -66,7 +66,7 @@ func (e *userspaceEngine) noteFlowProblemFromPeer(f flowtrack.Tuple, problem pac
 	of.problem = problem
 }
 
-func (e *userspaceEngine) trackOpenPreFilterIn(pp *packet.Parsed, t *tstun.TUN) (res filter.Response) {
+func (e *userspaceEngine) trackOpenPreFilterIn(pp *packet.Parsed, t *tstun.Wrapper) (res filter.Response) {
 	res = filter.Accept // always
 
 	if pp.IPProto == ipproto.TSMP {
@@ -99,7 +99,7 @@ func (e *userspaceEngine) trackOpenPreFilterIn(pp *packet.Parsed, t *tstun.TUN)
 	return
 }
 
-func (e *userspaceEngine) trackOpenPostFilterOut(pp *packet.Parsed, t *tstun.TUN) (res filter.Response) {
+func (e *userspaceEngine) trackOpenPostFilterOut(pp *packet.Parsed, t *tstun.Wrapper) (res filter.Response) {
 	res = filter.Accept // always
 
 	if pp.IPVersion == 0 ||

+ 7 - 7
wgengine/userspace.go

@@ -80,7 +80,7 @@ type userspaceEngine struct {
 	reqCh             chan struct{}
 	waitCh            chan struct{} // chan is closed when first Close call completes; contrast with closing bool
 	timeNow           func() time.Time
-	tundev            *tstun.TUN
+	tundev            *tstun.Wrapper
 	wgdev             *device.Device
 	router            router.Router
 	resolver          *dns.Resolver
@@ -124,10 +124,10 @@ type userspaceEngine struct {
 
 // InternalsGetter is implemented by Engines that can export their internals.
 type InternalsGetter interface {
-	GetInternals() (*tstun.TUN, *magicsock.Conn)
+	GetInternals() (*tstun.Wrapper, *magicsock.Conn)
 }
 
-func (e *userspaceEngine) GetInternals() (*tstun.TUN, *magicsock.Conn) {
+func (e *userspaceEngine) GetInternals() (*tstun.Wrapper, *magicsock.Conn) {
 	return e.tundev, e.magicConn
 }
 
@@ -184,7 +184,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
 		closePool.add(r)
 	}
 
-	tsTUNDev := tstun.WrapTUN(logf, conf.TUN)
+	tsTUNDev := tstun.Wrap(logf, conf.TUN)
 	closePool.add(tsTUNDev)
 
 	e := &userspaceEngine{
@@ -379,7 +379,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
 }
 
 // echoRespondToAll is an inbound post-filter responding to all echo requests.
-func echoRespondToAll(p *packet.Parsed, t *tstun.TUN) filter.Response {
+func echoRespondToAll(p *packet.Parsed, t *tstun.Wrapper) filter.Response {
 	if p.IsEchoRequest() {
 		header := p.ICMP4Header()
 		header.ToResponse()
@@ -400,7 +400,7 @@ func echoRespondToAll(p *packet.Parsed, t *tstun.TUN) filter.Response {
 // stack, and intercepts any packets that should be handled by
 // tailscaled directly. Other packets are allowed to proceed into the
 // main ACL filter.
-func (e *userspaceEngine) handleLocalPackets(p *packet.Parsed, t *tstun.TUN) filter.Response {
+func (e *userspaceEngine) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper) filter.Response {
 	if verdict := e.handleDNS(p, t); verdict == filter.Drop {
 		// local DNS handled the packet.
 		return filter.Drop
@@ -429,7 +429,7 @@ func (e *userspaceEngine) isLocalAddr(ip netaddr.IP) bool {
 }
 
 // handleDNS is an outbound pre-filter resolving Tailscale domains.
-func (e *userspaceEngine) handleDNS(p *packet.Parsed, t *tstun.TUN) filter.Response {
+func (e *userspaceEngine) handleDNS(p *packet.Parsed, t *tstun.Wrapper) filter.Response {
 	if p.Dst.IP == magicDNSIP && p.Dst.Port == magicDNSPort && p.IPProto == ipproto.UDP {
 		request := dns.Packet{
 			Payload: append([]byte(nil), p.Payload()...),

+ 1 - 1
wgengine/userspace_test.go

@@ -39,7 +39,7 @@ func TestNoteReceiveActivity(t *testing.T) {
 		logf: func(format string, a ...interface{}) {
 			fmt.Fprintf(&logBuf, format, a...)
 		},
-		tundev:                new(tstun.TUN),
+		tundev:                new(tstun.Wrapper),
 		testMaybeReconfigHook: func() { confc <- true },
 		trimmedDisco:          map[tailcfg.DiscoKey]bool{},
 	}