Commit Graph

319 Commits

Author SHA1 Message Date
Matt Layher
32912dc778 device, tun: rearrange code and fix device tests
Signed-off-by: Matt Layher <mdlayher@gmail.com>
2019-05-29 18:34:55 +02:00
Jason A. Donenfeld
d4034e5f8a wintun: remove extra / 2019-05-26 02:20:01 +02:00
Simon Rozman
6a0a3a5406 wintun: revise GetInterface()
- Make foreign interface found error numeric to ease condition
  detection.
- Update GetInterface() documentation.
- Make tun.CreateTUN() quit when foreign interface found before
  attempting to create a Wintun interface with a duplicate name.
  Creation is futile.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-05-24 09:29:57 +02:00
Jason A. Donenfeld
8fdcf5ee30 wintun: never return nil, nil 2019-05-23 15:25:53 +02:00
Simon Rozman
dc9bbec9db setupapi: trim "Get" from getters
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-05-22 19:31:52 +02:00
Jason A. Donenfeld
a6dbe4f475 wintun: don't try to flush interface, but rather delete 2019-05-17 16:06:02 +02:00
Jason A. Donenfeld
95c70b8032 wintun: make certain methods private 2019-05-17 15:01:08 +02:00
Simon Rozman
7d5f5bcc0d wintun: change acronyms to uppercase
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-05-17 10:22:34 +02:00
Jason A. Donenfeld
3bf41b06ae global: regroup all imports 2019-05-14 09:09:52 +02:00
Jason A. Donenfeld
3147f00089 wintun: registry: fix nits 2019-05-11 17:25:48 +02:00
Simon Rozman
6c1b66802f wintun: registry: revise value reading
- Make getStringValueRetry() reusable for reading any value type. This
  merges code from GetIntegerValueWait().
- expandString() >> toString() and extend to support REG_MULTI_SZ
  (to return first value of REG_MULTI_SZ). Furthermore, doing our own
  UTF-16 to UTF-8 conversion works around a bug in windows/registry's
  GetStringValue() non-zero terminated string handling.
- Provide toInteger() analogous to toString()
- GetStringValueWait() tolerates and reads REG_MULTI_SZ too now. It
  returns REG_MULTI_SZ[0], making GetFirstStringValueWait() redundant.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-05-11 17:14:37 +02:00
Jason A. Donenfeld
5669ed326f wintun: call HrRenameConnection in another thread 2019-05-10 21:31:37 +02:00
Jason A. Donenfeld
2d847a38a2 wintun: add LUID accessor 2019-05-10 21:30:23 +02:00
Jason A. Donenfeld
7a8553aef0 wintun: enumerate faster by using COMPATDRIVER instead of CLASSDRIVER 2019-05-10 20:30:59 +02:00
Jason A. Donenfeld
a6045ac042 wintun: destroy devinfolist after usage 2019-05-10 20:19:11 +02:00
Simon Rozman
1c92b48415 wintun: registry: replace REG_NOTIFY with NOTIFY
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-05-10 18:09:20 +02:00
Jason A. Donenfeld
c267965bf8 wintun: IpConfig is a MULTI_SZ, and fix errors 2019-05-10 18:06:49 +02:00
Jason A. Donenfeld
1bf1dadf15 wintun: poll for device key
It's actually pretty hard to guess where it is.
2019-05-10 17:34:03 +02:00
Jason A. Donenfeld
f9dcfccbb7 wintun: fix scope of error object 2019-05-10 16:59:24 +02:00
Simon Rozman
7e962a9932 wintun: wait for interface registry key on device creation
By using RegNotifyChangeKeyValue(). Also disable dead gateway detection.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-05-10 16:43:58 +02:00
Simon Rozman
dcb8f1aa6b wintun: fix GUID leading zero padding
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-05-09 12:16:21 +02:00
Jason A. Donenfeld
81ca08f1b3 setupapi: safer aliasing of slice types 2019-05-03 09:34:00 +02:00
Jason A. Donenfeld
2e988467c2 wintun: work around GetInterface staleness bug 2019-05-03 00:42:36 +02:00
Jason A. Donenfeld
46dbf54040 wintun: don't retry when not creating
The only time we're trying to counteract the race condition is when
we're creating a driver. When we're simply looking up all drivers, it
doesn't make sense to retry.
2019-05-02 23:53:15 +02:00
Jason A. Donenfeld
247e14693a wintun: try harder to open registry key
This sucks. Can we please find a deterministic way of doing this
instead?
2019-04-29 14:00:49 +02:00
Jason A. Donenfeld
bb42ec7d18 tun: freebsd: work around numerous kernel panics on shutdown
There are numerous race conditions. But even this will crash it:

