Commit graph

259 commits

Author SHA1 Message Date
Jason A. Donenfeld 097af6e135 tun: windows: protect reads from closing
The code previously used the old errors channel for checking, rather
than the simpler boolean, which caused issues on shutdown, since the
errors channel was meaningless. However, looking at this exposed a more
basic problem: Close() and all the other functions that check the closed
boolean can race. So protect with a basic RW lock, to ensure that
Close() waits for all pending operations to complete.

Reported-by: Joshua Sjoding <joshua.sjoding@scjalliance.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-26 22:22:45 -04:00
Jason A. Donenfeld 3625f8d284 tun: freebsd: avoid OOB writes
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-19 15:10:23 -06:00
Jason A. Donenfeld 0687dc06c8 tun: freebsd: become controlling process when reopening tun FD
When we pass the TUN FD to the child, we have to call TUNSIFPID;
otherwise when we close the device, we get a splat in dmesg.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-19 15:02:44 -06:00
Jason A. Donenfeld 71aefa374d tun: freebsd: restructure and cleanup
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-19 14:54:59 -06:00
Jason A. Donenfeld 3d3e30beb8 tun: freebsd: remove horrific hack for getting tunnel name
As of FreeBSD 12.1, there's TUNGIFNAME.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-19 12:03:16 -06:00
Jason A. Donenfeld b0e5b19969 tun: freebsd: set IFF_MULTICAST for routing daemons
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-18 20:09:04 -06:00
Jason A. Donenfeld 12ce53271b tun: freebsd: use broadcast mode instead of PPP mode
It makes the routing configuration simpler.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-23 12:41:34 -06:00
Jason A. Donenfeld c5f382624e tun: linux: do not spam events every second from hack listener
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-11 09:23:11 -07:00
Kay Diam 6005c573e2 tun: freebsd: allow empty names
This change allows omitting the tun interface name setting. When the
name is not set, the kernel automatically picks up the tun name and
index.

Signed-off-by: Kay Diam <kay.diam@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-08 21:32:27 -07:00
Jason A. Donenfeld 4885e7c954 memmod: use resource functions from x/sys
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-08 21:04:09 -07:00
Jason A. Donenfeld 497ba95de7 memmod: do not use IsBadReadPtr
It should be enough to check for the trailing zero name.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-08 21:04:09 -07:00
Jason A. Donenfeld 79611c64e8 tun/netstack: bump deps and api
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-06 08:48:14 -07:00
Jason A. Donenfeld f9dac7099e global: remove TODO name graffiti
Googlers have a habit of graffiting their name in TODO items that then
are never addressed, and other people won't go near those because
they're marked territory of another animal. I've been gradually cleaning
these up as I see them, but this commit just goes all the way and
removes the remaining stragglers.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-23 20:00:57 +01:00
Jason A. Donenfeld 9a29ae267c device: test up/down using virtual conn
This prevents port clashing bugs.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-23 20:00:57 +01:00
Brad Fitzpatrick 0f4809f366 tun: make NativeTun.Close well behaved, not crash on double close
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-02-22 15:26:29 +01:00
Jason A. Donenfeld 8bf4204d2e global: stop using ioutil
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-17 22:19:27 +01:00
Jason A. Donenfeld 587a2b2a20 device: return error from Up() and Down()
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-10 00:12:23 +01:00
Jason A. Donenfeld 6f08a10041 rwcancel: add an explicit close call
This lets us collect FDs even if the GC doesn't do it for us.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-09 20:19:14 +01:00
Jason A. Donenfeld c040dea798 tun: use errors.Is for unwrapping
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-09 19:50:31 +01:00
Jason A. Donenfeld d4112d9096 global: bump copyright
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-28 17:52:15 +01:00
Jason A. Donenfeld a11dec5dc1 tun: use %w for errors on linux
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-27 16:02:42 +01:00
Jason A. Donenfeld fcc8ad05df netstack: further sequester with own go.mod and go.sum
In order to avoid even the flirtation with passing on these dependencies
to ordinary consumers of wireguard-go, this commit makes a new go.mod
that's entirely separate from the root one.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-21 00:25:02 +01:00
Jason A. Donenfeld 1d4eb2727a 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>
2021-01-21 00:16:59 +01:00
Josh Bleecher Snyder b00b2c2951 tun: fix fmt.Errorf format strings
Type tcpip.Error is not an error.

