23 Commits

Author SHA1 Message Date
Jason A. Donenfeld
738d027f0b version: bump snapshot 2018-10-18 02:38:29 +02:00
Jason A. Donenfeld
60848b9c72 Makefile: rename default to all 2018-10-17 21:45:16 +02: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
85b2378a07 Use go modules always 2018-10-12 01:45:33 +02:00
Jason A. Donenfeld
fddb949002 Do not build if nothing to do 2018-10-12 01:12:56 +02:00
Jason A. Donenfeld
5d6083df7e Switch to go modules 2018-10-09 18:13:56 +02:00
Jason A. Donenfeld
b41922e5c8 version: bump snapshot 2018-10-01 17:58:31 +02:00
Jason A. Donenfeld
dbb72402f2 Adding missing queueconstants file 2018-10-01 16:11:31 +02:00
Chris Branch
7c971d7ef4 Fix transport message length check
wireguard-go has a bad length check in its transport message handling.
Although it cannot be exploited because of another length check earlier in the
function, this should be fixed regardless.
2018-09-25 05:18:11 +02:00
Jason A. Donenfeld
70bcf9ecb8 Make it easy to restrict queue sizes more 2018-09-25 02:31:02 +02:00
Jason A. Donenfeld
ebc7541953 Fix shutdown races 2018-09-24 01:52:02 +02:00
Jason A. Donenfeld
833597b585 More pooling 2018-09-24 00:37:43 +02:00
Jason A. Donenfeld
cf81a28dd3 Fixup buffer freeing 2018-09-22 05:43:03 +02:00
Jason A. Donenfeld
942abf948a send: more precise padding calculation 2018-09-16 23:42:31 +02:00
Jason A. Donenfeld
47d1140361 device: preallocated buffers scheme
Not useful now but quite possibly later.
2018-09-16 23:10:19 +02:00
Jason A. Donenfeld
39d6e4f2f1 Change queueing drop order and fix memory leaks
If the queues are full, we drop the present packet, which is better for
network traffic flow. Also, we try to fix up the memory leaks with not
putting buffers from our shared pool.
2018-09-16 21:50:58 +02:00
Jason A. Donenfeld
1c02557013 send: use accessor function for buffer pool 2018-09-16 18:49:19 +02:00
Mathias Hall-Andersen
32d2148835 Fixed port overwrite issue on kernels without ipv6
Fixed an issue in CreateBind for Linux:
If ipv6 was not supported the error code would be
correctly identified as EAFNOSUPPORT and ipv4 binding attempted.
However the port would be set to 0,
which results in the subsequent create4 call requesting
a random port rather than the one provided to CreateBind.

This issue was identified by:
Kent Friis <leeloored@gmx.com>
2018-09-16 18:49:19 +02:00
Jason A. Donenfeld
5be541d147 global: fix up copyright headers 2018-09-16 18:49:19 +02:00
Jason A. Donenfeld
063becdc73 uapi: insert peer version placeholder
While we don't want people to ever use old protocols, people will
complain if the API "changes", so explicitly make the unset protocol
mean the latest, and add a dummy mechanism of specifying the protocol on
a per-peer basis, which we hope nobody actually ever uses.
2018-09-02 23:04:47 -06:00
Jason A. Donenfeld
15da869b31 Fix duplicate copyright line 2018-07-30 05:14:17 +02:00
Jason A. Donenfeld
3ad3e83c7a uapi: allow overriding socket directory at compile time 2018-07-24 14:32:35 +02:00
Jason A. Donenfeld
2e13b7b0fb send: better debug message for failed data packet 2018-07-16 16:05:36 +02:00
61 changed files with 478 additions and 394 deletions

42
Gopkg.lock generated
View File

@@ -1,42 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
packages = [
"blake2s",
"chacha20poly1305",
"curve25519",
"internal/chacha20",
"poly1305"
]
revision = "ab813273cd59e1333f7ae7bff5d027d4aadf528c"
[[projects]]
branch = "master"
name = "golang.org/x/net"
packages = [
"bpf",
"internal/iana",
"internal/socket",
"ipv4",
"ipv6"
]
revision = "dfa909b99c79129e1100513e5cd36307665e5723"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = [
"cpu",
"unix"
]
revision = "c11f84a56e43e20a78cee75a7c034031ecf57d1f"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "d85ae9d2b4afafc3d7535505c46368cbbbec350cf876616302c1bcf44f6ec103"
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -1,15 +0,0 @@
[[constraint]]
branch = "master"
name = "golang.org/x/crypto"
[[constraint]]
branch = "master"
name = "golang.org/x/net"
[[constraint]]
branch = "master"
name = "golang.org/x/sys"
[prune]
go-tests = true
unused-packages = true

View File

