]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
netstack: introduce new module for gvisor tcp tun adapter
authorJason A. Donenfeld <Jason@zx2c4.com>
Wed, 20 Jan 2021 23:02:32 +0000 (00:02 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Wed, 20 Jan 2021 23:16:59 +0000 (00:16 +0100)
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>
tun/netstack/examples/http_client.go [new file with mode: 0644]
tun/netstack/examples/http_server.go [new file with mode: 0644]
tun/netstack/tun.go [moved from tun/tun_net.go with 98% similarity]

diff --git a/tun/netstack/examples/http_client.go b/tun/netstack/examples/http_client.go
new file mode 100644 (file)
index 0000000..2c1f8f4
--- /dev/null
@@ -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))
+}
diff --git a/tun/netstack/examples/http_server.go b/tun/netstack/examples/http_server.go
new file mode 100644 (file)
index 0000000..e627e55
--- /dev/null
@@ -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)
+       }
+}
similarity index 98%
rename from tun/tun_net.go
rename to tun/netstack/tun.go
index 9a6f26f690ed94dd67b0b5ea4df38c65adaf091a..6bdea236d49e28448be9e6b1d7bfbb66875ad9bf 100644 (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
 }