Compare commits
18 Commits
0.0.201810
...
0.0.201812
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fde8334dc | ||
|
|
a8326ae753 | ||
|
|
05cc0c8298 | ||
|
|
c967f15e44 | ||
|
|
5ace0fdfe2 | ||
|
|
849fa400e9 | ||
|
|
651744561e | ||
|
|
4fd55daafe | ||
|
|
276bf973e8 | ||
|
|
c37c4ece9e | ||
|
|
b803276061 | ||
|
|
8be1fc9c00 | ||
|
|
738d027f0b | ||
|
|
60848b9c72 | ||
|
|
2e772194cf | ||
|
|
85b2378a07 | ||
|
|
fddb949002 | ||
|
|
5d6083df7e |
42
Gopkg.lock
generated
42
Gopkg.lock
generated
@@ -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
|
|
||||||
15
Gopkg.toml
15
Gopkg.toml
@@ -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
|
|
||||||
55
Makefile
55
Makefile
@@ -1,51 +1,42 @@
|
|||||||
PREFIX ?= /usr
|
PREFIX ?= /usr
|
||||||
DESTDIR ?=
|
DESTDIR ?=
|
||||||
BINDIR ?= $(PREFIX)/bin
|
BINDIR ?= $(PREFIX)/bin
|
||||||
|
export GOPATH ?= $(CURDIR)/.gopath
|
||||||
|
export GO111MODULE := on
|
||||||
|
|
||||||
ifeq ($(shell go env GOOS),linux)
|
all: generate-version-and-build
|
||||||
ifeq ($(wildcard .git),)
|
|
||||||
|
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.)
|
$(error Do not build this for Linux. Instead use the Linux kernel module. See wireguard.com/install/ for more info.)
|
||||||
else
|
else
|
||||||
$(shell printf 'package main\nconst UseTheKernelModuleInstead = 0xdeadbabe\n' > ireallywantobuildon_linux.go)
|
ireallywantobuildon_linux.go:
|
||||||
endif
|
@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
|
endif
|
||||||
|
|
||||||
all: wireguard-go
|
MAKEFLAGS += --no-print-directory
|
||||||
|
|
||||||
export GOPATH := $(CURDIR)/.gopath
|
generate-version-and-build:
|
||||||
export PATH := $(PATH):$(CURDIR)/.gopath/bin
|
|
||||||
GO_IMPORT_PATH := git.zx2c4.com/wireguard-go
|
|
||||||
|
|
||||||
version.go:
|
|
||||||
@export GIT_CEILING_DIRECTORIES="$(realpath $(CURDIR)/..)" && \
|
@export GIT_CEILING_DIRECTORIES="$(realpath $(CURDIR)/..)" && \
|
||||||
tag="$$(git describe --dirty 2>/dev/null)" && \
|
tag="$$(git describe --dirty 2>/dev/null)" && \
|
||||||
ver="$$(printf 'package main\nconst WireGuardGoVersion = "%s"\n' "$$tag")" && \
|
ver="$$(printf 'package main\nconst WireGuardGoVersion = "%s"\n' "$$tag")" && \
|
||||||
[ "$$(cat $@ 2>/dev/null)" != "$$ver" ] && \
|
[ "$$(cat version.go 2>/dev/null)" != "$$ver" ] && \
|
||||||
echo "$$ver" > $@ && \
|
echo "$$ver" > version.go && \
|
||||||
git update-index --assume-unchanged $@ || true
|
git update-index --assume-unchanged version.go || true
|
||||||
|
@$(MAKE) wireguard-go
|
||||||
|
|
||||||
.gopath/.created:
|
wireguard-go: $(wildcard *.go) $(wildcard */*.go)
|
||||||
rm -rf .gopath
|
go build -v -o "$@"
|
||||||
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)
|
|
||||||
|
|
||||||
install: wireguard-go
|
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:
|
clean:
|
||||||
rm -f wireguard-go
|
rm -f wireguard-go
|
||||||
|
|
||||||
update-dep: | .gopath/.created
|
.PHONY: all clean install generate-version-and-build
|
||||||
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
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ This will run on OpenBSD. It does not yet support sticky sockets. Fwmark is mapp
|
|||||||
|
|
||||||
## Building
|
## 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
|
$ git clone https://git.zx2c4.com/wireguard-go
|
||||||
|
|||||||
@@ -8,10 +8,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -171,47 +169,3 @@ func (bind *NativeBind) Send(buff []byte, endpoint Endpoint) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var fwmarkIoctl int
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "linux", "android":
|
|
||||||
fwmarkIoctl = 36 /* unix.SO_MARK */
|
|
||||||
case "freebsd":
|
|
||||||
fwmarkIoctl = 0x1015 /* unix.SO_USER_COOKIE */
|
|
||||||
case "openbsd":
|
|
||||||
fwmarkIoctl = 0x1021 /* unix.SO_RTABLE */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bind *NativeBind) SetMark(mark uint32) error {
|
|
||||||
if fwmarkIoctl == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if bind.ipv4 != nil {
|
|
||||||
fd, err := bind.ipv4.SyscallConn()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = fd.Control(func(fd uintptr) {
|
|
||||||
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if bind.ipv6 != nil {
|
|
||||||
fd, err := bind.ipv6.SyscallConn()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = fd.Control(func(fd uintptr) {
|
|
||||||
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
19
cookie.go
19
cookie.go
@@ -8,7 +8,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"git.zx2c4.com/wireguard-go/xchacha20poly1305"
|
|
||||||
"golang.org/x/crypto/blake2s"
|
"golang.org/x/crypto/blake2s"
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -163,13 +162,8 @@ func (st *CookieChecker) CreateReply(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
xchacha20poly1305.Encrypt(
|
xchapoly, _ := chacha20poly1305.NewX(st.mac2.encryptionKey[:])
|
||||||
reply.Cookie[:0],
|
xchapoly.Seal(reply.Cookie[:0], reply.Nonce[:], cookie[:], msg[smac1:smac2])
|
||||||
&reply.Nonce,
|
|
||||||
cookie[:],
|
|
||||||
msg[smac1:smac2],
|
|
||||||
&st.mac2.encryptionKey,
|
|
||||||
)
|
|
||||||
|
|
||||||
st.mutex.RUnlock()
|
st.mutex.RUnlock()
|
||||||
|
|
||||||
@@ -207,13 +201,8 @@ func (st *CookieGenerator) ConsumeReply(msg *MessageCookieReply) bool {
|
|||||||
|
|
||||||
var cookie [blake2s.Size128]byte
|
var cookie [blake2s.Size128]byte
|
||||||
|
|
||||||
_, err := xchacha20poly1305.Decrypt(
|
xchapoly, _ := chacha20poly1305.NewX(st.mac2.encryptionKey[:])
|
||||||
cookie[:0],
|
_, err := xchapoly.Open(cookie[:0], msg.Nonce[:], msg.Cookie[:], st.mac2.lastMAC1[:])
|
||||||
&msg.Nonce,
|
|
||||||
msg.Cookie[:],
|
|
||||||
st.mac2.lastMAC1[:],
|
|
||||||
&st.mac2.encryptionKey,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
|||||||
7
go.mod
Normal file
7
go.mod
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
module git.zx2c4.com/wireguard-go
|
||||||
|
|
||||||
|
require (
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9
|
||||||
|
golang.org/x/net v0.0.0-20181207154023-610586996380
|
||||||
|
golang.org/x/sys v0.0.0-20181210030007-2a47403f2ae5
|
||||||
|
)
|
||||||
6
go.sum
Normal file
6
go.sum
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/net v0.0.0-20181207154023-610586996380 h1:zPQexyRtNYBc7bcHmehl1dH6TB3qn8zytv8cBGLDNY0=
|
||||||
|
golang.org/x/net v0.0.0-20181207154023-610586996380/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/sys v0.0.0-20181210030007-2a47403f2ae5 h1:SlFRMb9PEnqzqnBRCynVOhxv4vHjB2lnIoxK6p5nzFM=
|
||||||
|
golang.org/x/sys v0.0.0-20181210030007-2a47403f2ae5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
12
mark_default.go
Normal file
12
mark_default.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// +build !linux,!openbsd,!freebsd
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func (bind *NativeBind) SetMark(mark uint32) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
57
mark_unix.go
Normal file
57
mark_unix.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// +build android openbsd freebsd
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fwmarkIoctl int
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "linux", "android":
|
||||||
|
fwmarkIoctl = 36 /* unix.SO_MARK */
|
||||||
|
case "freebsd":
|
||||||
|
fwmarkIoctl = 0x1015 /* unix.SO_USER_COOKIE */
|
||||||
|
case "openbsd":
|
||||||
|
fwmarkIoctl = 0x1021 /* unix.SO_RTABLE */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bind *NativeBind) SetMark(mark uint32) error {
|
||||||
|
if fwmarkIoctl == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if bind.ipv4 != nil {
|
||||||
|
fd, err := bind.ipv4.SyscallConn()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = fd.Control(func(fd uintptr) {
|
||||||
|
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if bind.ipv6 != nil {
|
||||||
|
fd, err := bind.ipv6.SyscallConn()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = fd.Control(func(fd uintptr) {
|
||||||
|
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -89,7 +89,7 @@ type MessageTransport struct {
|
|||||||
type MessageCookieReply struct {
|
type MessageCookieReply struct {
|
||||||
Type uint32
|
Type uint32
|
||||||
Receiver uint32
|
Receiver uint32
|
||||||
Nonce [24]byte
|
Nonce [chacha20poly1305.NonceSizeX]byte
|
||||||
Cookie [blake2s.Size128 + poly1305.TagSize]byte
|
Cookie [blake2s.Size128 + poly1305.TagSize]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
|
|||||||
device.net.stopping.Done()
|
device.net.stopping.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
logDebug.Println("Routine: receive incoming IPv" + strconv.Itoa(IP) + " - starting")
|
logDebug.Println("Routine: receive incoming IPv" + strconv.Itoa(IP) + " - started")
|
||||||
device.net.starting.Done()
|
device.net.starting.Done()
|
||||||
|
|
||||||
// receive datagrams until conn is closed
|
// receive datagrams until conn is closed
|
||||||
@@ -351,7 +351,10 @@ func (device *Device) RoutineHandshake() {
|
|||||||
// consume reply
|
// consume reply
|
||||||
|
|
||||||
if peer := entry.peer; peer.isRunning.Get() {
|
if peer := entry.peer; peer.isRunning.Get() {
|
||||||
peer.cookieGenerator.ConsumeReply(&reply)
|
logDebug.Println("Receiving cookie response from ", elem.endpoint.DstToString())
|
||||||
|
if !peer.cookieGenerator.ConsumeReply(&reply) {
|
||||||
|
logDebug.Println("Could not decrypt invalid cookie response")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// +build !freebsd
|
|
||||||
|
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package rwcancel
|
|
||||||
|
|
||||||
import "golang.org/x/sys/unix"
|
|
||||||
|
|
||||||
type fdSet struct {
|
|
||||||
fdset unix.FdSet
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fdset *fdSet) set(i int) {
|
|
||||||
bits := 32 << (^uint(0) >> 63)
|
|
||||||
fdset.fdset.X__fds_bits[i/bits] |= 1 << uint(i%bits)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fdset *fdSet) check(i int) bool {
|
|
||||||
bits := 32 << (^uint(0) >> 63)
|
|
||||||
return (fdset.fdset.X__fds_bits[i/bits] & (1 << uint(i%bits))) != 0
|
|
||||||
}
|
|
||||||
3
send.go
3
send.go
@@ -206,7 +206,7 @@ func (peer *Peer) SendHandshakeResponse() error {
|
|||||||
|
|
||||||
func (device *Device) SendHandshakeCookie(initiatingElem *QueueHandshakeElement) error {
|
func (device *Device) SendHandshakeCookie(initiatingElem *QueueHandshakeElement) error {
|
||||||
|
|
||||||
device.log.Debug.Println("Sending cookie reply to:", initiatingElem.endpoint.DstToString())
|
device.log.Debug.Println("Sending cookie response for denied handshake message for", initiatingElem.endpoint.DstToString())
|
||||||
|
|
||||||
sender := binary.LittleEndian.Uint32(initiatingElem.packet[4:8])
|
sender := binary.LittleEndian.Uint32(initiatingElem.packet[4:8])
|
||||||
reply, err := device.cookieChecker.CreateReply(initiatingElem.packet, sender, initiatingElem.endpoint.DstToBytes())
|
reply, err := device.cookieChecker.CreateReply(initiatingElem.packet, sender, initiatingElem.endpoint.DstToBytes())
|
||||||
@@ -562,7 +562,6 @@ func (peer *Peer) RoutineSequentialSender() {
|
|||||||
elem.Drop()
|
elem.Drop()
|
||||||
}
|
}
|
||||||
device.PutOutboundElement(elem)
|
device.PutOutboundElement(elem)
|
||||||
elem.mutex.Unlock()
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
goto out
|
goto out
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func Now() Timestamp {
|
|||||||
var tai64n Timestamp
|
var tai64n Timestamp
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
secs := base + uint64(now.Unix())
|
secs := base + uint64(now.Unix())
|
||||||
nano := uint32(now.UnixNano())
|
nano := uint32(now.Nanosecond())
|
||||||
binary.BigEndian.PutUint64(tai64n[:], secs)
|
binary.BigEndian.PutUint64(tai64n[:], secs)
|
||||||
binary.BigEndian.PutUint32(tai64n[8:], nano)
|
binary.BigEndian.PutUint32(tai64n[8:], nano)
|
||||||
return tai64n
|
return tai64n
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ func (peer *Peer) timersActive() bool {
|
|||||||
|
|
||||||
func expiredRetransmitHandshake(peer *Peer) {
|
func expiredRetransmitHandshake(peer *Peer) {
|
||||||
if atomic.LoadUint32(&peer.timers.handshakeAttempts) > MaxTimerHandshakes {
|
if atomic.LoadUint32(&peer.timers.handshakeAttempts) > MaxTimerHandshakes {
|
||||||
peer.device.log.Debug.Printf("%s: Handshake did not complete after %d attempts, giving up\n", peer, MaxTimerHandshakes+2)
|
peer.device.log.Debug.Printf("%s - Handshake did not complete after %d attempts, giving up\n", peer, MaxTimerHandshakes+2)
|
||||||
|
|
||||||
if peer.timersActive() {
|
if peer.timersActive() {
|
||||||
peer.timers.sendKeepalive.Del()
|
peer.timers.sendKeepalive.Del()
|
||||||
@@ -98,7 +98,7 @@ func expiredRetransmitHandshake(peer *Peer) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
atomic.AddUint32(&peer.timers.handshakeAttempts, 1)
|
atomic.AddUint32(&peer.timers.handshakeAttempts, 1)
|
||||||
peer.device.log.Debug.Printf("%s: Handshake did not complete after %d seconds, retrying (try %d)\n", peer, int(RekeyTimeout.Seconds()), atomic.LoadUint32(&peer.timers.handshakeAttempts)+1)
|
peer.device.log.Debug.Printf("%s - Handshake did not complete after %d seconds, retrying (try %d)\n", peer, int(RekeyTimeout.Seconds()), atomic.LoadUint32(&peer.timers.handshakeAttempts)+1)
|
||||||
|
|
||||||
/* We clear the endpoint address src address, in case this is the cause of trouble. */
|
/* We clear the endpoint address src address, in case this is the cause of trouble. */
|
||||||
peer.mutex.Lock()
|
peer.mutex.Lock()
|
||||||
@@ -122,7 +122,7 @@ func expiredSendKeepalive(peer *Peer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func expiredNewHandshake(peer *Peer) {
|
func expiredNewHandshake(peer *Peer) {
|
||||||
peer.device.log.Debug.Printf("%s: Retrying handshake because we stopped hearing back after %d seconds\n", peer, int((KeepaliveTimeout + RekeyTimeout).Seconds()))
|
peer.device.log.Debug.Printf("%s - Retrying handshake because we stopped hearing back after %d seconds\n", peer, int((KeepaliveTimeout + RekeyTimeout).Seconds()))
|
||||||
/* We clear the endpoint address src address, in case this is the cause of trouble. */
|
/* We clear the endpoint address src address, in case this is the cause of trouble. */
|
||||||
peer.mutex.Lock()
|
peer.mutex.Lock()
|
||||||
if peer.endpoint != nil {
|
if peer.endpoint != nil {
|
||||||
@@ -134,7 +134,7 @@ func expiredNewHandshake(peer *Peer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func expiredZeroKeyMaterial(peer *Peer) {
|
func expiredZeroKeyMaterial(peer *Peer) {
|
||||||
peer.device.log.Debug.Printf("%s: Removing all keys, since we haven't received a new one in %d seconds\n", peer, int((RejectAfterTime * 3).Seconds()))
|
peer.device.log.Debug.Printf("%s - Removing all keys, since we haven't received a new one in %d seconds\n", peer, int((RejectAfterTime * 3).Seconds()))
|
||||||
peer.ZeroAndFlushAll()
|
peer.ZeroAndFlushAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// +build !ios
|
|
||||||
|
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
|
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
|
||||||
@@ -37,7 +35,8 @@ type sockaddrCtl struct {
|
|||||||
|
|
||||||
type nativeTun struct {
|
type nativeTun struct {
|
||||||
name string
|
name string
|
||||||
fd *os.File
|
tunFile *os.File
|
||||||
|
fd uintptr
|
||||||
rwcancel *rwcancel.RWCancel
|
rwcancel *rwcancel.RWCancel
|
||||||
events chan TUNEvent
|
events chan TUNEvent
|
||||||
errors chan error
|
errors chan error
|
||||||
@@ -171,14 +170,15 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
|||||||
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
||||||
|
|
||||||
tun := &nativeTun{
|
tun := &nativeTun{
|
||||||
fd: file,
|
tunFile: file,
|
||||||
|
fd: file.Fd(),
|
||||||
events: make(chan TUNEvent, 10),
|
events: make(chan TUNEvent, 10),
|
||||||
errors: make(chan error, 1),
|
errors: make(chan error, 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
name, err := tun.Name()
|
name, err := tun.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,19 +190,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
|||||||
return iface.Index, nil
|
return iface.Index, nil
|
||||||
}()
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
|
tun.rwcancel, err = rwcancel.NewRWCancel(int(tun.fd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
|
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ func (tun *nativeTun) Name() (string, error) {
|
|||||||
|
|
||||||
_, _, errno := unix.Syscall6(
|
_, _, errno := unix.Syscall6(
|
||||||
unix.SYS_GETSOCKOPT,
|
unix.SYS_GETSOCKOPT,
|
||||||
uintptr(tun.fd.Fd()),
|
uintptr(tun.fd),
|
||||||
2, /* #define SYSPROTO_CONTROL 2 */
|
2, /* #define SYSPROTO_CONTROL 2 */
|
||||||
2, /* #define UTUN_OPT_IFNAME 2 */
|
2, /* #define UTUN_OPT_IFNAME 2 */
|
||||||
uintptr(unsafe.Pointer(&ifName)),
|
uintptr(unsafe.Pointer(&ifName)),
|
||||||
@@ -241,7 +241,7 @@ func (tun *nativeTun) Name() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) File() *os.File {
|
func (tun *nativeTun) File() *os.File {
|
||||||
return tun.fd
|
return tun.tunFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) Events() chan TUNEvent {
|
func (tun *nativeTun) Events() chan TUNEvent {
|
||||||
@@ -254,7 +254,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
default:
|
default:
|
||||||
buff := buff[offset-4:]
|
buff := buff[offset-4:]
|
||||||
n, err := tun.fd.Read(buff[:])
|
n, err := tun.tunFile.Read(buff[:])
|
||||||
if n < 4 {
|
if n < 4 {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -294,13 +294,13 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
|
|||||||
|
|
||||||
// write
|
// write
|
||||||
|
|
||||||
return tun.fd.Write(buff)
|
return tun.tunFile.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) Close() error {
|
func (tun *nativeTun) Close() error {
|
||||||
var err3 error
|
var err3 error
|
||||||
err1 := tun.rwcancel.Cancel()
|
err1 := tun.rwcancel.Cancel()
|
||||||
err2 := tun.fd.Close()
|
err2 := tun.tunFile.Close()
|
||||||
if tun.routeSocket != -1 {
|
if tun.routeSocket != -1 {
|
||||||
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
|
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
|
||||||
err3 = unix.Close(tun.routeSocket)
|
err3 = unix.Close(tun.routeSocket)
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ type ifstat struct {
|
|||||||
|
|
||||||
type nativeTun struct {
|
type nativeTun struct {
|
||||||
name string
|
name string
|
||||||
fd *os.File
|
tunFile *os.File
|
||||||
|
fd uintptr
|
||||||
rwcancel *rwcancel.RWCancel
|
rwcancel *rwcancel.RWCancel
|
||||||
events chan TUNEvent
|
events chan TUNEvent
|
||||||
errors chan error
|
errors chan error
|
||||||
@@ -237,15 +238,15 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
|||||||
return nil, fmt.Errorf("interface %s already exists", name)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tunfd := tunfile.Fd()
|
tunfd := tunFile.Fd()
|
||||||
assignedName, err := tunName(tunfd)
|
assignedName, err := tunName(tunfd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tunfile.Close()
|
tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,25 +294,26 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
|||||||
uintptr(unsafe.Pointer(&ifr)),
|
uintptr(unsafe.Pointer(&ifr)),
|
||||||
)
|
)
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
tunfile.Close()
|
tunFile.Close()
|
||||||
tunDestroy(name)
|
tunDestroy(name)
|
||||||
return nil, fmt.Errorf("failed to rename %s to %s: %s", assignedName, name, errno.Error())
|
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) {
|
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
||||||
|
|
||||||
tun := &nativeTun{
|
tun := &nativeTun{
|
||||||
fd: file,
|
tunFile: file,
|
||||||
|
fd: file.Fd(),
|
||||||
events: make(chan TUNEvent, 10),
|
events: make(chan TUNEvent, 10),
|
||||||
errors: make(chan error, 1),
|
errors: make(chan error, 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
name, err := tun.Name()
|
name, err := tun.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,19 +325,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
|||||||
return iface.Index, nil
|
return iface.Index, nil
|
||||||
}()
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
|
tun.rwcancel, err = rwcancel.NewRWCancel(int(tun.fd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
|
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,7 +353,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) Name() (string, error) {
|
func (tun *nativeTun) Name() (string, error) {
|
||||||
name, err := tunName(tun.fd.Fd())
|
name, err := tunName(tun.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -360,7 +362,7 @@ func (tun *nativeTun) Name() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) File() *os.File {
|
func (tun *nativeTun) File() *os.File {
|
||||||
return tun.fd
|
return tun.tunFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) Events() chan TUNEvent {
|
func (tun *nativeTun) Events() chan TUNEvent {
|
||||||
@@ -373,7 +375,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
default:
|
default:
|
||||||
buff := buff[offset-4:]
|
buff := buff[offset-4:]
|
||||||
n, err := tun.fd.Read(buff[:])
|
n, err := tun.tunFile.Read(buff[:])
|
||||||
if n < 4 {
|
if n < 4 {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -413,13 +415,13 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
|
|||||||
|
|
||||||
// write
|
// write
|
||||||
|
|
||||||
return tun.fd.Write(buff)
|
return tun.tunFile.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) Close() error {
|
func (tun *nativeTun) Close() error {
|
||||||
var err4 error
|
var err4 error
|
||||||
err1 := tun.rwcancel.Cancel()
|
err1 := tun.rwcancel.Cancel()
|
||||||
err2 := tun.fd.Close()
|
err2 := tun.tunFile.Close()
|
||||||
err3 := tunDestroy(tun.name)
|
err3 := tunDestroy(tun.name)
|
||||||
if tun.routeSocket != -1 {
|
if tun.routeSocket != -1 {
|
||||||
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
|
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type nativeTun struct {
|
type nativeTun struct {
|
||||||
fd *os.File
|
tunFile *os.File
|
||||||
|
fd uintptr
|
||||||
fdCancel *rwcancel.RWCancel
|
fdCancel *rwcancel.RWCancel
|
||||||
index int32 // if index
|
index int32 // if index
|
||||||
name string // name of interface
|
name string // name of interface
|
||||||
@@ -43,7 +44,7 @@ type nativeTun struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) File() *os.File {
|
func (tun *nativeTun) File() *os.File {
|
||||||
return tun.fd
|
return tun.tunFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) routineHackListener() {
|
func (tun *nativeTun) routineHackListener() {
|
||||||
@@ -51,7 +52,7 @@ func (tun *nativeTun) routineHackListener() {
|
|||||||
/* This is needed for the detection to work across network namespaces
|
/* 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.
|
* If you are reading this and know a better method, please get in touch.
|
||||||
*/
|
*/
|
||||||
fd := int(tun.fd.Fd())
|
fd := int(tun.fd)
|
||||||
for {
|
for {
|
||||||
_, err := unix.Write(fd, nil)
|
_, err := unix.Write(fd, nil)
|
||||||
switch err {
|
switch err {
|
||||||
@@ -266,7 +267,7 @@ func (tun *nativeTun) Name() (string, error) {
|
|||||||
var ifr [ifReqSize]byte
|
var ifr [ifReqSize]byte
|
||||||
_, _, errno := unix.Syscall(
|
_, _, errno := unix.Syscall(
|
||||||
unix.SYS_IOCTL,
|
unix.SYS_IOCTL,
|
||||||
tun.fd.Fd(),
|
tun.fd,
|
||||||
uintptr(unix.TUNGETIFF),
|
uintptr(unix.TUNGETIFF),
|
||||||
uintptr(unsafe.Pointer(&ifr[0])),
|
uintptr(unsafe.Pointer(&ifr[0])),
|
||||||
)
|
)
|
||||||
@@ -307,7 +308,7 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
|
|||||||
|
|
||||||
// write
|
// write
|
||||||
|
|
||||||
return tun.fd.Write(buff)
|
return tun.tunFile.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
||||||
@@ -316,10 +317,10 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
default:
|
default:
|
||||||
if tun.nopi {
|
if tun.nopi {
|
||||||
return tun.fd.Read(buff[offset:])
|
return tun.tunFile.Read(buff[offset:])
|
||||||
} else {
|
} else {
|
||||||
buff := buff[offset-4:]
|
buff := buff[offset-4:]
|
||||||
n, err := tun.fd.Read(buff[:])
|
n, err := tun.tunFile.Read(buff[:])
|
||||||
if n < 4 {
|
if n < 4 {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -354,7 +355,7 @@ func (tun *nativeTun) Close() error {
|
|||||||
} else if tun.events != nil {
|
} else if tun.events != nil {
|
||||||
close(tun.events)
|
close(tun.events)
|
||||||
}
|
}
|
||||||
err2 := tun.fd.Close()
|
err2 := tun.tunFile.Close()
|
||||||
err3 := tun.fdCancel.Cancel()
|
err3 := tun.fdCancel.Cancel()
|
||||||
|
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
@@ -367,21 +368,11 @@ func (tun *nativeTun) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
||||||
|
|
||||||
// open clone device
|
|
||||||
|
|
||||||
// HACK: we open it as a raw Fd first, so that f.nonblock=false
|
|
||||||
// when we make it into a file object.
|
|
||||||
nfd, err := unix.Open(cloneDevicePath, os.O_RDWR, 0)
|
nfd, err := unix.Open(cloneDevicePath, os.O_RDWR, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = unix.SetNonblock(nfd, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fd := os.NewFile(uintptr(nfd), cloneDevicePath)
|
fd := os.NewFile(uintptr(nfd), cloneDevicePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -413,7 +404,8 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
|||||||
|
|
||||||
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
||||||
tun := &nativeTun{
|
tun := &nativeTun{
|
||||||
fd: file,
|
tunFile: file,
|
||||||
|
fd: file.Fd(),
|
||||||
events: make(chan TUNEvent, 5),
|
events: make(chan TUNEvent, 5),
|
||||||
errors: make(chan error, 5),
|
errors: make(chan error, 5),
|
||||||
statusListenersShutdown: make(chan struct{}),
|
statusListenersShutdown: make(chan struct{}),
|
||||||
@@ -421,15 +413,15 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
|||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
tun.fdCancel, err = rwcancel.NewRWCancel(int(file.Fd()))
|
tun.fdCancel, err = rwcancel.NewRWCancel(int(tun.fd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = tun.Name()
|
_, err = tun.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,12 +434,12 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
|||||||
|
|
||||||
tun.netlinkSock, err = createNetlinkSocket()
|
tun.netlinkSock, err = createNetlinkSocket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tun.netlinkCancel, err = rwcancel.NewRWCancel(tun.netlinkSock)
|
tun.netlinkCancel, err = rwcancel.NewRWCancel(tun.netlinkSock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ const _TUNSIFMODE = 0x8004745d
|
|||||||
|
|
||||||
type nativeTun struct {
|
type nativeTun struct {
|
||||||
name string
|
name string
|
||||||
fd *os.File
|
tunFile *os.File
|
||||||
rwcancel *rwcancel.RWCancel
|
rwcancel *rwcancel.RWCancel
|
||||||
events chan TUNEvent
|
events chan TUNEvent
|
||||||
errors chan error
|
errors chan error
|
||||||
@@ -144,14 +144,14 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
|||||||
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
||||||
|
|
||||||
tun := &nativeTun{
|
tun := &nativeTun{
|
||||||
fd: file,
|
tunFile: file,
|
||||||
events: make(chan TUNEvent, 10),
|
events: make(chan TUNEvent, 10),
|
||||||
errors: make(chan error, 1),
|
errors: make(chan error, 1),
|
||||||
}
|
}
|
||||||
|
|
||||||
name, err := tun.Name()
|
name, err := tun.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,19 +163,19 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
|||||||
return iface.Index, nil
|
return iface.Index, nil
|
||||||
}()
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
|
tun.rwcancel, err = rwcancel.NewRWCancel(int(file.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
|
tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.fd.Close()
|
tun.tunFile.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (TUNDevice, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) Name() (string, error) {
|
func (tun *nativeTun) Name() (string, error) {
|
||||||
gostat, err := tun.fd.Stat()
|
gostat, err := tun.tunFile.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tun.name = ""
|
tun.name = ""
|
||||||
return "", err
|
return "", err
|
||||||
@@ -202,7 +202,7 @@ func (tun *nativeTun) Name() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) File() *os.File {
|
func (tun *nativeTun) File() *os.File {
|
||||||
return tun.fd
|
return tun.tunFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) Events() chan TUNEvent {
|
func (tun *nativeTun) Events() chan TUNEvent {
|
||||||
@@ -215,7 +215,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
default:
|
default:
|
||||||
buff := buff[offset-4:]
|
buff := buff[offset-4:]
|
||||||
n, err := tun.fd.Read(buff[:])
|
n, err := tun.tunFile.Read(buff[:])
|
||||||
if n < 4 {
|
if n < 4 {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -255,13 +255,13 @@ func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
|
|||||||
|
|
||||||
// write
|
// write
|
||||||
|
|
||||||
return tun.fd.Write(buff)
|
return tun.tunFile.Write(buff)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *nativeTun) Close() error {
|
func (tun *nativeTun) Close() error {
|
||||||
var err3 error
|
var err3 error
|
||||||
err1 := tun.rwcancel.Cancel()
|
err1 := tun.rwcancel.Cancel()
|
||||||
err2 := tun.fd.Close()
|
err2 := tun.tunFile.Close()
|
||||||
if tun.routeSocket != -1 {
|
if tun.routeSocket != -1 {
|
||||||
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
|
unix.Shutdown(tun.routeSocket, unix.SHUT_RDWR)
|
||||||
err3 = unix.Close(tun.routeSocket)
|
err3 = unix.Close(tun.routeSocket)
|
||||||
|
|||||||
2
uapi.go
2
uapi.go
@@ -307,7 +307,7 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
|
|||||||
|
|
||||||
// update persistent keepalive interval
|
// update persistent keepalive interval
|
||||||
|
|
||||||
logDebug.Println(peer, "- UAPI: Updating persistent keepalive interva")
|
logDebug.Println(peer, "- UAPI: Updating persistent keepalive interval")
|
||||||
|
|
||||||
secs, err := strconv.ParseUint(value, 10, 16)
|
secs, err := strconv.ParseUint(value, 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
package main
|
package main
|
||||||
const WireGuardGoVersion = "0.0.20181001"
|
const WireGuardGoVersion = "0.0.20181222"
|
||||||
|
|||||||
@@ -1,171 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: MIT
|
|
||||||
*
|
|
||||||
* Copyright (C) 2016 Andreas Auernhammer. All Rights Reserved.
|
|
||||||
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package xchacha20poly1305
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
|
||||||
)
|
|
||||||
|
|
||||||
func hChaCha20(out *[32]byte, nonce []byte, key *[32]byte) {
|
|
||||||
|
|
||||||
v00 := uint32(0x61707865)
|
|
||||||
v01 := uint32(0x3320646e)
|
|
||||||
v02 := uint32(0x79622d32)
|
|
||||||
v03 := uint32(0x6b206574)
|
|
||||||
|
|
||||||
v04 := binary.LittleEndian.Uint32(key[0:])
|
|
||||||
v05 := binary.LittleEndian.Uint32(key[4:])
|
|
||||||
v06 := binary.LittleEndian.Uint32(key[8:])
|
|
||||||
v07 := binary.LittleEndian.Uint32(key[12:])
|
|
||||||
v08 := binary.LittleEndian.Uint32(key[16:])
|
|
||||||
v09 := binary.LittleEndian.Uint32(key[20:])
|
|
||||||
v10 := binary.LittleEndian.Uint32(key[24:])
|
|
||||||
v11 := binary.LittleEndian.Uint32(key[28:])
|
|
||||||
v12 := binary.LittleEndian.Uint32(nonce[0:])
|
|
||||||
v13 := binary.LittleEndian.Uint32(nonce[4:])
|
|
||||||
v14 := binary.LittleEndian.Uint32(nonce[8:])
|
|
||||||
v15 := binary.LittleEndian.Uint32(nonce[12:])
|
|
||||||
|
|
||||||
for i := 0; i < 20; i += 2 {
|
|
||||||
v00 += v04
|
|
||||||
v12 ^= v00
|
|
||||||
v12 = (v12 << 16) | (v12 >> 16)
|
|
||||||
v08 += v12
|
|
||||||
v04 ^= v08
|
|
||||||
v04 = (v04 << 12) | (v04 >> 20)
|
|
||||||
v00 += v04
|
|
||||||
v12 ^= v00
|
|
||||||
v12 = (v12 << 8) | (v12 >> 24)
|
|
||||||
v08 += v12
|
|
||||||
v04 ^= v08
|
|
||||||
v04 = (v04 << 7) | (v04 >> 25)
|
|
||||||
v01 += v05
|
|
||||||
v13 ^= v01
|
|
||||||
v13 = (v13 << 16) | (v13 >> 16)
|
|
||||||
v09 += v13
|
|
||||||
v05 ^= v09
|
|
||||||
v05 = (v05 << 12) | (v05 >> 20)
|
|
||||||
v01 += v05
|
|
||||||
v13 ^= v01
|
|
||||||
v13 = (v13 << 8) | (v13 >> 24)
|
|
||||||
v09 += v13
|
|
||||||
v05 ^= v09
|
|
||||||
v05 = (v05 << 7) | (v05 >> 25)
|
|
||||||
v02 += v06
|
|
||||||
v14 ^= v02
|
|
||||||
v14 = (v14 << 16) | (v14 >> 16)
|
|
||||||
v10 += v14
|
|
||||||
v06 ^= v10
|
|
||||||
v06 = (v06 << 12) | (v06 >> 20)
|
|
||||||
v02 += v06
|
|
||||||
v14 ^= v02
|
|
||||||
v14 = (v14 << 8) | (v14 >> 24)
|
|
||||||
v10 += v14
|
|
||||||
v06 ^= v10
|
|
||||||
v06 = (v06 << 7) | (v06 >> 25)
|
|
||||||
v03 += v07
|
|
||||||
v15 ^= v03
|
|
||||||
v15 = (v15 << 16) | (v15 >> 16)
|
|
||||||
v11 += v15
|
|
||||||
v07 ^= v11
|
|
||||||
v07 = (v07 << 12) | (v07 >> 20)
|
|
||||||
v03 += v07
|
|
||||||
v15 ^= v03
|
|
||||||
v15 = (v15 << 8) | (v15 >> 24)
|
|
||||||
v11 += v15
|
|
||||||
v07 ^= v11
|
|
||||||
v07 = (v07 << 7) | (v07 >> 25)
|
|
||||||
v00 += v05
|
|
||||||
v15 ^= v00
|
|
||||||
v15 = (v15 << 16) | (v15 >> 16)
|
|
||||||
v10 += v15
|
|
||||||
v05 ^= v10
|
|
||||||
v05 = (v05 << 12) | (v05 >> 20)
|
|
||||||
v00 += v05
|
|
||||||
v15 ^= v00
|
|
||||||
v15 = (v15 << 8) | (v15 >> 24)
|
|
||||||
v10 += v15
|
|
||||||
v05 ^= v10
|
|
||||||
v05 = (v05 << 7) | (v05 >> 25)
|
|
||||||
v01 += v06
|
|
||||||
v12 ^= v01
|
|
||||||
v12 = (v12 << 16) | (v12 >> 16)
|
|
||||||
v11 += v12
|
|
||||||
v06 ^= v11
|
|
||||||
v06 = (v06 << 12) | (v06 >> 20)
|
|
||||||
v01 += v06
|
|
||||||
v12 ^= v01
|
|
||||||
v12 = (v12 << 8) | (v12 >> 24)
|
|
||||||
v11 += v12
|
|
||||||
v06 ^= v11
|
|
||||||
v06 = (v06 << 7) | (v06 >> 25)
|
|
||||||
v02 += v07
|
|
||||||
v13 ^= v02
|
|
||||||
v13 = (v13 << 16) | (v13 >> 16)
|
|
||||||
v08 += v13
|
|
||||||
v07 ^= v08
|
|
||||||
v07 = (v07 << 12) | (v07 >> 20)
|
|
||||||
v02 += v07
|
|
||||||
v13 ^= v02
|
|
||||||
v13 = (v13 << 8) | (v13 >> 24)
|
|
||||||
v08 += v13
|
|
||||||
v07 ^= v08
|
|
||||||
v07 = (v07 << 7) | (v07 >> 25)
|
|
||||||
v03 += v04
|
|
||||||
v14 ^= v03
|
|
||||||
v14 = (v14 << 16) | (v14 >> 16)
|
|
||||||
v09 += v14
|
|
||||||
v04 ^= v09
|
|
||||||
v04 = (v04 << 12) | (v04 >> 20)
|
|
||||||
v03 += v04
|
|
||||||
v14 ^= v03
|
|
||||||
v14 = (v14 << 8) | (v14 >> 24)
|
|
||||||
v09 += v14
|
|
||||||
v04 ^= v09
|
|
||||||
v04 = (v04 << 7) | (v04 >> 25)
|
|
||||||
}
|
|
||||||
|
|
||||||
binary.LittleEndian.PutUint32(out[0:], v00)
|
|
||||||
binary.LittleEndian.PutUint32(out[4:], v01)
|
|
||||||
binary.LittleEndian.PutUint32(out[8:], v02)
|
|
||||||
binary.LittleEndian.PutUint32(out[12:], v03)
|
|
||||||
binary.LittleEndian.PutUint32(out[16:], v12)
|
|
||||||
binary.LittleEndian.PutUint32(out[20:], v13)
|
|
||||||
binary.LittleEndian.PutUint32(out[24:], v14)
|
|
||||||
binary.LittleEndian.PutUint32(out[28:], v15)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Encrypt(
|
|
||||||
dst []byte,
|
|
||||||
nonceFull *[24]byte,
|
|
||||||
plaintext []byte,
|
|
||||||
additionalData []byte,
|
|
||||||
key *[chacha20poly1305.KeySize]byte,
|
|
||||||
) []byte {
|
|
||||||
var nonce [chacha20poly1305.NonceSize]byte
|
|
||||||
var derivedKey [chacha20poly1305.KeySize]byte
|
|
||||||
hChaCha20(&derivedKey, nonceFull[:16], key)
|
|
||||||
aead, _ := chacha20poly1305.New(derivedKey[:])
|
|
||||||
copy(nonce[4:], nonceFull[16:])
|
|
||||||
return aead.Seal(dst, nonce[:], plaintext, additionalData)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Decrypt(
|
|
||||||
dst []byte,
|
|
||||||
nonceFull *[24]byte,
|
|
||||||
plaintext []byte,
|
|
||||||
additionalData []byte,
|
|
||||||
key *[chacha20poly1305.KeySize]byte,
|
|
||||||
) ([]byte, error) {
|
|
||||||
var nonce [chacha20poly1305.NonceSize]byte
|
|
||||||
var derivedKey [chacha20poly1305.KeySize]byte
|
|
||||||
hChaCha20(&derivedKey, nonceFull[:16], key)
|
|
||||||
aead, _ := chacha20poly1305.New(derivedKey[:])
|
|
||||||
copy(nonce[4:], nonceFull[16:])
|
|
||||||
return aead.Open(dst, nonce[:], plaintext, additionalData)
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
|
||||||
*
|
|
||||||
* Copyright (C) 2017-2018 WireGuard LLC. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package xchacha20poly1305
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/hex"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
type XChaCha20Test struct {
|
|
||||||
Nonce string
|
|
||||||
Key string
|
|
||||||
PT string
|
|
||||||
CT string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestXChaCha20(t *testing.T) {
|
|
||||||
|
|
||||||
tests := []XChaCha20Test{
|
|
||||||
{
|
|
||||||
Nonce: "000000000000000000000000000000000000000000000000",
|
|
||||||
Key: "0000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
PT: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
CT: "789e9689e5208d7fd9e1f3c5b5341f48ef18a13e418998addadd97a3693a987f8e82ecd5c1433bfed1af49750c0f1ff29c4174a05b119aa3a9e8333812e0c0feb1299c5949d895ee01dbf50f8395dd84",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Nonce: "0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f",
|
|
||||||
Key: "0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f",
|
|
||||||
PT: "0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f",
|
|
||||||
CT: "e1a046aa7f71e2af8b80b6408b2fd8d3a350278cde79c94d9efaa475e1339b3dd490127b",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Nonce: "d9a8213e8a697508805c2c171ad54487ead9e3e02d82d5bc",
|
|
||||||
Key: "979196dbd78526f2f584f7534db3f5824d8ccfa858ca7e09bdd3656ecd36033c",
|
|
||||||
PT: "43cc6d624e451bbed952c3e071dc6c03392ce11eb14316a94b2fdc98b22fedea",
|
|
||||||
CT: "53c1e8bef2dbb8f2505ec010a7afe21d5a8e6dd8f987e4ea1a2ed5dfbc844ea400db34496fd2153526c6e87c36694200",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
|
|
||||||
nonce, err := hex.DecodeString(test.Nonce)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
key, err := hex.DecodeString(test.Key)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pt, err := hex.DecodeString(test.PT)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func() {
|
|
||||||
var nonceArray [24]byte
|
|
||||||
var keyArray [32]byte
|
|
||||||
copy(nonceArray[:], nonce)
|
|
||||||
copy(keyArray[:], key)
|
|
||||||
|
|
||||||
// test encryption
|
|
||||||
|
|
||||||
ct := Encrypt(
|
|
||||||
nil,
|
|
||||||
&nonceArray,
|
|
||||||
pt,
|
|
||||||
nil,
|
|
||||||
&keyArray,
|
|
||||||
)
|
|
||||||
ctHex := hex.EncodeToString(ct)
|
|
||||||
if ctHex != test.CT {
|
|
||||||
t.Fatal("encryption failed, expected:", test.CT, "got", ctHex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// test decryption
|
|
||||||
|
|
||||||
ptp, err := Decrypt(
|
|
||||||
nil,
|
|
||||||
&nonceArray,
|
|
||||||
ct,
|
|
||||||
nil,
|
|
||||||
&keyArray,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ptHex := hex.EncodeToString(ptp)
|
|
||||||
if ptHex != test.PT {
|
|
||||||
t.Fatal("decryption failed, expected:", test.PT, "got", ptHex)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user