@@ -1,51 +1,42 @@
PREFIX ?= /usr
DESTDIR ?=
BINDIR ?= $(PREFIX)/bin
export GOPATH ?= $(CURDIR)/.gopath
export GO111MODULE := on
ifeq ($(shell go env GOOS),linux)
ifeq ($(wildcard .git),)
all: generate-version-and-build
ifeq ($(shell go env GOOS)|$(wildcard .git),linux|)
$(error Do not build this for Linux. Instead use the Linux kernel module. See wireguard.com/install/ for more info.)
else
$(shell printf 'package main\nconst UseTheKernelModuleInstead = 0xdeadbabe\n' > ireallywantobuildon_linux.go)
endif
ireallywantobuildon_linux.go:
@printf "WARNING: This software is meant for use on non-Linux\nsystems. For Linux, please use the kernel module\ninstead. See wireguard.com/install/ for more info.\n\n" >&2
@printf 'package main\nconst UseTheKernelModuleInstead = 0xdeadbabe\n' > "$@"
clean-ireallywantobuildon_linux.go:
@rm -f ireallywantobuildon_linux.go
.PHONY: clean-ireallywantobuildon_linux.go
clean: clean-ireallywantobuildon_linux.go
wireguard-go: ireallywantobuildon_linux.go
endif
all: wireguard-go
MAKEFLAGS += --no-print-directory
export GOPATH := $(CURDIR)/.gopath
export PATH := $(PATH):$(CURDIR)/.gopath/bin
GO_IMPORT_PATH := git.zx2c4.com/wireguard-go
version.go:
generate-version-and-build:
@export GIT_CEILING_DIRECTORIES="$(realpath $(CURDIR)/..)" && \
tag="$$(git describe --dirty 2>/dev/null)" && \
ver="$$(printf 'package main\nconst WireGuardGoVersion = "%s"\n' "$$tag")" && \
[ "$$(cat $@ 2>/dev/null)" != "$$ver" ] && \
echo "$$ver" > $@ && \
git update-index --assume-unchanged $@ || true
[ "$$(cat version.go 2>/dev/null)" != "$$ver" ] && \
echo "$$ver" > version.go && \
git update-index --assume-unchanged version.go || true
@$(MAKE) wireguard-go
.gopath/.created:
rm -rf .gopath
mkdir -p $(dir .gopath/src/$(GO_IMPORT_PATH))
ln -s ../../.. .gopath/src/$(GO_IMPORT_PATH)
touch $@
vendor/.created: Gopkg.toml Gopkg.lock | .gopath/.created
command -v dep >/dev/null || go get -v github.com/golang/dep/cmd/dep
export PWD; cd .gopath/src/$(GO_IMPORT_PATH) && dep ensure -vendor-only -v
touch $@
wireguard-go: $(wildcard *.go) $(wildcard */*.go) .gopath/.created vendor/.created version.go
go build -v $(GO_IMPORT_PATH)
wireguard-go: $(wildcard *.go) $(wildcard */*.go)
go build -v -o "$@"
install: wireguard-go
@install -v -d "$(DESTDIR)$(BINDIR)" && install -v -m 0755 wireguard-go "$(DESTDIR)$(BINDIR)/wireguard-go"
@install -v -d "$(DESTDIR)$(BINDIR)" && install -v -m 0755 "$<" "$(DESTDIR)$(BINDIR)/wireguard-go"
clean:
rm -f wireguard-go
update-dep: | .gopath/.created
command -v dep >/dev/null || go get -v github.com/golang/dep/cmd/dep
cd .gopath/src/$(GO_IMPORT_PATH) && dep ensure -update -v
.PHONY: clean install update-dep version.go
.PHONY: all clean install generate-version-and-build

View File