while true; do ifconfig tun0 create; ifconfig tun0 destroy; done

It seems like LLv6 is related, which we're not using anyway, so
explicitly disable it on the interface.
2019-04-23 18:00:23 +09:00
Simon Rozman
f1dc167901 setupapi: Fix struct size mismatches
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-19 10:08:11 +02:00
Jason A. Donenfeld
c7a26dfef3 setupapi: actually fix padding by rounding up to sizeof(void*) 2019-04-19 10:19:00 +09:00
Jason A. Donenfeld
d024393335 tun: darwin: write routeSocket variable in helper
Otherwise the race detector "complains".
2019-04-19 07:53:19 +09:00
Simon Rozman
5811447b38 setupapi: Revise DrvInfoDetailData struct size calculation
Go adds trailing padding to DrvInfoDetailData struct in GOARCH=386 which
confuses SetupAPI expecting exactly sizeof(SP_DRVINFO_DETAIL_DATA).

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-18 10:39:22 +02:00
Jason A. Donenfeld
e0a8c22aa6 windows: use proper constants from updated x/sys 2019-04-13 02:02:02 +02:00
Simon Rozman
ef5f3ad80a tun: windows: Adopt new error codes returned by Wintun
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-11 19:38:11 +02:00
Simon Rozman
a291fdd746 tun: windows: do not sleep after OPERATION_ABORTED on write
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-11 19:37:04 +02:00
Jason A. Donenfeld
e680008700 tun: windows: do not sleep after OPERATION_ABORTED 2019-04-09 07:36:03 +02:00
Simon Rozman
767c86f8cb tun: windows: Retry R/W on ERROR_OPERATION_ABORTED
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-04 09:20:18 +02:00
Simon Rozman
421c1f9143 tun: windows: Attempt to reopen handle on all errors
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-03 05:41:38 +02:00
Jason A. Donenfeld
ac25702eaf wintun: rename device using undocumented API that netsh.exe uses 2019-04-01 12:04:44 +02:00
Jason A. Donenfeld
92f8474832 wintun: add more retry loops 2019-04-01 09:07:43 +02:00
Jason A. Donenfeld
2e0ed4614a tun: windows: cancel ongoing reads on closing and delete after close
This reverts commit 52ec440d79 and adds
some spice.
2019-03-26 16:14:32 +01:00
Jason A. Donenfeld
2fa80c0cb7 wintun: query for NetCfgInstanceId several times 2019-03-22 16:48:40 -06:00
Jason A. Donenfeld
52ec440d79 tun: windows: delete interface before deleting file handles 2019-03-22 16:45:58 -06:00
Simon Rozman
2faf2dcf90 tun: windows: Make adapter rename asynchronous
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-22 16:36:30 +01:00
Simon Rozman
41c30a7279 tun: windows: Adapter devices renamed to WINTUN<LUID Index>
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-22 15:29:14 +01:00
Simon Rozman
4b1db1d39b tun: windows: Increase unavailable adapter timeout to 30sec
5 seconds was too short when debugging.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-22 13:52:51 +01:00
Simon Rozman
a80db5e65e tun: windows: Make writing persistent too
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-22 13:52:51 +01:00
Simon Rozman
9748a52073 tun: windows: Fix paused adapter test
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-22 13:52:51 +01:00
Jason A. Donenfeld
317d716d66 tun: windows: just open two file handles 2019-03-21 15:20:09 -06:00
Jason A. Donenfeld
6440f010ee receive: implement flush semantics 2019-03-21 14:45:41 -06:00
Jason A. Donenfeld
49ea0c9b1a tun: windows: add dummy overlapped events back
These seem basically wrong to me, but we get crashes without them.
2019-03-21 02:29:09 -06:00
Jason A. Donenfeld
ca59b60aa7 tun: windows: use new constants in sys 2019-03-20 23:42:30 -06:00
Simon Rozman
91b4e909bb wintun: Use native Win32 API for I/O
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-21 00:56:45 +01:00
Jason A. Donenfeld
03f2e2614a tun: windows: wintun does iocp 2019-03-18 02:42:45 -06:00
Jason A. Donenfeld
b0e0ab308d tun: windows: temporary hack for forcing MTU 2019-03-13 02:52:32 -06:00
Jason A. Donenfeld
66fb5caf02 wintun: Poll more often 2019-03-10 03:47:54 +01:00
Simon Rozman
c2a2b8d739 wintun: Make errors more descriptive
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-08 10:03:57 +01:00
Simon Rozman
70449f1a97 wintun: Return correct reboot-req flag on CreateInterface() error too
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-08 10:03:57 +01:00
Simon Rozman
33c3528430 wintun: Fix double-quoted strings escaping on output
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-08 10:03:57 +01:00
Simon Rozman
30ab07e354 wintun: Introduce SetupAPI enumerator and machineName consts
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-08 10:03:57 +01:00
Simon Rozman
368dea72fe wintun: Cleanup
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-07 21:12:20 +01:00
Simon Rozman
9b22255cad wintun: Refactor network registry key name generation
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-07 21:12:20 +01:00
Simon Rozman
11f5780250 wintun: Revise interface creation wait
DIF_INSTALLDEVICE returns almost immediately, while the device
installation continues in the background. It might take a while, before
all registry keys and values are populated.

