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:
Jason A. Donenfeld 2021-01-21 00:02:32 +01:00
parent 294d3bedf9
commit 1d4eb2727a
3 changed files with 106 additions and 6 deletions

View 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))
}

View 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)
}
}

View file

@ -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
}