I've filed https://github.com/google/gvisor/issues/5314
to fix this upstream.

Until that is fixed, use %v instead of %w,
to keep vet happy.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-20 20:03:40 +01:00
Josh Bleecher Snyder 291dbcf1f0 tun/wintun/memmod: gofmt
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-20 19:57:04 +01:00
Josh Bleecher Snyder abc88c82b1 tun/wintun/memmod: fix format verb
Caught by 'go vet'.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-20 19:57:02 +01:00
Jason A. Donenfeld 675955de5d tun: add tcpip stack tunnel abstraction
This allows people to initiate connections over WireGuard without any
underlying operating system support.

I'm not crazy about the trash it adds to go.sum, but the code this
actually adds to the binaries seems contained to the gvisor repo.

For the TCP/IP implementation, it uses gvisor. And it borrows some
internals from the Go standard library's resolver in order to bring Dial
and DialContext to tun_net, along with the LookupHost helper function.
This allows for things like HTTP2-over-TLS to work quite well:

    package main

    import (
        "io"
        "log"
        "net"
        "net/http"

        "golang.zx2c4.com/wireguard/device"
        "golang.zx2c4.com/wireguard/tun"
    )

    func main() {
        tun, tnet, err := tun.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
    `)
        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))
    }

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-13 16:33:40 +01:00
Jason A. Donenfeld 3d83df9bf3 memmod: apply explicit build tags to _32 and _64 files
Since _32 and _64 aren't valid goarchs, they don't match _GOOS_GOARCH,
and so the existing tags wind up not being restricted to windows-only.
This fixes the problem by adding windows to the tags explicitly. We
could also fix it by calling the files _32_windows or _64_windows, but
that changes the convention with the other single-arch files.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-07 14:49:44 +01:00
Jason A. Donenfeld d664444928 tun: make customization of WintunPool and requested GUID more obvious
Persnickety consumers can now do:

    func init() {
        tun.WintunPool, _ = wintun.MakePool("Flurp")
        tun.WintunStaticRequestedGUID, _ = windows.GUIDFromString("{5ae2716f-0b3e-4dc4-a8b5-48eba11a6e16}")
    }

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-07 14:49:44 +01:00
Josh Bleecher Snyder 1481e72107 all: use ++ to increment
Make the code slightly more idiomatic. No functional changes.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-07 14:49:44 +01:00
Jason A. Donenfeld ca9edf1c63 wintun: do not load dll in init()
This prevents linking to wintun.dll until it's actually needed, which
should improve startup time.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-07 14:49:44 +01:00
Josh Bleecher Snyder 347ce76bbc tun/tuntest: make genICMPv4 allocate less
It doesn't really matter, because it is only used in tests,
but it does remove some noise from pprof profiles.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-07 14:49:37 +01:00
Jason A. Donenfeld b6303091fc memmod: fix import loading function usage
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-27 13:13:45 +01:00
Simon Rozman c9fabbd5bf wintun: log when reboot is suggested by Windows
Which really shouldn't happen. But it is a useful information for
troubleshooting.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-25 13:58:11 +01:00
Simon Rozman 4cc7a7a455 wintun: keep original error when Wintun session start fails
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-25 13:57:05 +01:00
Jason A. Donenfeld 60b3766b89 wintun: load from filesystem by default
We let people loading this from resources opt in via:

    go build -tags load_wintun_from_rsrc

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-11 18:51:44 +01:00
Jason A. Donenfeld 82128c47d9 global: switch to using %w instead of %v for Errorf
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-07 21:56:32 +01:00
Simon Rozman a3b231b31e wintun: ring management moved to wintun.dll
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-07 15:20:49 +01:00
Simon Rozman 65e03a9182 wintun: load wintun.dll from RCDATA resource
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-07 15:20:49 +01:00
Simon Rozman 3e08b8aee0 wintun: migrate to wintun.dll API
Rather than having every application using Wintun driver reinvent the
wheel, the Wintun device/adapter/interface management has been moved
from wireguard-go to wintun.dll deployed with Wintun itself.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-07 12:46:35 +01:00
Tobias Klauser 3b490f30aa tun: use SockaddrCtl from golang.org/x/sys/unix on macOS
Direct syscalls using unix.Syscall(unix.SYS_*, ...) are discouraged on
macOS and might not be supported in future versions. Switch to use
unix.Connect with unix.SockaddrCtl instead.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-10-27 16:20:09 +01:00
Tobias Klauser e6b7c4eef3 tun: use Ioctl{Get,Set}IfreqMTU from golang.org/x/sys/unix on macOS
Direct syscalls using unix.Syscall(unix.SYS_*, ...) are discouraged on
macOS and might not be supported in future versions. Switch to use
unix.Ioctl{Get,Set}IfreqMTU to get and set an interface's MTU.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-10-27 16:20:09 +01:00
Tobias Klauser 8ae09213a7 tun: use IoctlCtlInfo from golang.org/x/sys/unix on macOS
Direct syscalls using unix.Syscall(unix.SYS_*, ...) are discouraged on
macOS and might not be supported in future versions. Switch to use
unix.IoctlCtlInfo to get the kernel control info.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-10-27 16:20:09 +01:00
Tobias Klauser 36dc8b6994 tun: use GetsockoptString in (*NativeTun).Name on macOS
Direct syscalls using unix.Syscall(unix.SYS_*, ...) are discouraged on
macOS and might not be supported in future versions. Instead, use the
existing unix.GetsockoptString wrapper to get the interface name.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-10-27 16:20:09 +01:00
Brad Fitzpatrick 58a8f05f50 tun/wintun/registry: fix Go 1.15 race/checkptr failure
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
[Jason: ran go mod tidy.]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-10-21 18:26:10 +02:00
Jason A. Donenfeld db0aa39b76 global: update header comments and modules
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-05-02 02:08:26 -06:00
Simon Rozman fdba6c183a wintun: make remaining HWID comparisons case insensitive
c85e4a410f introduced preliminary HWID
checking to speed up Wintun adapter enumeration. However, all HWID are
case insensitive by Windows convention.

Furthermore, a device might have multiple HWIDs. When DevInfo's
DeviceRegistryProperty(SPDRP_HARDWAREID) method returns []string, all
strings returned should be checked against given hardware ID.

This issue was discovered when researching Wintun and wireguard-go on
Windows 10 ARM64. The Wintun adapter was created using devcon.exe
utility with "wintun" hardware ID, causing wireguard-go fail to
enumerate the adapter properly.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-05-02 01:50:47 -06:00
Simon Rozman 250b9795f3 setupapi: extend struct size constant definitions for arm(64)
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-05-02 01:50:47 -06:00
Brad Fitzpatrick 2fb0a712f0 tun: return a better error message if /dev/net/tun doesn't exist
It was just returning "no such file or directory" (the String of the
syscall.Errno returned by CreateTUN).

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2020-05-02 01:50:47 -06:00
Avery Pennarun c76b818466 tun: NetlinkListener: don't send EventDown before sending EventUp
This works around a startup race condition when competing with
HackListener, which is trying to do the same job. If HackListener
detects that the tundev is running while there is still an event in the
netlink queue that says it isn't running, then the device receives a
string of events like
	EventUp (HackListener)
	EventDown (NetlinkListener)
	EventUp (NetlinkListener)
Unfortunately, after the first EventDown, the device stops itself,
thinking incorrectly that the administrator has downed its tundev.

The device is ignoring the initial EventDown anyway, so just don't emit
it.

Signed-off-by: Avery Pennarun <apenwarr@tailscale.com>
2020-05-02 01:46:42 -06:00