Previously, wireguard-go waited for HKLM\SYSTEM\CurrentControlSet\
Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\<id> registry key
only.

Followed by a SetInterfaceName() method of Wintun struct which tried to
access HKLM\SYSTEM\CurrentControlSet\Control\Network\
{4D36E972-E325-11CE-BFC1-08002BE10318}\<id>\Connection registry key
might not be available yet.

This commit loops until both registry keys are available before
returning from CreateInterface() function.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-07 21:12:20 +01:00
Jason A. Donenfeld
92f72f5aa6 tun: linux: work out netpoll trick 2019-03-07 01:51:41 +01:00
Simon Rozman
1fdf7b19a3 wintun: Resolve some of golint warnings
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-04 16:37:11 +01:00
Simon Rozman
a1aabb21ae Elaborate the failing step when forwarding errors on return
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-04 16:37:11 +01:00
Simon Rozman
9041d38e2d Simplify reading NetCfgInstanceId from registry
As querying non-existing registry value and reading non-existing
registry string value both return ERROR_FILE_NOT_FOUND, we can
use later only.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-04 16:37:11 +01:00
Simon Rozman
cddfd9a0d8 Unify interface-specific network registry key open
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-03-04 16:37:11 +01:00
Jason A. Donenfeld
68f0721c6a tun: import mobile particularities 2019-03-04 16:37:11 +01:00
Jason A. Donenfeld
69f0fe67b6 global: begin modularization 2019-03-03 05:00:40 +01:00
Jason A. Donenfeld
d435be35ca tun: windows: expose GUID 2019-03-01 00:11:12 +01:00
Jason A. Donenfeld
967d1a0f3d tun: allow special methods in NativeTun 2019-03-01 00:05:57 +01:00
Jason A. Donenfeld
88ff67fb6f tun: linux: netpoll is broken for tun's epoll
So this mostly reverts the switch to Sysconn for Linux.

Issue: https://github.com/golang/go/issues/30426
2019-02-27 04:38:26 +01:00
Jason A. Donenfeld
971be13e77 tun: linux: netlink sock needs cleaning up but file will be gc'd 2019-02-27 04:11:41 +01:00
Jason A. Donenfeld
366cbd11a4 tun: use netpoll instead of rwcancel
The new sysconn function of Go 1.12 makes this possible:

package main

import "log"
import "os"
import "unsafe"
import "time"
import "syscall"
import "sync"
import "golang.org/x/sys/unix"

