netstack: introduce new module for gvisor tcp tun adapter
The Go linker isn't smart enough to prevent gvisor from being pulled into modules that use other parts of tun/, due to the types exposed. So, we put this into its own standalone module. We use this as an opportunity to introduce some example code as well. I'm still not happy that this not only clutters this repo's go.sum, but all the other projects that consume it, but it seems like making a new module inside of this repo will lead to even greater confusion. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
		
							parent
							
								
									294d3bedf9
								
							
						
					
					
						commit
						1d4eb2727a
					
				
							
								
								
									
										50
									
								
								tun/netstack/examples/http_client.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								tun/netstack/examples/http_client.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
			
		||||
// +build ignore
 | 
			
		||||
 | 
			
		||||
/* SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"golang.zx2c4.com/wireguard/device"
 | 
			
		||||
	"golang.zx2c4.com/wireguard/tun/netstack"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	tun, tnet, err := netstack.CreateNetTUN(
 | 
			
		||||
		[]net.IP{net.ParseIP("192.168.4.29")},
 | 
			
		||||
		[]net.IP{net.ParseIP("8.8.8.8")},
 | 
			
		||||
		1420)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	dev := device.NewDevice(tun, &device.Logger{log.Default(), log.Default(), log.Default()})
 | 
			
		||||
	dev.IpcSet(`private_key=a8dac1d8a70a751f0f699fb14ba1cff7b79cf4fbd8f09f44c6e6a90d0369604f
 | 
			
		||||
public_key=25123c5dcd3328ff645e4f2a3fce0d754400d3887a0cb7c56f0267e20fbf3c5b
 | 
			
		||||
endpoint=163.172.161.0:12912
 | 
			
		||||
allowed_ip=0.0.0.0/0
 | 
			
		||||
`)
 | 
			
		||||
	dev.Up()
 | 
			
		||||
 | 
			
		||||
	client := http.Client{
 | 
			
		||||
		Transport: &http.Transport{
 | 
			
		||||
			DialContext: tnet.DialContext,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	resp, err := client.Get("https://www.zx2c4.com/ip")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	body, err := io.ReadAll(resp.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	log.Println(string(body))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								tun/netstack/examples/http_server.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tun/netstack/examples/http_server.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
			
		||||
// +build ignore
 | 
			
		||||
 | 
			
		||||
/* SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"golang.zx2c4.com/wireguard/device"
 | 
			
		||||
	"golang.zx2c4.com/wireguard/tun/netstack"
 | 
			
		||||
	"io"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	tun, tnet, err := netstack.CreateNetTUN(
 | 
			
		||||
		[]net.IP{net.ParseIP("192.168.4.29")},
 | 
			
		||||
		[]net.IP{net.ParseIP("8.8.8.8"), net.ParseIP("8.8.4.4")},
 | 
			
		||||
		1420,
 | 
			
		||||
	)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	dev := device.NewDevice(tun, &device.Logger{log.Default(), log.Default(), log.Default()})
 | 
			
		||||
	dev.IpcSet(`private_key=a8dac1d8a70a751f0f699fb14ba1cff7b79cf4fbd8f09f44c6e6a90d0369604f
 | 
			
		||||
public_key=25123c5dcd3328ff645e4f2a3fce0d754400d3887a0cb7c56f0267e20fbf3c5b
 | 
			
		||||
endpoint=163.172.161.0:12912
 | 
			
		||||
allowed_ip=0.0.0.0/0
 | 
			
		||||
persistent_keepalive_interval=25
 | 
			
		||||
    `)
 | 
			
		||||
	dev.Up()
 | 
			
		||||
	listener, err := tnet.ListenTCP(&net.TCPAddr{Port: 80})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Panicln(err)
 | 
			
		||||
	}
 | 
			
		||||
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
 | 
			
		||||
		log.Printf("> %s - %s - %s", request.RemoteAddr, request.URL.String(), request.UserAgent())
 | 
			
		||||
		io.WriteString(writer, "Hello from userspace TCP!")
 | 
			
		||||
	})
 | 
			
		||||
	err = http.Serve(listener, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Panicln(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
 * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package tun
 | 
			
		||||
package netstack
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
@ -18,6 +18,8 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"golang.zx2c4.com/wireguard/tun"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/net/dns/dnsmessage"
 | 
			
		||||
	"gvisor.dev/gvisor/pkg/tcpip"
 | 
			
		||||
	"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
 | 
			
		||||
@ -33,7 +35,7 @@ import (
 | 
			
		||||
type netTun struct {
 | 
			
		||||
	stack          *stack.Stack
 | 
			
		||||
	dispatcher     stack.NetworkDispatcher
 | 
			
		||||
	events         chan Event
 | 
			
		||||
	events         chan tun.Event
 | 
			
		||||
	incomingPacket chan buffer.VectorisedView
 | 
			
		||||
	mtu            int
 | 
			
		||||
	dnsServers     []net.IP
 | 
			
		||||
@ -88,7 +90,7 @@ func (*endpoint) ARPHardwareType() header.ARPHardwareType {
 | 
			
		||||
func (e *endpoint) AddHeader(local, remote tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func CreateNetTUN(localAddresses []net.IP, dnsServers []net.IP, mtu int) (Device, *Net, error) {
 | 
			
		||||
func CreateNetTUN(localAddresses []net.IP, dnsServers []net.IP, mtu int) (tun.Device, *Net, error) {
 | 
			
		||||
	opts := stack.Options{
 | 
			
		||||
		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
 | 
			
		||||
		TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol},
 | 
			
		||||
@ -96,7 +98,7 @@ func CreateNetTUN(localAddresses []net.IP, dnsServers []net.IP, mtu int) (Device
 | 
			
		||||
	}
 | 
			
		||||
	dev := &netTun{
 | 
			
		||||
		stack:          stack.New(opts),
 | 
			
		||||
		events:         make(chan Event, 10),
 | 
			
		||||
		events:         make(chan tun.Event, 10),
 | 
			
		||||
		incomingPacket: make(chan buffer.VectorisedView),
 | 
			
		||||
		dnsServers:     dnsServers,
 | 
			
		||||
		mtu:            mtu,
 | 
			
		||||
@ -127,7 +129,7 @@ func CreateNetTUN(localAddresses []net.IP, dnsServers []net.IP, mtu int) (Device
 | 
			
		||||
		dev.stack.AddRoute(tcpip.Route{Destination: header.IPv6EmptySubnet, NIC: 1})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev.events <- EventUp
 | 
			
		||||
	dev.events <- tun.EventUp
 | 
			
		||||
	return dev, (*Net)(dev), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -139,7 +141,7 @@ func (tun *netTun) File() *os.File {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (tun *netTun) Events() chan Event {
 | 
			
		||||
func (tun *netTun) Events() chan tun.Event {
 | 
			
		||||
	return tun.events
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user