@@ -48,7 +48,7 @@ This will run on OpenBSD. It does not yet support sticky sockets. Fwmark is mapp
## Building
This requires an installation of [go](https://golang.org) and of [dep](https://github.com/golang/dep). If dep is not installed, it will be downloaded and built as part of the build process.
This requires an installation of [go](https://golang.org) ≥ 1.11.
```
$ git clone https://git.zx2c4.com/wireguard-go

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -2,8 +2,7 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -2,8 +2,7 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*
* This implements userspace semantics of "sticky sockets", modeled after
* WireGuard's kernelspace implementation. This is more or less a straight port
@@ -28,6 +27,10 @@ import (
"unsafe"
)
const (
FD_ERR = -1
)
type IPv4Source struct {
src [4]byte
ifindex int32
@@ -127,6 +130,7 @@ func createNetlinkRouteSocket() (int, error) {
func CreateBind(port uint16, device *Device) (*NativeBind, uint16, error) {
var err error
var bind NativeBind
var newPort uint16
bind.netlinkSock, err = createNetlinkRouteSocket()
if err != nil {
@@ -140,18 +144,35 @@ func CreateBind(port uint16, device *Device) (*NativeBind, uint16, error) {
go bind.routineRouteListener(device)
bind.sock6, port, err = create6(port)
if err != nil && err != syscall.EAFNOSUPPORT {
// attempt ipv6 bind, update port if succesful
bind.sock6, newPort, err = create6(port)
if err != nil {
if err != syscall.EAFNOSUPPORT {
bind.netlinkCancel.Cancel()
return nil, 0, err
}
} else {
port = newPort
}
bind.sock4, port, err = create4(port)
if err != nil && err != syscall.EAFNOSUPPORT {
// attempt ipv4 bind, update port if succesful
bind.sock4, newPort, err = create4(port)
if err != nil {
if err != syscall.EAFNOSUPPORT {
bind.netlinkCancel.Cancel()
unix.Close(bind.sock6)
return nil, 0, err
}
} else {
port = newPort
}
if bind.sock4 == FD_ERR && bind.sock6 == FD_ERR {
return nil, 0, errors.New("ipv4 and ipv6 not supported")
}
return &bind, port, nil
}
@@ -335,7 +356,7 @@ func create4(port uint16) (int, uint16, error) {
)
if err != nil {
return -1, 0, err
return FD_ERR, 0, err
}
addr := unix.SockaddrInet4{
@@ -366,7 +387,7 @@ func create4(port uint16) (int, uint16, error) {
return unix.Bind(fd, &addr)
}(); err != nil {
unix.Close(fd)
return -1, 0, err
return FD_ERR, 0, err
}
return fd, uint16(addr.Port), err
@@ -383,7 +404,7 @@ func create6(port uint16) (int, uint16, error) {
)
if err != nil {
return -1, 0, err
return FD_ERR, 0, err
}
// set sockopts and bind
@@ -425,7 +446,7 @@ func create6(port uint16) (int, uint16, error) {
}(); err != nil {
unix.Close(fd)
return -1, 0, err
return FD_ERR, 0, err
}
return fd, uint16(addr.Port), err

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
@@ -27,18 +26,14 @@ const (
PaddingMultiple = 16
)
/* Implementation specific constants */
const (
QueueOutboundSize = 1024
QueueInboundSize = 1024
QueueHandshakeSize = 1024
MaxSegmentSize = (1 << 16) - 1 // largest possible UDP datagram
MinMessageSize = MessageKeepaliveSize // minimum size of transport message (keepalive)
MaxMessageSize = MaxSegmentSize // maximum size of transport message
MaxContentSize = MaxSegmentSize - MessageTransportSize // maximum size of transport message content
)
/* Implementation constants */
const (
UnderLoadQueueSize = QueueHandshakeSize / 8
UnderLoadAfterTime = time.Second // how long does the device remain under load after detected

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
@@ -67,7 +66,12 @@ type Device struct {
}
pool struct {
messageBuffers sync.Pool
messageBufferPool *sync.Pool
messageBufferReuseChan chan *[MaxMessageSize]byte
inboundElementPool *sync.Pool
inboundElementReuseChan chan *QueueInboundElement
outboundElementPool *sync.Pool
outboundElementReuseChan chan *QueueOutboundElement
}
queue struct {
@@ -243,14 +247,6 @@ func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
return nil
}
func (device *Device) GetMessageBuffer() *[MaxMessageSize]byte {
return device.pool.messageBuffers.Get().(*[MaxMessageSize]byte)
}
func (device *Device) PutMessageBuffer(msg *[MaxMessageSize]byte) {
device.pool.messageBuffers.Put(msg)
}
func NewDevice(tunDevice tun.TUNDevice, logger *Logger) *Device {
device := new(Device)
@@ -275,11 +271,7 @@ func NewDevice(tunDevice tun.TUNDevice, logger *Logger) *Device {
device.indexTable.Init()
device.allowedips.Reset()
device.pool.messageBuffers = sync.Pool{
New: func() interface{} {
return new([MaxMessageSize]byte)
},
}
device.PopulatePools()
// create queues
@@ -385,10 +377,11 @@ func (device *Device) Close() {
close(device.signals.stop)
device.RemoveAllPeers()
device.state.stopping.Wait()
device.FlushPacketQueues()
device.RemoveAllPeers()
device.rate.limiter.Close()
device.state.changing.Set(false)

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -2,7 +2,7 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

7
go.mod Normal file
View File

@@ -0,0 +1,7 @@
module git.zx2c4.com/wireguard-go
require (
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4
golang.org/x/net v0.0.0-20181005035420-146acd28ed58
golang.org/x/sys v0.0.0-20181005133103-4497e2df6f9e
)

6
go.sum Normal file
View File

@@ -0,0 +1,6 @@
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4 h1:Vk3wNqEZwyGyei9yq5ekj7frek2u7HUfffJ1/opblzc=
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sys v0.0.0-20181005133103-4497e2df6f9e h1:EfdBzeKbFSvOjoIqSZcfS8wp0FBLokGBEs9lz1OtSg0=
golang.org/x/sys v0.0.0-20181005133103-4497e2df6f9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

3
ip.go
View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

89
pools.go Normal file
View File

@@ -0,0 +1,89 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
import "sync"
func (device *Device) PopulatePools() {
if PreallocatedBuffersPerPool == 0 {
device.pool.messageBufferPool = &sync.Pool{
New: func() interface{} {
return new([MaxMessageSize]byte)
},
}
device.pool.inboundElementPool = &sync.Pool{
New: func() interface{} {
return new(QueueInboundElement)
},
}
device.pool.outboundElementPool = &sync.Pool{
New: func() interface{} {
return new(QueueOutboundElement)
},
}
} else {
device.pool.messageBufferReuseChan = make(chan *[MaxMessageSize]byte, PreallocatedBuffersPerPool)
for i := 0; i < PreallocatedBuffersPerPool; i += 1 {
device.pool.messageBufferReuseChan <- new([MaxMessageSize]byte)
}
device.pool.inboundElementReuseChan = make(chan *QueueInboundElement, PreallocatedBuffersPerPool)
for i := 0; i < PreallocatedBuffersPerPool; i += 1 {
device.pool.inboundElementReuseChan <- new(QueueInboundElement)
}
device.pool.outboundElementReuseChan = make(chan *QueueOutboundElement, PreallocatedBuffersPerPool)
for i := 0; i < PreallocatedBuffersPerPool; i += 1 {
device.pool.outboundElementReuseChan <- new(QueueOutboundElement)
}
}
}
func (device *Device) GetMessageBuffer() *[MaxMessageSize]byte {
if PreallocatedBuffersPerPool == 0 {
return device.pool.messageBufferPool.Get().(*[MaxMessageSize]byte)
} else {
return <-device.pool.messageBufferReuseChan
}
}
func (device *Device) PutMessageBuffer(msg *[MaxMessageSize]byte) {
if PreallocatedBuffersPerPool == 0 {
device.pool.messageBufferPool.Put(msg)
} else {
device.pool.messageBufferReuseChan <- msg
}
}
func (device *Device) GetInboundElement() *QueueInboundElement {
if PreallocatedBuffersPerPool == 0 {
return device.pool.inboundElementPool.Get().(*QueueInboundElement)
} else {
return <-device.pool.inboundElementReuseChan
}
}
func (device *Device) PutInboundElement(msg *QueueInboundElement) {
if PreallocatedBuffersPerPool == 0 {
device.pool.inboundElementPool.Put(msg)
} else {
device.pool.inboundElementReuseChan <- msg
}
}
func (device *Device) GetOutboundElement() *QueueOutboundElement {
if PreallocatedBuffersPerPool == 0 {
return device.pool.outboundElementPool.Get().(*QueueOutboundElement)
} else {
return <-device.pool.outboundElementReuseChan
}
}
func (device *Device) PutOutboundElement(msg *QueueOutboundElement) {
if PreallocatedBuffersPerPool == 0 {
device.pool.outboundElementPool.Put(msg)
} else {
device.pool.outboundElementReuseChan <- msg
}
}

16
queueconstants.go Normal file
View File

@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
/* Implementation specific constants */
const (
QueueOutboundSize = 1024
QueueInboundSize = 1024
QueueHandshakeSize = 1024
MaxSegmentSize = (1 << 16) - 1 // largest possible UDP datagram
PreallocatedBuffersPerPool = 0 // Disable and allow for infinite memory growth
)

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package ratelimiter

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package ratelimiter

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
@@ -44,59 +43,29 @@ func (elem *QueueInboundElement) IsDropped() bool {
return atomic.LoadInt32(&elem.dropped) == AtomicTrue
}
func (device *Device) addToInboundQueue(
queue chan *QueueInboundElement,
element *QueueInboundElement,
) {
for {
func (device *Device) addToInboundAndDecryptionQueues(inboundQueue chan *QueueInboundElement, decryptionQueue chan *QueueInboundElement, element *QueueInboundElement) bool {
select {
case queue <- element:
return
default:
case inboundQueue <- element:
select {
case old := <-queue:
old.Drop()
case decryptionQueue <- element:
return true
default:
element.Drop()
element.mutex.Unlock()
return false
}
}
default:
device.PutInboundElement(element)
return false
}
}
func (device *Device) addToDecryptionQueue(
queue chan *QueueInboundElement,
element *QueueInboundElement,
) {
for {
func (device *Device) addToHandshakeQueue(queue chan QueueHandshakeElement, element QueueHandshakeElement) bool {
select {
case queue <- element:
return
return true
default:
select {
case old := <-queue:
// drop & release to potential consumer
old.Drop()
old.mutex.Unlock()
default:
}
}
}
}
func (device *Device) addToHandshakeQueue(
queue chan QueueHandshakeElement,
element QueueHandshakeElement,
) {
for {
select {
case queue <- element:
return
default:
select {
case elem := <-queue:
device.PutMessageBuffer(elem.buffer)
default:
}
}
return false
}
}
@@ -155,6 +124,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
}
if err != nil {
device.PutMessageBuffer(buffer)
return
}
@@ -177,7 +147,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
// check size
if len(packet) < MessageTransportType {
if len(packet) < MessageTransportSize {
continue
}
@@ -199,24 +169,24 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
}
// create work element
peer := value.peer
elem := &QueueInboundElement{
packet: packet,
buffer: buffer,
keypair: keypair,
dropped: AtomicFalse,
endpoint: endpoint,
}
elem := device.GetInboundElement()
elem.packet = packet
elem.buffer = buffer
elem.keypair = keypair
elem.dropped = AtomicFalse
elem.endpoint = endpoint
elem.counter = 0
elem.mutex = sync.Mutex{}
elem.mutex.Lock()
// add to decryption queues
if peer.isRunning.Get() {
device.addToDecryptionQueue(device.queue.decryption, elem)
device.addToInboundQueue(peer.queue.inbound, elem)
if device.addToInboundAndDecryptionQueues(peer.queue.inbound, device.queue.decryption, elem) {
buffer = device.GetMessageBuffer()
}
}
continue
@@ -236,7 +206,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
}
if okay {
device.addToHandshakeQueue(
if (device.addToHandshakeQueue(
device.queue.handshake,
QueueHandshakeElement{
msgType: msgType,
@@ -244,10 +214,11 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
packet: packet,
endpoint: endpoint,
},
)
)) {
buffer = device.GetMessageBuffer()
}
}
}
}
func (device *Device) RoutineDecryption() {
@@ -308,6 +279,7 @@ func (device *Device) RoutineDecryption() {
)
if err != nil {
elem.Drop()
device.PutMessageBuffer(elem.buffer)
}
elem.mutex.Unlock()
}
@@ -322,18 +294,26 @@ func (device *Device) RoutineHandshake() {
logError := device.log.Error
logDebug := device.log.Debug
var elem QueueHandshakeElement
var ok bool
defer func() {
logDebug.Println("Routine: handshake worker - stopped")
device.state.stopping.Done()
if elem.buffer != nil {
device.PutMessageBuffer(elem.buffer)
}
}()
logDebug.Println("Routine: handshake worker - started")
device.state.starting.Done()
var elem QueueHandshakeElement
var ok bool
for {
if elem.buffer != nil {
device.PutMessageBuffer(elem.buffer)
elem.buffer = nil
}
select {
case elem, ok = <-device.queue.handshake:
case <-device.signals.stop:
@@ -506,9 +486,18 @@ func (peer *Peer) RoutineSequentialReceiver() {
logError := device.log.Error
logDebug := device.log.Debug
var elem *QueueInboundElement
var ok bool
defer func() {
logDebug.Println(peer, "- Routine: sequential receiver - stopped")
peer.routines.stopping.Done()
if elem != nil {
if !elem.IsDropped() {
device.PutMessageBuffer(elem.buffer)
}
device.PutInboundElement(elem)
}
}()
logDebug.Println(peer, "- Routine: sequential receiver - started")
@@ -516,13 +505,20 @@ func (peer *Peer) RoutineSequentialReceiver() {
peer.routines.starting.Done()
for {
if elem != nil {
if !elem.IsDropped() {
device.PutMessageBuffer(elem.buffer)
}
device.PutInboundElement(elem)
elem = nil
}
select {
case <-peer.routines.stop:
return
case elem, ok := <-peer.queue.inbound:
case elem, ok = <-peer.queue.inbound:
if !ok {
return
@@ -633,10 +629,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
offset := MessageTransportOffsetContent
atomic.AddUint64(&peer.stats.rxBytes, uint64(len(elem.packet)))
_, err := device.tun.device.Write(
elem.buffer[:offset+len(elem.packet)],
offset)
device.PutMessageBuffer(elem.buffer)
_, err := device.tun.device.Write(elem.buffer[:offset+len(elem.packet)], offset)
if err != nil {
logError.Println("Failed to write packet to TUN device:", err)
}

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package replay

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package replay

View File

@@ -2,7 +2,7 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package rwcancel

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package rwcancel

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package rwcancel

View File

@@ -2,7 +2,7 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package rwcancel

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package rwcancel

134
send.go
View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
@@ -53,10 +52,14 @@ type QueueOutboundElement struct {
}
func (device *Device) NewOutboundElement() *QueueOutboundElement {
return &QueueOutboundElement{
dropped: AtomicFalse,
buffer: device.pool.messageBuffers.Get().(*[MaxMessageSize]byte),
}
elem := device.GetOutboundElement()
elem.dropped = AtomicFalse
elem.buffer = device.GetMessageBuffer()
elem.mutex = sync.Mutex{}
elem.nonce = 0
elem.keypair = nil
elem.peer = nil
return elem
}
func (elem *QueueOutboundElement) Drop() {
@@ -67,10 +70,7 @@ func (elem *QueueOutboundElement) IsDropped() bool {
return atomic.LoadInt32(&elem.dropped) == AtomicTrue
}
func addToOutboundQueue(
queue chan *QueueOutboundElement,
element *QueueOutboundElement,
) {
func addToNonceQueue(queue chan *QueueOutboundElement, element *QueueOutboundElement, device *Device) {
for {
select {
case queue <- element:
@@ -78,30 +78,28 @@ func addToOutboundQueue(
default:
select {
case old := <-queue:
old.Drop()
device.PutMessageBuffer(old.buffer)
device.PutOutboundElement(old)
default:
}
}
}
}
func addToEncryptionQueue(
queue chan *QueueOutboundElement,
element *QueueOutboundElement,
) {
for {
func addToOutboundAndEncryptionQueues(outboundQueue chan *QueueOutboundElement, encryptionQueue chan *QueueOutboundElement, element *QueueOutboundElement) {
select {
case queue <- element:
case outboundQueue <- element:
select {
case encryptionQueue <- element:
return
default:
select {
case old := <-queue:
// drop & release to potential consumer
old.Drop()
old.mutex.Unlock()
element.Drop()
element.peer.device.PutMessageBuffer(element.buffer)
element.mutex.Unlock()
}
default:
}
}
element.peer.device.PutMessageBuffer(element.buffer)
element.peer.device.PutOutboundElement(element)
}
}
@@ -118,6 +116,8 @@ func (peer *Peer) SendKeepalive() bool {
peer.device.log.Debug.Println(peer, "- Sending keepalive packet")
return true
default:
peer.device.PutMessageBuffer(elem.buffer)
peer.device.PutOutboundElement(elem)
return false
}
}
@@ -243,8 +243,6 @@ func (peer *Peer) keepKeyFreshSending() {
*/
func (device *Device) RoutineReadFromTUN() {
elem := device.NewOutboundElement()
logDebug := device.log.Debug
logError := device.log.Error
@@ -256,7 +254,14 @@ func (device *Device) RoutineReadFromTUN() {
logDebug.Println("Routine: TUN reader - started")
device.state.starting.Done()
var elem *QueueOutboundElement
for {
if elem != nil {
device.PutMessageBuffer(elem.buffer)
device.PutOutboundElement(elem)
}
elem = device.NewOutboundElement()
// read packet
@@ -268,6 +273,8 @@ func (device *Device) RoutineReadFromTUN() {
logError.Println("Failed to read packet from TUN device:", err)
device.Close()
}
device.PutMessageBuffer(elem.buffer)
device.PutOutboundElement(elem)
return
}
@@ -309,8 +316,8 @@ func (device *Device) RoutineReadFromTUN() {
if peer.queue.packetInNonceQueueIsAwaitingKey.Get() {
peer.SendHandshakeInitiation(false)
}
addToOutboundQueue(peer.queue.nonce, elem)
elem = device.NewOutboundElement()
addToNonceQueue(peer.queue.nonce, elem, device)
elem = nil
}
}
}
@@ -334,22 +341,25 @@ func (peer *Peer) RoutineNonce() {
device := peer.device
logDebug := device.log.Debug
defer func() {
logDebug.Println(peer, "- Routine: nonce worker - stopped")
peer.queue.packetInNonceQueueIsAwaitingKey.Set(false)
peer.routines.stopping.Done()
}()
flush := func() {
for {
select {
case <-peer.queue.nonce:
case elem := <-peer.queue.nonce:
device.PutMessageBuffer(elem.buffer)
device.PutOutboundElement(elem)
default:
return
}
}
}
defer func() {
flush()
logDebug.Println(peer, "- Routine: nonce worker - stopped")
peer.queue.packetInNonceQueueIsAwaitingKey.Set(false)
peer.routines.stopping.Done()
}()
peer.routines.starting.Done()
logDebug.Println(peer, "- Routine: nonce worker - started")
@@ -403,10 +413,14 @@ func (peer *Peer) RoutineNonce() {
logDebug.Println(peer, "- Obtained awaited keypair")
case <-peer.signals.flushNonceQueue:
device.PutMessageBuffer(elem.buffer)
device.PutOutboundElement(elem)
flush()
goto NextPacket
case <-peer.routines.stop:
device.PutMessageBuffer(elem.buffer)
device.PutOutboundElement(elem)
return
}
}
@@ -421,6 +435,8 @@ func (peer *Peer) RoutineNonce() {
if elem.nonce >= RejectAfterMessages {
atomic.StoreUint64(&keypair.sendNonce, RejectAfterMessages)
device.PutMessageBuffer(elem.buffer)
device.PutOutboundElement(elem)
goto NextPacket
}
@@ -429,9 +445,7 @@ func (peer *Peer) RoutineNonce() {
elem.mutex.Lock()
// add to parallel and sequential queue
addToEncryptionQueue(device.queue.encryption, elem)
addToOutboundQueue(peer.queue.outbound, elem)
addToOutboundAndEncryptionQueues(peer.queue.outbound, device.queue.encryption, elem)
}
}
}
@@ -448,6 +462,19 @@ func (device *Device) RoutineEncryption() {
logDebug := device.log.Debug
defer func() {
for {
select {
case elem, ok := <-device.queue.encryption:
if ok && !elem.IsDropped() {
elem.Drop()
device.PutMessageBuffer(elem.buffer)
elem.mutex.Unlock()
}
default:
goto out
}
}
out:
logDebug.Println("Routine: encryption worker - stopped")
device.state.stopping.Done()
}()
@@ -490,11 +517,13 @@ func (device *Device) RoutineEncryption() {
// pad content to multiple of 16
mtu := int(atomic.LoadInt32(&device.tun.mtu))
rem := len(elem.packet) % PaddingMultiple
if rem > 0 {
for i := 0; i < PaddingMultiple-rem && len(elem.packet) < mtu; i++ {
elem.packet = append(elem.packet, 0)
lastUnit := len(elem.packet) % mtu
paddedSize := (lastUnit + PaddingMultiple - 1) & ^(PaddingMultiple - 1)
if paddedSize > mtu {
paddedSize = mtu
}
for i := len(elem.packet); i < paddedSize; i++ {
elem.packet = append(elem.packet, 0)
}
// encrypt content and release to consumer
@@ -521,8 +550,25 @@ func (peer *Peer) RoutineSequentialSender() {
device := peer.device
logDebug := device.log.Debug
logError := device.log.Error
defer func() {
for {
select {
case elem, ok := <-peer.queue.outbound:
if ok {
if !elem.IsDropped() {
device.PutMessageBuffer(elem.buffer)
elem.Drop()
}
device.PutOutboundElement(elem)
elem.mutex.Unlock()
}
default:
goto out
}
}
out:
logDebug.Println(peer, "- Routine: sequential sender - stopped")
peer.routines.stopping.Done()
}()
@@ -545,6 +591,7 @@ func (peer *Peer) RoutineSequentialSender() {
elem.mutex.Lock()
if elem.IsDropped() {
device.PutOutboundElement(elem)
continue
}
@@ -556,8 +603,9 @@ func (peer *Peer) RoutineSequentialSender() {
length := uint64(len(elem.packet))
err := peer.SendBuffer(elem.packet)
device.PutMessageBuffer(elem.buffer)
device.PutOutboundElement(elem)
if err != nil {
logDebug.Println("Failed to send authenticated packet to peer", peer)
logError.Println(peer, "- Failed to send data packet", err)
continue
}
atomic.AddUint64(&peer.stats.txBytes, length)

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package tai64n

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package tai64n

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*
* This is based heavily on timers.c from the kernel implementation.
*/

3
tun.go
View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package tun

View File

@@ -2,8 +2,7 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package tun
@@ -38,7 +37,8 @@ type sockaddrCtl struct {
type nativeTun struct {
name string
fd *os.File
tunFile *os.File
fd uintptr
rwcancel *rwcancel.RWCancel
events chan TUNEvent
errors chan error
@@ -172,14 +172,15 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun := &nativeTun{
fd: file,
tunFile: file,
fd: file.Fd(),
events: make(chan TUNEvent, 10),
errors: make(chan error, 1),
}
name, err := tun.Name()
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
@@ -191,19 +192,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
return iface.Index, nil
}()
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
tun.rwcancel, err = rwcancel.NewRWCancel(int(tun.fd))
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
@@ -227,7 +228,7 @@ func (tun *nativeTun) Name() (string, error) {
_, _, errno := unix.Syscall6(
unix.SYS_GETSOCKOPT,
uintptr(tun.fd.Fd()),
uintptr(tun.fd),
2, /* #define SYSPROTO_CONTROL 2 */
2, /* #define UTUN_OPT_IFNAME 2 */
uintptr(unsafe.Pointer(&ifName)),
@@ -242,7 +243,7 @@ func (tun *nativeTun) Name() (string, error) {
}
func (tun *nativeTun) File() *os.File {
return tun.fd
return tun.tunFile
}
func (tun *nativeTun) Events() chan TUNEvent {
@@ -255,7 +256,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
return 0, err
default:
buff := buff[offset-4:]
n, err := tun.fd.Read(buff[:])
n, err := tun.tunFile.Read(buff[:])
if n < 4 {
return 0, err
}
@@ -295,13 +296,13 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
// write
return tun.fd.Write(buff)
return tun.tunFile.Write(buff)
}
func (tun *nativeTun) Close() error {
var err3 error
err1 := tun.rwcancel.Cancel()
err2 := tun.fd.Close()
err2 := tun.tunFile.Close()
if tun.routeSocket != -1 {
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
err3 = unix.Close(tun.routeSocket)

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package tun
@@ -51,7 +51,8 @@ type ifstat struct {
type nativeTun struct {
name string
fd *os.File
tunFile *os.File
fd uintptr
rwcancel *rwcancel.RWCancel
events chan TUNEvent
errors chan error
@@ -237,15 +238,15 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
return nil, fmt.Errorf("interface %s already exists", name)
}
tunfile, err := os.OpenFile("/dev/tun", unix.O_RDWR, 0)
tunFile, err := os.OpenFile("/dev/tun", unix.O_RDWR, 0)
if err != nil {
return nil, err
}
tunfd := tunfile.Fd()
tunfd := tunFile.Fd()
assignedName, err := tunName(tunfd)
if err != nil {
tunfile.Close()
tunFile.Close()
return nil, err
}
@@ -293,25 +294,26 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
uintptr(unsafe.Pointer(&ifr)),
)
if errno != 0 {
tunfile.Close()
tunFile.Close()
tunDestroy(name)
return nil, fmt.Errorf("failed to rename %s to %s: %s", assignedName, name, errno.Error())
}
return CreateTUNFromFile(tunfile, mtu)
return CreateTUNFromFile(tunFile, mtu)
}
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun := &nativeTun{
fd: file,
tunFile: file,
fd: file.Fd(),
events: make(chan TUNEvent, 10),
errors: make(chan error, 1),
}
name, err := tun.Name()
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
@@ -323,19 +325,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
return iface.Index, nil
}()
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
tun.rwcancel, err = rwcancel.NewRWCancel(int(tun.fd))
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
@@ -351,7 +353,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
}
func (tun *nativeTun) Name() (string, error) {
name, err := tunName(tun.fd.Fd())
name, err := tunName(tun.fd)
if err != nil {
return "", err
}
@@ -360,7 +362,7 @@ func (tun *nativeTun) Name() (string, error) {
}
func (tun *nativeTun) File() *os.File {
return tun.fd
return tun.tunFile
}
func (tun *nativeTun) Events() chan TUNEvent {
@@ -373,7 +375,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
return 0, err
default:
buff := buff[offset-4:]
n, err := tun.fd.Read(buff[:])
n, err := tun.tunFile.Read(buff[:])
if n < 4 {
return 0, err
}
@@ -413,13 +415,13 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
// write
return tun.fd.Write(buff)
return tun.tunFile.Write(buff)
}
func (tun *nativeTun) Close() error {
var err4 error
err1 := tun.rwcancel.Cancel()
err2 := tun.fd.Close()
err2 := tun.tunFile.Close()
err3 := tunDestroy(tun.name)
if tun.routeSocket != -1 {
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)

View File

@@ -1,11 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
/* Copyright 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
package tun
/* Implementation of the TUN device interface for linux
@@ -32,7 +29,8 @@ const (
)
type nativeTun struct {
fd *os.File
tunFile *os.File
fd uintptr
fdCancel *rwcancel.RWCancel
index int32 // if index
name string // name of interface
@@ -46,7 +44,7 @@ type nativeTun struct {
}
func (tun *nativeTun) File() *os.File {
return tun.fd
return tun.tunFile
}
func (tun *nativeTun) routineHackListener() {
@@ -54,7 +52,7 @@ func (tun *nativeTun) routineHackListener() {
/* This is needed for the detection to work across network namespaces
* If you are reading this and know a better method, please get in touch.
*/
fd := int(tun.fd.Fd())
fd := int(tun.fd)
for {
_, err := unix.Write(fd, nil)
switch err {
@@ -269,7 +267,7 @@ func (tun *nativeTun) Name() (string, error) {
var ifr [ifReqSize]byte
_, _, errno := unix.Syscall(
unix.SYS_IOCTL,
tun.fd.Fd(),
tun.fd,
uintptr(unix.TUNGETIFF),
uintptr(unsafe.Pointer(&ifr[0])),
)
@@ -310,7 +308,7 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
// write
return tun.fd.Write(buff)
return tun.tunFile.Write(buff)
}
func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
@@ -319,10 +317,10 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
return 0, err
default:
if tun.nopi {
return tun.fd.Read(buff[offset:])
return tun.tunFile.Read(buff[offset:])
} else {
buff := buff[offset-4:]
n, err := tun.fd.Read(buff[:])
n, err := tun.tunFile.Read(buff[:])
if n < 4 {
return 0, err
}
@@ -357,7 +355,7 @@ func (tun *nativeTun) Close() error {
} else if tun.events != nil {
close(tun.events)
}
err2 := tun.fd.Close()
err2 := tun.tunFile.Close()
err3 := tun.fdCancel.Cancel()
if err1 != nil {
@@ -416,7 +414,8 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun := &nativeTun{
fd: file,
tunFile: file,
fd: file.Fd(),
events: make(chan TUNEvent, 5),
errors: make(chan error, 5),
statusListenersShutdown: make(chan struct{}),
@@ -424,15 +423,15 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
}
var err error
tun.fdCancel, err = rwcancel.NewRWCancel(int(file.Fd()))
tun.fdCancel, err = rwcancel.NewRWCancel(int(tun.fd))
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
_, err = tun.Name()
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
@@ -445,12 +444,12 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun.netlinkSock, err = createNetlinkSocket()
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
tun.netlinkCancel, err = rwcancel.NewRWCancel(tun.netlinkSock)
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package tun
@@ -29,7 +29,7 @@ const _TUNSIFMODE = 0x8004745d
type nativeTun struct {
name string
fd *os.File
tunFile *os.File
rwcancel *rwcancel.RWCancel
events chan TUNEvent
errors chan error
@@ -144,14 +144,14 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
tun := &nativeTun{
fd: file,
tunFile: file,
events: make(chan TUNEvent, 10),
errors: make(chan error, 1),
}
name, err := tun.Name()
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
@@ -163,19 +163,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
return iface.Index, nil
}()
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
if err != nil {
tun.fd.Close()
tun.tunFile.Close()
return nil, err
}
@@ -191,7 +191,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
}
func (tun *nativeTun) Name() (string, error) {
gostat, err := tun.fd.Stat()
gostat, err := tun.tunFile.Stat()
if err != nil {
tun.name = ""
return "", err
@@ -202,7 +202,7 @@ func (tun *nativeTun) Name() (string, error) {
}
func (tun *nativeTun) File() *os.File {
return tun.fd
return tun.tunFile
}
func (tun *nativeTun) Events() chan TUNEvent {
@@ -215,7 +215,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
return 0, err
default:
buff := buff[offset-4:]
n, err := tun.fd.Read(buff[:])
n, err := tun.tunFile.Read(buff[:])
if n < 4 {
return 0, err
}
@@ -255,13 +255,13 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
// write
return tun.fd.Write(buff)
return tun.tunFile.Write(buff)
}
func (tun *nativeTun) Close() error {
var err3 error
err1 := tun.rwcancel.Cancel()
err2 := tun.fd.Close()
err2 := tun.tunFile.Close()
if tun.routeSocket != -1 {
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
err3 = unix.Close(tun.routeSocket)

11
uapi.go
View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
@@ -75,6 +74,7 @@ func ipcGetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
send("public_key=" + peer.handshake.remoteStatic.ToHex())
send("preshared_key=" + peer.handshake.presharedKey.ToHex())
send("protocol_version=1")
if peer.endpoint != nil {
send("endpoint=" + peer.endpoint.DstToString())
}
@@ -362,6 +362,13 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
ones, _ := network.Mask.Size()
device.allowedips.Insert(network.IP, uint(ones), peer)
case "protocol_version":
if value != "1" {
logError.Println("Invalid protocol version:", value)
return &IPCError{Code: ipcErrorInvalid}
}
default:
logError.Println("Invalid UAPI peer key:", key)
return &IPCError{Code: ipcErrorInvalid}

View File

@@ -2,8 +2,7 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
@@ -18,12 +17,13 @@ import (
"unsafe"
)
var socketDirectory = "/var/run/wireguard"
const (
ipcErrorIO = -int64(unix.EIO)
ipcErrorProtocol = -int64(unix.EPROTO)
ipcErrorInvalid = -int64(unix.EINVAL)
ipcErrorPortInUse = -int64(unix.EADDRINUSE)
socketDirectory = "/var/run/wireguard"
socketName = "%s.sock"
)

View File

@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package main
@@ -16,12 +15,13 @@ import (
"path"
)
var socketDirectory = "/var/run/wireguard"
const (
ipcErrorIO = -int64(unix.EIO)
ipcErrorProtocol = -int64(unix.EPROTO)
ipcErrorInvalid = -int64(unix.EINVAL)
ipcErrorPortInUse = -int64(unix.EADDRINUSE)
socketDirectory = "/var/run/wireguard"
socketName = "%s.sock"
)

View File

@@ -1,2 +1,2 @@
package main
const WireGuardGoVersion = "0.0.20180613"
const WireGuardGoVersion = "0.0.20181018"

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2016 Andreas Auernhammer. All Rights Reserved.
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package xchacha20poly1305

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
*/
package xchacha20poly1305