func main() {
	fd, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0)
	if err != nil {
		log.Fatal(err)
	}

	var ifr [unix.IFNAMSIZ + 64]byte
	copy(ifr[:], []byte("cheese"))
	*(*uint16)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = unix.IFF_TUN

	var errno syscall.Errno
	s, _ := fd.SyscallConn()
	s.Control(func(fd uintptr) {
		_, _, errno = unix.Syscall(
			unix.SYS_IOCTL,
			fd,
			uintptr(unix.TUNSETIFF),
			uintptr(unsafe.Pointer(&ifr[0])),
		)
	})
	if errno != 0 {
		log.Fatal(errno)
	}

	b := [4]byte{}
	wait := sync.WaitGroup{}
	wait.Add(1)
	go func() {
		_, err := fd.Read(b[:])
		log.Print("Read errored: ", err)
		wait.Done()
	}()
	time.Sleep(time.Second)
	log.Print("Closing")
	err = fd.Close()
	if err != nil {
		log.Print("Close errored: " , err)
	}
	wait.Wait()
	log.Print("Exiting")
}
2019-02-27 01:52:55 +01:00
Jason A. Donenfeld
ab0f442daf tun: use sysconn instead of .Fd with Go 1.12 2019-02-27 01:34:11 +01:00
Simon Rozman
d002eff155 wintun: Read/write packet size from/to exchange buffer directly
Driver <-> user-space communication is local and using native endian.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-22 16:16:14 +01:00
Simon Rozman
e06a8f8f9f wintun: Make two-step slicing a one step
Stop relying to Go compiler optimizations and calculate the end offset
directly.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-22 16:11:33 +01:00
Simon Rozman
ac4944a708 wintun: Write exchange buffer increased back to 1MiB
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-20 20:13:33 +01:00
Simon Rozman
2491f9d454 wintun: Migrate from unsafe buffer handling to encoding/binary
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-20 20:10:24 +01:00
Simon Rozman
8091c6474a wintun: Adopt new packet data alignment
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-20 19:56:10 +01:00
Simon Rozman
040da43889 wintun: Cleanup
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-20 18:38:18 +01:00
Simon Rozman
b7025b5627 wintun: Add TUN device locking
In case reading from TUN device detected TUN device was closed, it
closed the file handle and set tunFile to nil. The tunFile is
automatically reopened on retry, but... If another packet comes in the
WireGuard calls Write() method. With tunFile set to nil, this will
cause access violation.

Therefore, locking was introduced.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-20 13:12:08 +01:00
Simon Rozman
6581cfb885 wintun: Move exchange buffer in separate struct on heap
This allows buffer alignment and keeps it together with its meta-data.

Furthermore, the write buffer has been reduced - as long as we flush
after _every_ write, we don't need a 1MiB write buffer.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-20 11:41:37 +01:00
Simon Rozman
4863089120 wintun: Switch to dynamic packet sizes
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-19 18:50:42 +01:00
Jason A. Donenfeld
42c6d0e261 Change package path 2019-02-18 05:11:39 +01:00
Simon Rozman
b719a09a26 wintun: Auto-calculate TUN exchange buffer size
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-08 15:21:24 +01:00
Simon Rozman
f05f52637f wintun: Simplify Read method()
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-08 14:31:05 +01:00
Simon Rozman
713477cfb1 wintun: Make constants private and adopt Go recommended case
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-08 08:55:23 +01:00
Simon Rozman
5981d5cacf wintun: Check for user close in read loop regardless the load
Do the WaitForSingleObject() always to provide high-load responsiveness.

Reorder events so TUN_SIGNAL_CLOSE has priority over
TUN_SIGNAL_DATA_AVAIL, to provide high-load responsiveness at all.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-08 08:48:35 +01:00
Simon Rozman
b13739ada2 wintun: Adjust tunRWQueue.left member to match Wintun driver
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-08 07:32:12 +01:00
Simon Rozman
c4988999ac setupapi: Merge _SP_DRVINFO_DETAIL_DATA and DrvInfoDetailData
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 23:50:43 +01:00
Simon Rozman
b662896cf4 setupapi: Merge SP_DRVINFO_DATA and DrvInfoData
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 23:50:43 +01:00
Simon Rozman
0525f6b112 setupapi: Rename SP_REMOVEDEVICE_PARAMS to RemoveDeviceParams
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 23:50:43 +01:00
Simon Rozman
9d830826c5 setupapi: Rename SP_CLASSINSTALL_HEADER to ClassInstallHeader
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 23:50:43 +01:00
Simon Rozman
bd963497da setupapi: Merge _SP_DEVINSTALL_PARAMS and DevInstallParams
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 23:50:30 +01:00
Simon Rozman
05d25fd1b7 setupapi: Merge _SP_DEVINFO_LIST_DETAIL_DATA and DevInfoListDetailData
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 23:49:50 +01:00
Simon Rozman
6d2729dccc setupapi: Rename SP_DEVINFO_DATA to DevInfoData
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 22:43:02 +01:00
Simon Rozman
d87cbeeb2f wintun: Detect if a foreign interface with the same name exists
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 22:02:51 +01:00
Simon Rozman
043b7e8013 wintun: Clean excessive setupapi.DevInfo.GetDeviceInfoListDetail() call
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 20:49:41 +01:00
Simon Rozman
ef48d4fa95 wintun: Explain rationale behind case-insensitive interface names
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 19:42:59 +01:00
Simon Rozman
f7276ed522 wintun: Implement TODO in TestSetupDiGetDeviceRegistryProperty()
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-07 18:59:34 +01:00
Jason A. Donenfeld
c4b43e35a7 wintun: add FlushInterface stub 2019-02-07 18:24:28 +01:00
Jason A. Donenfeld
fac1fbcd72 wintun: Compare values of GUID, not pointers, when removing 2019-02-07 04:49:15 +01:00
Jason A. Donenfeld
ea59177f1c wintun: Introduce new package for obscuring Windows bits 2019-02-07 04:39:59 +01:00
Jason A. Donenfeld
306d08e692 tun_windows: Style 2019-02-07 04:08:05 +01:00
Simon Rozman
cb2bc4b34c tun_windows: Introduce preliminary TUN interface creation
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-06 22:30:14 +01:00
Simon Rozman
46279ad0f9 tun_windows: Stop checking minimum size of received TUN packets
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-02-06 20:22:04 +01:00
Jason A. Donenfeld
c599bf9497 Fix up errors and paths 2019-02-05 22:06:25 +09:00
Jason A. Donenfeld
6f76edd045 Import windows scafolding 2019-02-05 12:59:42 +01:00
Jason A. Donenfeld
dff424baf8 Update copyright 2019-02-05 12:59:42 +01:00
Jason A. Donenfeld
651744561e tun: remove nonblock hack for linux
This is no longer necessary and actually breaks things

Reported-by: Chris Branch <cbranch@cloudflare.com>
2018-12-06 17:17:51 +01:00
Jason A. Donenfeld
276bf973e8 Use darwin tun on ios 2018-11-06 16:24:35 +01:00
Jason A. Donenfeld
2e772194cf tun: only call .Fd() once
Doing so tends to make the tunnel blocking, so we only retrieve it once
before we call SetNonblock, and then cache the result.
2018-10-17 21:31:42 +02:00
Jason A. Donenfeld
5be541d147 global: fix up copyright headers 2018-09-16 18:49:19 +02:00
Jason A. Donenfeld
15da869b31 Fix duplicate copyright line 2018-07-30 05:14:17 +02:00
Jason A. Donenfeld
0ba551807f Do not build tun device on ios 2018-06-09 03:31:17 +02:00
Jason A. Donenfeld
5079298ce2 Disable broadcast mode on *BSD
Keeping it on makes IPv6 problematic and confuses routing daemons.
2018-05-27 22:55:15 +02:00
Jason A. Donenfeld
2f2eca8947 Catch EINTR 2018-05-24 15:36:29 +02:00
Jason A. Donenfeld
588b9f01ae Adopt GOPATH
GOPATH is annoying, but the Go community pushing me to adopt it is even
more annoying.
2018-05-23 05:18:13 +02:00
Jason A. Donenfeld
0a63188afa Move tun to subpackage 2018-05-23 03:58:27 +02:00