Compare commits
34 Commits
0.0.201805
...
0.0.201810
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b41922e5c8 | ||
|
|
dbb72402f2 | ||
|
|
7c971d7ef4 | ||
|
|
70bcf9ecb8 | ||
|
|
ebc7541953 | ||
|
|
833597b585 | ||
|
|
cf81a28dd3 | ||
|
|
942abf948a | ||
|
|
47d1140361 | ||
|
|
39d6e4f2f1 | ||
|
|
1c02557013 | ||
|
|
32d2148835 | ||
|
|
5be541d147 | ||
|
|
063becdc73 | ||
|
|
15da869b31 | ||
|
|
3ad3e83c7a | ||
|
|
2e13b7b0fb | ||
|
|
6b3b1c3b91 | ||
|
|
6a5d0e2bcd | ||
|
|
0ba551807f | ||
|
|
99d5aeeb27 | ||
|
|
a050431f26 | ||
|
|
0c976003c8 | ||
|
|
955e89839f | ||
|
|
a4cd0216c0 | ||
|
|
1d7845a600 | ||
|
|
5079298ce2 | ||
|
|
fc3a7635e5 | ||
|
|
2496cdd8e6 | ||
|
|
4365b4583f | ||
|
|
bbf320c477 | ||
|
|
625d59da14 | ||
|
|
2f2eca8947 | ||
|
|
66f6ca3e4a |
6
Gopkg.lock
generated
6
Gopkg.lock
generated
@@ -11,7 +11,7 @@
|
|||||||
"internal/chacha20",
|
"internal/chacha20",
|
||||||
"poly1305"
|
"poly1305"
|
||||||
]
|
]
|
||||||
revision = "1a580b3eff7814fc9b40602fd35256c63b50f491"
|
revision = "ab813273cd59e1333f7ae7bff5d027d4aadf528c"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"ipv4",
|
"ipv4",
|
||||||
"ipv6"
|
"ipv6"
|
||||||
]
|
]
|
||||||
revision = "9ef9f5bb98a1fdc41f8cf6c250a4404b4085e389"
|
revision = "dfa909b99c79129e1100513e5cd36307665e5723"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
"cpu",
|
"cpu",
|
||||||
"unix"
|
"unix"
|
||||||
]
|
]
|
||||||
revision = "88eb85aaee56831ad49eaf7aa80d73de9814cde2"
|
revision = "c11f84a56e43e20a78cee75a7c034031ecf57d1f"
|
||||||
|
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -32,11 +32,11 @@ version.go:
|
|||||||
|
|
||||||
vendor/.created: Gopkg.toml Gopkg.lock | .gopath/.created
|
vendor/.created: Gopkg.toml Gopkg.lock | .gopath/.created
|
||||||
command -v dep >/dev/null || go get -v github.com/golang/dep/cmd/dep
|
command -v dep >/dev/null || go get -v github.com/golang/dep/cmd/dep
|
||||||
cd .gopath/src/$(GO_IMPORT_PATH) && dep ensure -vendor-only -v
|
export PWD; cd .gopath/src/$(GO_IMPORT_PATH) && dep ensure -vendor-only -v
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
wireguard-go: $(wildcard *.go) $(wildcard */*.go) .gopath/.created vendor/.created version.go
|
wireguard-go: $(wildcard *.go) $(wildcard */*.go) .gopath/.created vendor/.created version.go
|
||||||
go build $(GO_BUILD_EXTRA_ARGS) -v $(GO_IMPORT_PATH)
|
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 wireguard-go "$(DESTDIR)$(BINDIR)/wireguard-go"
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ $ make
|
|||||||
are otherwise in compliance with the GPLv2 for each covered work you convey
|
are otherwise in compliance with the GPLv2 for each covered work you convey
|
||||||
(including without limitation making the Corresponding Source available in
|
(including without limitation making the Corresponding Source available in
|
||||||
compliance with Section 3 of the GPLv2), you are granted the additional
|
compliance with Section 3 of the GPLv2), you are granted the additional
|
||||||
the additional permission to convey through the Apple App Store
|
permission to convey through the Apple App Store non-source executable
|
||||||
non-source executable versions of the Program as incorporated into each
|
versions of the Program as incorporated into each applicable covered work
|
||||||
applicable covered work as Executable Versions only under the Mozilla
|
as Executable Versions only under the Mozilla Public License version 2.0
|
||||||
Public License version 2.0 (https://www.mozilla.org/en-US/MPL/2.0/).
|
(https://www.mozilla.org/en-US/MPL/2.0/).
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
3
conn.go
3
conn.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -11,7 +10,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* This code is meant to be a temporary solution
|
/* This code is meant to be a temporary solution
|
||||||
@@ -87,6 +88,18 @@ func listenNet(network string, port int) (*net.UDPConn, int, error) {
|
|||||||
return conn, uaddr.Port, nil
|
return conn, uaddr.Port, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractErrno(err error) error {
|
||||||
|
opErr, ok := err.(*net.OpError)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
syscallErr, ok := opErr.Err.(*os.SyscallError)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return syscallErr.Err
|
||||||
|
}
|
||||||
|
|
||||||
func CreateBind(uport uint16, device *Device) (Bind, uint16, error) {
|
func CreateBind(uport uint16, device *Device) (Bind, uint16, error) {
|
||||||
var err error
|
var err error
|
||||||
var bind NativeBind
|
var bind NativeBind
|
||||||
@@ -94,13 +107,15 @@ func CreateBind(uport uint16, device *Device) (Bind, uint16, error) {
|
|||||||
port := int(uport)
|
port := int(uport)
|
||||||
|
|
||||||
bind.ipv4, port, err = listenNet("udp4", port)
|
bind.ipv4, port, err = listenNet("udp4", port)
|
||||||
if err != nil {
|
if err != nil && extractErrno(err) != syscall.EAFNOSUPPORT {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bind.ipv6, port, err = listenNet("udp6", port)
|
bind.ipv6, port, err = listenNet("udp6", port)
|
||||||
if err != nil {
|
if err != nil && extractErrno(err) != syscall.EAFNOSUPPORT {
|
||||||
|
return nil, 0, err
|
||||||
bind.ipv4.Close()
|
bind.ipv4.Close()
|
||||||
|
bind.ipv4 = nil
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,8 +123,13 @@ func CreateBind(uport uint16, device *Device) (Bind, uint16, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bind *NativeBind) Close() error {
|
func (bind *NativeBind) Close() error {
|
||||||
err1 := bind.ipv4.Close()
|
var err1, err2 error
|
||||||
err2 := bind.ipv6.Close()
|
if bind.ipv4 != nil {
|
||||||
|
err1 = bind.ipv4.Close()
|
||||||
|
}
|
||||||
|
if bind.ipv6 != nil {
|
||||||
|
err2 = bind.ipv6.Close()
|
||||||
|
}
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
return err1
|
return err1
|
||||||
}
|
}
|
||||||
@@ -117,6 +137,9 @@ func (bind *NativeBind) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
|
func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
|
||||||
|
if bind.ipv4 == nil {
|
||||||
|
return 0, nil, syscall.EAFNOSUPPORT
|
||||||
|
}
|
||||||
n, endpoint, err := bind.ipv4.ReadFromUDP(buff)
|
n, endpoint, err := bind.ipv4.ReadFromUDP(buff)
|
||||||
if endpoint != nil {
|
if endpoint != nil {
|
||||||
endpoint.IP = endpoint.IP.To4()
|
endpoint.IP = endpoint.IP.To4()
|
||||||
@@ -125,6 +148,9 @@ func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bind *NativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
|
func (bind *NativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
|
||||||
|
if bind.ipv6 == nil {
|
||||||
|
return 0, nil, syscall.EAFNOSUPPORT
|
||||||
|
}
|
||||||
n, endpoint, err := bind.ipv6.ReadFromUDP(buff)
|
n, endpoint, err := bind.ipv6.ReadFromUDP(buff)
|
||||||
return n, (*NativeEndpoint)(endpoint), err
|
return n, (*NativeEndpoint)(endpoint), err
|
||||||
}
|
}
|
||||||
@@ -133,8 +159,14 @@ func (bind *NativeBind) Send(buff []byte, endpoint Endpoint) error {
|
|||||||
var err error
|
var err error
|
||||||
nend := endpoint.(*NativeEndpoint)
|
nend := endpoint.(*NativeEndpoint)
|
||||||
if nend.IP.To4() != nil {
|
if nend.IP.To4() != nil {
|
||||||
|
if bind.ipv4 == nil {
|
||||||
|
return syscall.EAFNOSUPPORT
|
||||||
|
}
|
||||||
_, err = bind.ipv4.WriteToUDP(buff, (*net.UDPAddr)(nend))
|
_, err = bind.ipv4.WriteToUDP(buff, (*net.UDPAddr)(nend))
|
||||||
} else {
|
} else {
|
||||||
|
if bind.ipv6 == nil {
|
||||||
|
return syscall.EAFNOSUPPORT
|
||||||
|
}
|
||||||
_, err = bind.ipv6.WriteToUDP(buff, (*net.UDPAddr)(nend))
|
_, err = bind.ipv6.WriteToUDP(buff, (*net.UDPAddr)(nend))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -157,31 +189,29 @@ func (bind *NativeBind) SetMark(mark uint32) error {
|
|||||||
if fwmarkIoctl == 0 {
|
if fwmarkIoctl == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
fd4, err1 := bind.ipv4.SyscallConn()
|
if bind.ipv4 != nil {
|
||||||
fd6, err2 := bind.ipv6.SyscallConn()
|
fd, err := bind.ipv4.SyscallConn()
|
||||||
if err1 != nil {
|
if err != nil {
|
||||||
return err1
|
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 err2 != nil {
|
if bind.ipv6 != nil {
|
||||||
return err2
|
fd, err := bind.ipv6.SyscallConn()
|
||||||
}
|
if err != nil {
|
||||||
err3 := fd4.Control(func(fd uintptr) {
|
return err
|
||||||
err1 = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
|
}
|
||||||
})
|
err = fd.Control(func(fd uintptr) {
|
||||||
err4 := fd6.Control(func(fd uintptr) {
|
err = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
|
||||||
err2 = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
|
})
|
||||||
})
|
if err != nil {
|
||||||
if err1 != nil {
|
return err
|
||||||
return err1
|
}
|
||||||
}
|
|
||||||
if err2 != nil {
|
|
||||||
return err2
|
|
||||||
}
|
|
||||||
if err3 != nil {
|
|
||||||
return err3
|
|
||||||
}
|
|
||||||
if err4 != nil {
|
|
||||||
return err4
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
112
conn_linux.go
112
conn_linux.go
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*
|
*
|
||||||
* This implements userspace semantics of "sticky sockets", modeled after
|
* This implements userspace semantics of "sticky sockets", modeled after
|
||||||
* WireGuard's kernelspace implementation. This is more or less a straight port
|
* WireGuard's kernelspace implementation. This is more or less a straight port
|
||||||
@@ -18,15 +17,20 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/rwcancel"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
"git.zx2c4.com/wireguard-go/rwcancel"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FD_ERR = -1
|
||||||
|
)
|
||||||
|
|
||||||
type IPv4Source struct {
|
type IPv4Source struct {
|
||||||
src [4]byte
|
src [4]byte
|
||||||
ifindex int32
|
ifindex int32
|
||||||
@@ -126,6 +130,7 @@ func createNetlinkRouteSocket() (int, error) {
|
|||||||
func CreateBind(port uint16, device *Device) (*NativeBind, uint16, error) {
|
func CreateBind(port uint16, device *Device) (*NativeBind, uint16, error) {
|
||||||
var err error
|
var err error
|
||||||
var bind NativeBind
|
var bind NativeBind
|
||||||
|
var newPort uint16
|
||||||
|
|
||||||
bind.netlinkSock, err = createNetlinkRouteSocket()
|
bind.netlinkSock, err = createNetlinkRouteSocket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -139,41 +144,63 @@ func CreateBind(port uint16, device *Device) (*NativeBind, uint16, error) {
|
|||||||
|
|
||||||
go bind.routineRouteListener(device)
|
go bind.routineRouteListener(device)
|
||||||
|
|
||||||
bind.sock6, port, err = create6(port)
|
// attempt ipv6 bind, update port if succesful
|
||||||
|
|
||||||
|
bind.sock6, newPort, err = create6(port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bind.netlinkCancel.Cancel()
|
if err != syscall.EAFNOSUPPORT {
|
||||||
return nil, port, err
|
bind.netlinkCancel.Cancel()
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
port = newPort
|
||||||
}
|
}
|
||||||
|
|
||||||
bind.sock4, port, err = create4(port)
|
// attempt ipv4 bind, update port if succesful
|
||||||
|
|
||||||
|
bind.sock4, newPort, err = create4(port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bind.netlinkCancel.Cancel()
|
if err != syscall.EAFNOSUPPORT {
|
||||||
unix.Close(bind.sock6)
|
bind.netlinkCancel.Cancel()
|
||||||
|
unix.Close(bind.sock6)
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
port = newPort
|
||||||
}
|
}
|
||||||
return &bind, port, err
|
|
||||||
|
if bind.sock4 == FD_ERR && bind.sock6 == FD_ERR {
|
||||||
|
return nil, 0, errors.New("ipv4 and ipv6 not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &bind, port, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bind *NativeBind) SetMark(value uint32) error {
|
func (bind *NativeBind) SetMark(value uint32) error {
|
||||||
err := unix.SetsockoptInt(
|
if bind.sock6 != -1 {
|
||||||
bind.sock6,
|
err := unix.SetsockoptInt(
|
||||||
unix.SOL_SOCKET,
|
bind.sock6,
|
||||||
unix.SO_MARK,
|
unix.SOL_SOCKET,
|
||||||
int(value),
|
unix.SO_MARK,
|
||||||
)
|
int(value),
|
||||||
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = unix.SetsockoptInt(
|
if bind.sock4 != -1 {
|
||||||
bind.sock4,
|
err := unix.SetsockoptInt(
|
||||||
unix.SOL_SOCKET,
|
bind.sock4,
|
||||||
unix.SO_MARK,
|
unix.SOL_SOCKET,
|
||||||
int(value),
|
unix.SO_MARK,
|
||||||
)
|
int(value),
|
||||||
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bind.lastMark = value
|
bind.lastMark = value
|
||||||
@@ -187,9 +214,14 @@ func closeUnblock(fd int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bind *NativeBind) Close() error {
|
func (bind *NativeBind) Close() error {
|
||||||
err1 := closeUnblock(bind.sock6)
|
var err1, err2, err3 error
|
||||||
err2 := closeUnblock(bind.sock4)
|
if bind.sock6 != -1 {
|
||||||
err3 := bind.netlinkCancel.Cancel()
|
err1 = closeUnblock(bind.sock6)
|
||||||
|
}
|
||||||
|
if bind.sock4 != -1 {
|
||||||
|
err2 = closeUnblock(bind.sock4)
|
||||||
|
}
|
||||||
|
err3 = bind.netlinkCancel.Cancel()
|
||||||
|
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
return err1
|
return err1
|
||||||
@@ -202,6 +234,9 @@ func (bind *NativeBind) Close() error {
|
|||||||
|
|
||||||
func (bind *NativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
|
func (bind *NativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
|
||||||
var end NativeEndpoint
|
var end NativeEndpoint
|
||||||
|
if bind.sock6 == -1 {
|
||||||
|
return 0, nil, syscall.EAFNOSUPPORT
|
||||||
|
}
|
||||||
n, err := receive6(
|
n, err := receive6(
|
||||||
bind.sock6,
|
bind.sock6,
|
||||||
buff,
|
buff,
|
||||||
@@ -212,6 +247,9 @@ func (bind *NativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
|
|||||||
|
|
||||||
func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
|
func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
|
||||||
var end NativeEndpoint
|
var end NativeEndpoint
|
||||||
|
if bind.sock4 == -1 {
|
||||||
|
return 0, nil, syscall.EAFNOSUPPORT
|
||||||
|
}
|
||||||
n, err := receive4(
|
n, err := receive4(
|
||||||
bind.sock4,
|
bind.sock4,
|
||||||
buff,
|
buff,
|
||||||
@@ -223,8 +261,14 @@ func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
|
|||||||
func (bind *NativeBind) Send(buff []byte, end Endpoint) error {
|
func (bind *NativeBind) Send(buff []byte, end Endpoint) error {
|
||||||
nend := end.(*NativeEndpoint)
|
nend := end.(*NativeEndpoint)
|
||||||
if !nend.isV6 {
|
if !nend.isV6 {
|
||||||
|
if bind.sock4 == -1 {
|
||||||
|
return syscall.EAFNOSUPPORT
|
||||||
|
}
|
||||||
return send4(bind.sock4, nend, buff)
|
return send4(bind.sock4, nend, buff)
|
||||||
} else {
|
} else {
|
||||||
|
if bind.sock6 == -1 {
|
||||||
|
return syscall.EAFNOSUPPORT
|
||||||
|
}
|
||||||
return send6(bind.sock6, nend, buff)
|
return send6(bind.sock6, nend, buff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -312,7 +356,7 @@ func create4(port uint16) (int, uint16, error) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, 0, err
|
return FD_ERR, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := unix.SockaddrInet4{
|
addr := unix.SockaddrInet4{
|
||||||
@@ -343,7 +387,7 @@ func create4(port uint16) (int, uint16, error) {
|
|||||||
return unix.Bind(fd, &addr)
|
return unix.Bind(fd, &addr)
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
unix.Close(fd)
|
unix.Close(fd)
|
||||||
return -1, 0, err
|
return FD_ERR, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return fd, uint16(addr.Port), err
|
return fd, uint16(addr.Port), err
|
||||||
@@ -360,7 +404,7 @@ func create6(port uint16) (int, uint16, error) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, 0, err
|
return FD_ERR, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// set sockopts and bind
|
// set sockopts and bind
|
||||||
@@ -402,7 +446,7 @@ func create6(port uint16) (int, uint16, error) {
|
|||||||
|
|
||||||
}(); err != nil {
|
}(); err != nil {
|
||||||
unix.Close(fd)
|
unix.Close(fd)
|
||||||
return -1, 0, err
|
return FD_ERR, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return fd, uint16(addr.Port), err
|
return fd, uint16(addr.Port), err
|
||||||
@@ -563,7 +607,7 @@ func (bind *NativeBind) routineRouteListener(device *Device) {
|
|||||||
var msgn int
|
var msgn int
|
||||||
for {
|
for {
|
||||||
msgn, _, _, _, err = unix.Recvmsg(bind.netlinkSock, msg[:], nil, 0)
|
msgn, _, _, _, err = unix.Recvmsg(bind.netlinkSock, msg[:], nil, 0)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
if err == nil || !rwcancel.RetryAfterError(err) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if !bind.netlinkCancel.ReadyRead() {
|
if !bind.netlinkCancel.ReadyRead() {
|
||||||
|
|||||||
17
constants.go
17
constants.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -27,18 +26,14 @@ const (
|
|||||||
PaddingMultiple = 16
|
PaddingMultiple = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Implementation specific constants */
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
QueueOutboundSize = 1024
|
MinMessageSize = MessageKeepaliveSize // minimum size of transport message (keepalive)
|
||||||
QueueInboundSize = 1024
|
MaxMessageSize = MaxSegmentSize // maximum size of transport message
|
||||||
QueueHandshakeSize = 1024
|
MaxContentSize = MaxSegmentSize - MessageTransportSize // maximum size of transport message content
|
||||||
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 (
|
const (
|
||||||
UnderLoadQueueSize = QueueHandshakeSize / 8
|
UnderLoadQueueSize = QueueHandshakeSize / 8
|
||||||
UnderLoadAfterTime = time.Second // how long does the device remain under load after detected
|
UnderLoadAfterTime = time.Second // how long does the device remain under load after detected
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/xchacha20poly1305"
|
|
||||||
"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"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
27
device.go
27
device.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -67,7 +66,12 @@ type Device struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pool 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 {
|
queue struct {
|
||||||
@@ -243,14 +247,6 @@ func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
|
|||||||
return nil
|
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 {
|
func NewDevice(tunDevice tun.TUNDevice, logger *Logger) *Device {
|
||||||
device := new(Device)
|
device := new(Device)
|
||||||
|
|
||||||
@@ -275,11 +271,7 @@ func NewDevice(tunDevice tun.TUNDevice, logger *Logger) *Device {
|
|||||||
device.indexTable.Init()
|
device.indexTable.Init()
|
||||||
device.allowedips.Reset()
|
device.allowedips.Reset()
|
||||||
|
|
||||||
device.pool.messageBuffers = sync.Pool{
|
device.PopulatePools()
|
||||||
New: func() interface{} {
|
|
||||||
return new([MaxMessageSize]byte)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// create queues
|
// create queues
|
||||||
|
|
||||||
@@ -385,10 +377,11 @@ func (device *Device) Close() {
|
|||||||
|
|
||||||
close(device.signals.stop)
|
close(device.signals.stop)
|
||||||
|
|
||||||
|
device.RemoveAllPeers()
|
||||||
|
|
||||||
device.state.stopping.Wait()
|
device.state.stopping.Wait()
|
||||||
device.FlushPacketQueues()
|
device.FlushPacketQueues()
|
||||||
|
|
||||||
device.RemoveAllPeers()
|
|
||||||
device.rate.limiter.Close()
|
device.rate.limiter.Close()
|
||||||
|
|
||||||
device.state.changing.Set(false)
|
device.state.changing.Set(false)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package main
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -9,6 +8,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"git.zx2c4.com/wireguard-go/tun"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -20,7 +20,7 @@ type DummyTUN struct {
|
|||||||
name string
|
name string
|
||||||
mtu int
|
mtu int
|
||||||
packets chan []byte
|
packets chan []byte
|
||||||
events chan TUNEvent
|
events chan tun.TUNEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *DummyTUN) File() *os.File {
|
func (tun *DummyTUN) File() *os.File {
|
||||||
@@ -46,7 +46,7 @@ func (tun *DummyTUN) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *DummyTUN) Events() chan TUNEvent {
|
func (tun *DummyTUN) Events() chan tun.TUNEvent {
|
||||||
return tun.events
|
return tun.events
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,11 +59,11 @@ func (tun *DummyTUN) Read(d []byte, offset int) (int, error) {
|
|||||||
return len(t), nil
|
return len(t), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateDummyTUN(name string) (TUNDevice, error) {
|
func CreateDummyTUN(name string) (tun.TUNDevice, error) {
|
||||||
var dummy DummyTUN
|
var dummy DummyTUN
|
||||||
dummy.mtu = 0
|
dummy.mtu = 0
|
||||||
dummy.packets = make(chan []byte, 100)
|
dummy.packets = make(chan []byte, 100)
|
||||||
dummy.events = make(chan TUNEvent, 10)
|
dummy.events = make(chan tun.TUNEvent, 10)
|
||||||
return &dummy, nil
|
return &dummy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
3
ip.go
3
ip.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/replay"
|
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
|
"git.zx2c4.com/wireguard-go/replay"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
7
main.go
7
main.go
@@ -1,14 +1,13 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/tun"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.zx2c4.com/wireguard-go/tun"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
@@ -160,6 +159,8 @@ func main() {
|
|||||||
fmt.Sprintf("(%s) ", interfaceName),
|
fmt.Sprintf("(%s) ", interfaceName),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger.Info.Println("Starting wireguard-go version", WireGuardGoVersion)
|
||||||
|
|
||||||
logger.Debug.Println("Debug log enabled")
|
logger.Debug.Println("Debug log enabled")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
3
misc.go
3
misc.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/tai64n"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
"git.zx2c4.com/wireguard-go/tai64n"
|
||||||
"golang.org/x/crypto/blake2s"
|
"golang.org/x/crypto/blake2s"
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
"golang.org/x/crypto/poly1305"
|
"golang.org/x/crypto/poly1305"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
14
peer.go
14
peer.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -258,3 +257,14 @@ func (peer *Peer) Stop() {
|
|||||||
|
|
||||||
peer.ZeroAndFlushAll()
|
peer.ZeroAndFlushAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var roamingDisabled bool
|
||||||
|
|
||||||
|
func (peer *Peer) SetEndpointFromPacket(endpoint Endpoint) {
|
||||||
|
if roamingDisabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
peer.mutex.Lock()
|
||||||
|
peer.endpoint = endpoint
|
||||||
|
peer.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|||||||
89
pools.go
Normal file
89
pools.go
Normal 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
16
queueconstants.go
Normal 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
|
||||||
|
)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package ratelimiter
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package ratelimiter
|
||||||
|
|||||||
152
receive.go
152
receive.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -44,59 +43,29 @@ func (elem *QueueInboundElement) IsDropped() bool {
|
|||||||
return atomic.LoadInt32(&elem.dropped) == AtomicTrue
|
return atomic.LoadInt32(&elem.dropped) == AtomicTrue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (device *Device) addToInboundQueue(
|
func (device *Device) addToInboundAndDecryptionQueues(inboundQueue chan *QueueInboundElement, decryptionQueue chan *QueueInboundElement, element *QueueInboundElement) bool {
|
||||||
queue chan *QueueInboundElement,
|
select {
|
||||||
element *QueueInboundElement,
|
case inboundQueue <- element:
|
||||||
) {
|
|
||||||
for {
|
|
||||||
select {
|
select {
|
||||||
case queue <- element:
|
case decryptionQueue <- element:
|
||||||
return
|
return true
|
||||||
default:
|
default:
|
||||||
select {
|
element.Drop()
|
||||||
case old := <-queue:
|
element.mutex.Unlock()
|
||||||
old.Drop()
|
return false
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
device.PutInboundElement(element)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (device *Device) addToDecryptionQueue(
|
func (device *Device) addToHandshakeQueue(queue chan QueueHandshakeElement, element QueueHandshakeElement) bool {
|
||||||
queue chan *QueueInboundElement,
|
select {
|
||||||
element *QueueInboundElement,
|
case queue <- element:
|
||||||
) {
|
return true
|
||||||
for {
|
default:
|
||||||
select {
|
return false
|
||||||
case queue <- element:
|
|
||||||
return
|
|
||||||
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:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +124,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
device.PutMessageBuffer(buffer)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +147,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
|
|||||||
|
|
||||||
// check size
|
// check size
|
||||||
|
|
||||||
if len(packet) < MessageTransportType {
|
if len(packet) < MessageTransportSize {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,23 +169,23 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create work element
|
// create work element
|
||||||
|
|
||||||
peer := value.peer
|
peer := value.peer
|
||||||
elem := &QueueInboundElement{
|
elem := device.GetInboundElement()
|
||||||
packet: packet,
|
elem.packet = packet
|
||||||
buffer: buffer,
|
elem.buffer = buffer
|
||||||
keypair: keypair,
|
elem.keypair = keypair
|
||||||
dropped: AtomicFalse,
|
elem.dropped = AtomicFalse
|
||||||
endpoint: endpoint,
|
elem.endpoint = endpoint
|
||||||
}
|
elem.counter = 0
|
||||||
|
elem.mutex = sync.Mutex{}
|
||||||
elem.mutex.Lock()
|
elem.mutex.Lock()
|
||||||
|
|
||||||
// add to decryption queues
|
// add to decryption queues
|
||||||
|
|
||||||
if peer.isRunning.Get() {
|
if peer.isRunning.Get() {
|
||||||
device.addToDecryptionQueue(device.queue.decryption, elem)
|
if device.addToInboundAndDecryptionQueues(peer.queue.inbound, device.queue.decryption, elem) {
|
||||||
device.addToInboundQueue(peer.queue.inbound, elem)
|
buffer = device.GetMessageBuffer()
|
||||||
buffer = device.GetMessageBuffer()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
@@ -236,7 +206,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if okay {
|
if okay {
|
||||||
device.addToHandshakeQueue(
|
if (device.addToHandshakeQueue(
|
||||||
device.queue.handshake,
|
device.queue.handshake,
|
||||||
QueueHandshakeElement{
|
QueueHandshakeElement{
|
||||||
msgType: msgType,
|
msgType: msgType,
|
||||||
@@ -244,8 +214,9 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) {
|
|||||||
packet: packet,
|
packet: packet,
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
},
|
},
|
||||||
)
|
)) {
|
||||||
buffer = device.GetMessageBuffer()
|
buffer = device.GetMessageBuffer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,6 +279,7 @@ func (device *Device) RoutineDecryption() {
|
|||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
elem.Drop()
|
elem.Drop()
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
}
|
}
|
||||||
elem.mutex.Unlock()
|
elem.mutex.Unlock()
|
||||||
}
|
}
|
||||||
@@ -322,18 +294,26 @@ func (device *Device) RoutineHandshake() {
|
|||||||
logError := device.log.Error
|
logError := device.log.Error
|
||||||
logDebug := device.log.Debug
|
logDebug := device.log.Debug
|
||||||
|
|
||||||
|
var elem QueueHandshakeElement
|
||||||
|
var ok bool
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
logDebug.Println("Routine: handshake worker - stopped")
|
logDebug.Println("Routine: handshake worker - stopped")
|
||||||
device.state.stopping.Done()
|
device.state.stopping.Done()
|
||||||
|
if elem.buffer != nil {
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
logDebug.Println("Routine: handshake worker - started")
|
logDebug.Println("Routine: handshake worker - started")
|
||||||
device.state.starting.Done()
|
device.state.starting.Done()
|
||||||
|
|
||||||
var elem QueueHandshakeElement
|
|
||||||
var ok bool
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
if elem.buffer != nil {
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
elem.buffer = nil
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case elem, ok = <-device.queue.handshake:
|
case elem, ok = <-device.queue.handshake:
|
||||||
case <-device.signals.stop:
|
case <-device.signals.stop:
|
||||||
@@ -440,10 +420,7 @@ func (device *Device) RoutineHandshake() {
|
|||||||
peer.timersAnyAuthenticatedPacketReceived()
|
peer.timersAnyAuthenticatedPacketReceived()
|
||||||
|
|
||||||
// update endpoint
|
// update endpoint
|
||||||
|
peer.SetEndpointFromPacket(elem.endpoint)
|
||||||
peer.mutex.Lock()
|
|
||||||
peer.endpoint = elem.endpoint
|
|
||||||
peer.mutex.Unlock()
|
|
||||||
|
|
||||||
logDebug.Println(peer, "- Received handshake initiation")
|
logDebug.Println(peer, "- Received handshake initiation")
|
||||||
|
|
||||||
@@ -473,10 +450,7 @@ func (device *Device) RoutineHandshake() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update endpoint
|
// update endpoint
|
||||||
|
peer.SetEndpointFromPacket(elem.endpoint)
|
||||||
peer.mutex.Lock()
|
|
||||||
peer.endpoint = elem.endpoint
|
|
||||||
peer.mutex.Unlock()
|
|
||||||
|
|
||||||
logDebug.Println(peer, "- Received handshake response")
|
logDebug.Println(peer, "- Received handshake response")
|
||||||
|
|
||||||
@@ -512,9 +486,18 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
|||||||
logError := device.log.Error
|
logError := device.log.Error
|
||||||
logDebug := device.log.Debug
|
logDebug := device.log.Debug
|
||||||
|
|
||||||
|
var elem *QueueInboundElement
|
||||||
|
var ok bool
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
logDebug.Println(peer, "- Routine: sequential receiver - stopped")
|
logDebug.Println(peer, "- Routine: sequential receiver - stopped")
|
||||||
peer.routines.stopping.Done()
|
peer.routines.stopping.Done()
|
||||||
|
if elem != nil {
|
||||||
|
if !elem.IsDropped() {
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
}
|
||||||
|
device.PutInboundElement(elem)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
logDebug.Println(peer, "- Routine: sequential receiver - started")
|
logDebug.Println(peer, "- Routine: sequential receiver - started")
|
||||||
@@ -522,13 +505,20 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
|||||||
peer.routines.starting.Done()
|
peer.routines.starting.Done()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
if elem != nil {
|
||||||
|
if !elem.IsDropped() {
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
}
|
||||||
|
device.PutInboundElement(elem)
|
||||||
|
elem = nil
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
|
||||||
case <-peer.routines.stop:
|
case <-peer.routines.stop:
|
||||||
return
|
return
|
||||||
|
|
||||||
case elem, ok := <-peer.queue.inbound:
|
case elem, ok = <-peer.queue.inbound:
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
@@ -549,10 +539,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update endpoint
|
// update endpoint
|
||||||
|
peer.SetEndpointFromPacket(elem.endpoint)
|
||||||
peer.mutex.Lock()
|
|
||||||
peer.endpoint = elem.endpoint
|
|
||||||
peer.mutex.Unlock()
|
|
||||||
|
|
||||||
// check if using new keypair
|
// check if using new keypair
|
||||||
if peer.ReceivedWithKeypair(elem.keypair) {
|
if peer.ReceivedWithKeypair(elem.keypair) {
|
||||||
@@ -642,10 +629,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
|||||||
|
|
||||||
offset := MessageTransportOffsetContent
|
offset := MessageTransportOffsetContent
|
||||||
atomic.AddUint64(&peer.stats.rxBytes, uint64(len(elem.packet)))
|
atomic.AddUint64(&peer.stats.rxBytes, uint64(len(elem.packet)))
|
||||||
_, err := device.tun.device.Write(
|
_, err := device.tun.device.Write(elem.buffer[:offset+len(elem.packet)], offset)
|
||||||
elem.buffer[:offset+len(elem.packet)],
|
|
||||||
offset)
|
|
||||||
device.PutMessageBuffer(elem.buffer)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logError.Println("Failed to write packet to TUN device:", err)
|
logError.Println("Failed to write packet to TUN device:", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package replay
|
package replay
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package replay
|
package replay
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package rwcancel
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package rwcancel
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package rwcancel
|
||||||
@@ -40,15 +40,16 @@ func NewRWCancel(fd int) (*RWCancel, error) {
|
|||||||
return &rwcancel, nil
|
return &rwcancel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://golang.org/src/crypto/rand/eagain.go */
|
func RetryAfterError(err error) bool {
|
||||||
func ErrorIsEAGAIN(err error) bool {
|
|
||||||
if pe, ok := err.(*os.PathError); ok {
|
if pe, ok := err.(*os.PathError); ok {
|
||||||
if errno, ok := pe.Err.(syscall.Errno); ok && errno == syscall.EAGAIN {
|
err = pe.Err
|
||||||
|
}
|
||||||
|
if errno, ok := err.(syscall.Errno); ok {
|
||||||
|
switch errno {
|
||||||
|
case syscall.EAGAIN, syscall.EINTR:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EAGAIN {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -86,7 +87,7 @@ func (rw *RWCancel) ReadyWrite() bool {
|
|||||||
func (rw *RWCancel) Read(p []byte) (n int, err error) {
|
func (rw *RWCancel) Read(p []byte) (n int, err error) {
|
||||||
for {
|
for {
|
||||||
n, err := unix.Read(rw.fd, p)
|
n, err := unix.Read(rw.fd, p)
|
||||||
if err == nil || !ErrorIsEAGAIN(err) {
|
if err == nil || !RetryAfterError(err) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
if !rw.ReadyRead() {
|
if !rw.ReadyRead() {
|
||||||
@@ -98,7 +99,7 @@ func (rw *RWCancel) Read(p []byte) (n int, err error) {
|
|||||||
func (rw *RWCancel) Write(p []byte) (n int, err error) {
|
func (rw *RWCancel) Write(p []byte) (n int, err error) {
|
||||||
for {
|
for {
|
||||||
n, err := unix.Write(rw.fd, p)
|
n, err := unix.Write(rw.fd, p)
|
||||||
if err == nil || !ErrorIsEAGAIN(err) {
|
if err == nil || !RetryAfterError(err) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
if !rw.ReadyWrite() {
|
if !rw.ReadyWrite() {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package rwcancel
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package rwcancel
|
||||||
|
|||||||
136
send.go
136
send.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -53,10 +52,14 @@ type QueueOutboundElement struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (device *Device) NewOutboundElement() *QueueOutboundElement {
|
func (device *Device) NewOutboundElement() *QueueOutboundElement {
|
||||||
return &QueueOutboundElement{
|
elem := device.GetOutboundElement()
|
||||||
dropped: AtomicFalse,
|
elem.dropped = AtomicFalse
|
||||||
buffer: device.pool.messageBuffers.Get().(*[MaxMessageSize]byte),
|
elem.buffer = device.GetMessageBuffer()
|
||||||
}
|
elem.mutex = sync.Mutex{}
|
||||||
|
elem.nonce = 0
|
||||||
|
elem.keypair = nil
|
||||||
|
elem.peer = nil
|
||||||
|
return elem
|
||||||
}
|
}
|
||||||
|
|
||||||
func (elem *QueueOutboundElement) Drop() {
|
func (elem *QueueOutboundElement) Drop() {
|
||||||
@@ -67,10 +70,7 @@ func (elem *QueueOutboundElement) IsDropped() bool {
|
|||||||
return atomic.LoadInt32(&elem.dropped) == AtomicTrue
|
return atomic.LoadInt32(&elem.dropped) == AtomicTrue
|
||||||
}
|
}
|
||||||
|
|
||||||
func addToOutboundQueue(
|
func addToNonceQueue(queue chan *QueueOutboundElement, element *QueueOutboundElement, device *Device) {
|
||||||
queue chan *QueueOutboundElement,
|
|
||||||
element *QueueOutboundElement,
|
|
||||||
) {
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case queue <- element:
|
case queue <- element:
|
||||||
@@ -78,30 +78,28 @@ func addToOutboundQueue(
|
|||||||
default:
|
default:
|
||||||
select {
|
select {
|
||||||
case old := <-queue:
|
case old := <-queue:
|
||||||
old.Drop()
|
device.PutMessageBuffer(old.buffer)
|
||||||
|
device.PutOutboundElement(old)
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addToEncryptionQueue(
|
func addToOutboundAndEncryptionQueues(outboundQueue chan *QueueOutboundElement, encryptionQueue chan *QueueOutboundElement, element *QueueOutboundElement) {
|
||||||
queue chan *QueueOutboundElement,
|
select {
|
||||||
element *QueueOutboundElement,
|
case outboundQueue <- element:
|
||||||
) {
|
|
||||||
for {
|
|
||||||
select {
|
select {
|
||||||
case queue <- element:
|
case encryptionQueue <- element:
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
select {
|
element.Drop()
|
||||||
case old := <-queue:
|
element.peer.device.PutMessageBuffer(element.buffer)
|
||||||
// drop & release to potential consumer
|
element.mutex.Unlock()
|
||||||
old.Drop()
|
|
||||||
old.mutex.Unlock()
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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")
|
peer.device.log.Debug.Println(peer, "- Sending keepalive packet")
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
|
peer.device.PutMessageBuffer(elem.buffer)
|
||||||
|
peer.device.PutOutboundElement(elem)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,8 +243,6 @@ func (peer *Peer) keepKeyFreshSending() {
|
|||||||
*/
|
*/
|
||||||
func (device *Device) RoutineReadFromTUN() {
|
func (device *Device) RoutineReadFromTUN() {
|
||||||
|
|
||||||
elem := device.NewOutboundElement()
|
|
||||||
|
|
||||||
logDebug := device.log.Debug
|
logDebug := device.log.Debug
|
||||||
logError := device.log.Error
|
logError := device.log.Error
|
||||||
|
|
||||||
@@ -256,7 +254,14 @@ func (device *Device) RoutineReadFromTUN() {
|
|||||||
logDebug.Println("Routine: TUN reader - started")
|
logDebug.Println("Routine: TUN reader - started")
|
||||||
device.state.starting.Done()
|
device.state.starting.Done()
|
||||||
|
|
||||||
|
var elem *QueueOutboundElement
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
if elem != nil {
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
device.PutOutboundElement(elem)
|
||||||
|
}
|
||||||
|
elem = device.NewOutboundElement()
|
||||||
|
|
||||||
// read packet
|
// read packet
|
||||||
|
|
||||||
@@ -268,6 +273,8 @@ func (device *Device) RoutineReadFromTUN() {
|
|||||||
logError.Println("Failed to read packet from TUN device:", err)
|
logError.Println("Failed to read packet from TUN device:", err)
|
||||||
device.Close()
|
device.Close()
|
||||||
}
|
}
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
device.PutOutboundElement(elem)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,8 +316,8 @@ func (device *Device) RoutineReadFromTUN() {
|
|||||||
if peer.queue.packetInNonceQueueIsAwaitingKey.Get() {
|
if peer.queue.packetInNonceQueueIsAwaitingKey.Get() {
|
||||||
peer.SendHandshakeInitiation(false)
|
peer.SendHandshakeInitiation(false)
|
||||||
}
|
}
|
||||||
addToOutboundQueue(peer.queue.nonce, elem)
|
addToNonceQueue(peer.queue.nonce, elem, device)
|
||||||
elem = device.NewOutboundElement()
|
elem = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,22 +341,25 @@ func (peer *Peer) RoutineNonce() {
|
|||||||
device := peer.device
|
device := peer.device
|
||||||
logDebug := device.log.Debug
|
logDebug := device.log.Debug
|
||||||
|
|
||||||
defer func() {
|
|
||||||
logDebug.Println(peer, "- Routine: nonce worker - stopped")
|
|
||||||
peer.queue.packetInNonceQueueIsAwaitingKey.Set(false)
|
|
||||||
peer.routines.stopping.Done()
|
|
||||||
}()
|
|
||||||
|
|
||||||
flush := func() {
|
flush := func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-peer.queue.nonce:
|
case elem := <-peer.queue.nonce:
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
device.PutOutboundElement(elem)
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
flush()
|
||||||
|
logDebug.Println(peer, "- Routine: nonce worker - stopped")
|
||||||
|
peer.queue.packetInNonceQueueIsAwaitingKey.Set(false)
|
||||||
|
peer.routines.stopping.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
peer.routines.starting.Done()
|
peer.routines.starting.Done()
|
||||||
logDebug.Println(peer, "- Routine: nonce worker - started")
|
logDebug.Println(peer, "- Routine: nonce worker - started")
|
||||||
|
|
||||||
@@ -403,10 +413,14 @@ func (peer *Peer) RoutineNonce() {
|
|||||||
logDebug.Println(peer, "- Obtained awaited keypair")
|
logDebug.Println(peer, "- Obtained awaited keypair")
|
||||||
|
|
||||||
case <-peer.signals.flushNonceQueue:
|
case <-peer.signals.flushNonceQueue:
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
device.PutOutboundElement(elem)
|
||||||
flush()
|
flush()
|
||||||
goto NextPacket
|
goto NextPacket
|
||||||
|
|
||||||
case <-peer.routines.stop:
|
case <-peer.routines.stop:
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
device.PutOutboundElement(elem)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,6 +435,8 @@ func (peer *Peer) RoutineNonce() {
|
|||||||
|
|
||||||
if elem.nonce >= RejectAfterMessages {
|
if elem.nonce >= RejectAfterMessages {
|
||||||
atomic.StoreUint64(&keypair.sendNonce, RejectAfterMessages)
|
atomic.StoreUint64(&keypair.sendNonce, RejectAfterMessages)
|
||||||
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
device.PutOutboundElement(elem)
|
||||||
goto NextPacket
|
goto NextPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,9 +445,7 @@ func (peer *Peer) RoutineNonce() {
|
|||||||
elem.mutex.Lock()
|
elem.mutex.Lock()
|
||||||
|
|
||||||
// add to parallel and sequential queue
|
// add to parallel and sequential queue
|
||||||
|
addToOutboundAndEncryptionQueues(peer.queue.outbound, device.queue.encryption, elem)
|
||||||
addToEncryptionQueue(device.queue.encryption, elem)
|
|
||||||
addToOutboundQueue(peer.queue.outbound, elem)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,6 +462,19 @@ func (device *Device) RoutineEncryption() {
|
|||||||
logDebug := device.log.Debug
|
logDebug := device.log.Debug
|
||||||
|
|
||||||
defer func() {
|
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")
|
logDebug.Println("Routine: encryption worker - stopped")
|
||||||
device.state.stopping.Done()
|
device.state.stopping.Done()
|
||||||
}()
|
}()
|
||||||
@@ -490,11 +517,13 @@ func (device *Device) RoutineEncryption() {
|
|||||||
// pad content to multiple of 16
|
// pad content to multiple of 16
|
||||||
|
|
||||||
mtu := int(atomic.LoadInt32(&device.tun.mtu))
|
mtu := int(atomic.LoadInt32(&device.tun.mtu))
|
||||||
rem := len(elem.packet) % PaddingMultiple
|
lastUnit := len(elem.packet) % mtu
|
||||||
if rem > 0 {
|
paddedSize := (lastUnit + PaddingMultiple - 1) & ^(PaddingMultiple - 1)
|
||||||
for i := 0; i < PaddingMultiple-rem && len(elem.packet) < mtu; i++ {
|
if paddedSize > mtu {
|
||||||
elem.packet = append(elem.packet, 0)
|
paddedSize = mtu
|
||||||
}
|
}
|
||||||
|
for i := len(elem.packet); i < paddedSize; i++ {
|
||||||
|
elem.packet = append(elem.packet, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// encrypt content and release to consumer
|
// encrypt content and release to consumer
|
||||||
@@ -521,8 +550,25 @@ func (peer *Peer) RoutineSequentialSender() {
|
|||||||
device := peer.device
|
device := peer.device
|
||||||
|
|
||||||
logDebug := device.log.Debug
|
logDebug := device.log.Debug
|
||||||
|
logError := device.log.Error
|
||||||
|
|
||||||
defer func() {
|
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")
|
logDebug.Println(peer, "- Routine: sequential sender - stopped")
|
||||||
peer.routines.stopping.Done()
|
peer.routines.stopping.Done()
|
||||||
}()
|
}()
|
||||||
@@ -545,6 +591,7 @@ func (peer *Peer) RoutineSequentialSender() {
|
|||||||
|
|
||||||
elem.mutex.Lock()
|
elem.mutex.Lock()
|
||||||
if elem.IsDropped() {
|
if elem.IsDropped() {
|
||||||
|
device.PutOutboundElement(elem)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,8 +603,9 @@ func (peer *Peer) RoutineSequentialSender() {
|
|||||||
length := uint64(len(elem.packet))
|
length := uint64(len(elem.packet))
|
||||||
err := peer.SendBuffer(elem.packet)
|
err := peer.SendBuffer(elem.packet)
|
||||||
device.PutMessageBuffer(elem.buffer)
|
device.PutMessageBuffer(elem.buffer)
|
||||||
|
device.PutOutboundElement(elem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logDebug.Println("Failed to send authenticated packet to peer", peer)
|
logError.Println(peer, "- Failed to send data packet", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&peer.stats.txBytes, length)
|
atomic.AddUint64(&peer.stats.txBytes, length)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package tai64n
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package tai64n
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
* This is based heavily on timers.c from the kernel implementation.
|
||||||
*/
|
*/
|
||||||
@@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
tun.go
3
tun.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package tun
|
package tun
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
|
// +build !ios
|
||||||
|
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package tun
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/rwcancel"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.zx2c4.com/wireguard-go/rwcancel"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -54,8 +56,12 @@ func (tun *nativeTun) routineRouteListener(tunIfindex int) {
|
|||||||
|
|
||||||
data := make([]byte, os.Getpagesize())
|
data := make([]byte, os.Getpagesize())
|
||||||
for {
|
for {
|
||||||
|
retry:
|
||||||
n, err := unix.Read(tun.routeSocket, data)
|
n, err := unix.Read(tun.routeSocket, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINTR {
|
||||||
|
goto retry
|
||||||
|
}
|
||||||
tun.errors <- err
|
tun.errors <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -259,7 +265,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
|||||||
func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
|
func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
|
||||||
for {
|
for {
|
||||||
n, err := tun.doRead(buff, offset)
|
n, err := tun.doRead(buff, offset)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
if err == nil || !rwcancel.RetryAfterError(err) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
if !tun.rwcancel.ReadyRead() {
|
if !tun.rwcancel.ReadyRead() {
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/rwcancel"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.zx2c4.com/wireguard-go/rwcancel"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -67,8 +68,12 @@ func (tun *nativeTun) routineRouteListener(tunIfindex int) {
|
|||||||
|
|
||||||
data := make([]byte, os.Getpagesize())
|
data := make([]byte, os.Getpagesize())
|
||||||
for {
|
for {
|
||||||
|
retry:
|
||||||
n, err := unix.Read(tun.routeSocket, data)
|
n, err := unix.Read(tun.routeSocket, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINTR {
|
||||||
|
goto retry
|
||||||
|
}
|
||||||
tun.errors <- err
|
tun.errors <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -257,19 +262,6 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
|||||||
return nil, fmt.Errorf("error %s", errno.Error())
|
return nil, fmt.Errorf("error %s", errno.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set TUN iface to broadcast mode. TUN inferfaces on freebsd come up in point to point by default
|
|
||||||
ifmodemode := unix.IFF_BROADCAST
|
|
||||||
_, _, errno = unix.Syscall(
|
|
||||||
unix.SYS_IOCTL,
|
|
||||||
uintptr(tunfd),
|
|
||||||
uintptr(_TUNSIFMODE),
|
|
||||||
uintptr(unsafe.Pointer(&ifmodemode)),
|
|
||||||
)
|
|
||||||
|
|
||||||
if errno != 0 {
|
|
||||||
return nil, fmt.Errorf("error %s", errno.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rename tun interface
|
// Rename tun interface
|
||||||
|
|
||||||
// Open control socket
|
// Open control socket
|
||||||
@@ -392,7 +384,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
|||||||
func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
|
func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
|
||||||
for {
|
for {
|
||||||
n, err := tun.doRead(buff, offset)
|
n, err := tun.doRead(buff, offset)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
if err == nil || !rwcancel.RetryAfterError(err) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
if !tun.rwcancel.ReadyRead() {
|
if !tun.rwcancel.ReadyRead() {
|
||||||
|
|||||||
@@ -1,21 +1,18 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Copyright 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
|
|
||||||
|
|
||||||
package tun
|
package tun
|
||||||
|
|
||||||
/* Implementation of the TUN device interface for linux
|
/* Implementation of the TUN device interface for linux
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/rwcancel"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.zx2c4.com/wireguard-go/rwcancel"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
"net"
|
"net"
|
||||||
@@ -102,7 +99,7 @@ func (tun *nativeTun) routineNetlinkListener() {
|
|||||||
var msgn int
|
var msgn int
|
||||||
for {
|
for {
|
||||||
msgn, _, _, _, err = unix.Recvmsg(tun.netlinkSock, msg[:], nil, 0)
|
msgn, _, _, _, err = unix.Recvmsg(tun.netlinkSock, msg[:], nil, 0)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
if err == nil || !rwcancel.RetryAfterError(err) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if !tun.netlinkCancel.ReadyRead() {
|
if !tun.netlinkCancel.ReadyRead() {
|
||||||
@@ -334,7 +331,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
|||||||
func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
|
func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
|
||||||
for {
|
for {
|
||||||
n, err := tun.doRead(buff, offset)
|
n, err := tun.doRead(buff, offset)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
if err == nil || !rwcancel.RetryAfterError(err) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
if !tun.fdCancel.ReadyRead() {
|
if !tun.fdCancel.ReadyRead() {
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/rwcancel"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.zx2c4.com/wireguard-go/rwcancel"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -46,8 +46,12 @@ func (tun *nativeTun) routineRouteListener(tunIfindex int) {
|
|||||||
|
|
||||||
data := make([]byte, os.Getpagesize())
|
data := make([]byte, os.Getpagesize())
|
||||||
for {
|
for {
|
||||||
|
retry:
|
||||||
n, err := unix.Read(tun.routeSocket, data)
|
n, err := unix.Read(tun.routeSocket, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EINTR {
|
||||||
|
goto retry
|
||||||
|
}
|
||||||
tun.errors <- err
|
tun.errors <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -90,9 +94,7 @@ func (tun *nativeTun) routineRouteListener(tunIfindex int) {
|
|||||||
|
|
||||||
func errorIsEBUSY(err error) bool {
|
func errorIsEBUSY(err error) bool {
|
||||||
if pe, ok := err.(*os.PathError); ok {
|
if pe, ok := err.(*os.PathError); ok {
|
||||||
if errno, ok := pe.Err.(syscall.Errno); ok && errno == syscall.EBUSY {
|
err = pe.Err
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EBUSY {
|
if errno, ok := err.(syscall.Errno); ok && errno == syscall.EBUSY {
|
||||||
return true
|
return true
|
||||||
@@ -127,19 +129,6 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set TUN iface to broadcast mode
|
|
||||||
ifmodemode := unix.IFF_BROADCAST
|
|
||||||
_, _, errno := unix.Syscall(
|
|
||||||
unix.SYS_IOCTL,
|
|
||||||
uintptr(tunfile.Fd()),
|
|
||||||
uintptr(_TUNSIFMODE),
|
|
||||||
uintptr(unsafe.Pointer(&ifmodemode)),
|
|
||||||
)
|
|
||||||
|
|
||||||
if errno != 0 {
|
|
||||||
return nil, fmt.Errorf("error %s", errno.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
tun, err := CreateTUNFromFile(tunfile, mtu)
|
tun, err := CreateTUNFromFile(tunfile, mtu)
|
||||||
|
|
||||||
if err == nil && name == "tun" {
|
if err == nil && name == "tun" {
|
||||||
@@ -237,7 +226,7 @@ func (tun *nativeTun) doRead(buff []byte, offset int) (int, error) {
|
|||||||
func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
|
func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
|
||||||
for {
|
for {
|
||||||
n, err := tun.doRead(buff, offset)
|
n, err := tun.doRead(buff, offset)
|
||||||
if err == nil || !rwcancel.ErrorIsEAGAIN(err) {
|
if err == nil || !rwcancel.RetryAfterError(err) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
if !tun.rwcancel.ReadyRead() {
|
if !tun.rwcancel.ReadyRead() {
|
||||||
|
|||||||
11
uapi.go
11
uapi.go
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -75,6 +74,7 @@ func ipcGetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
|
|||||||
|
|
||||||
send("public_key=" + peer.handshake.remoteStatic.ToHex())
|
send("public_key=" + peer.handshake.remoteStatic.ToHex())
|
||||||
send("preshared_key=" + peer.handshake.presharedKey.ToHex())
|
send("preshared_key=" + peer.handshake.presharedKey.ToHex())
|
||||||
|
send("protocol_version=1")
|
||||||
if peer.endpoint != nil {
|
if peer.endpoint != nil {
|
||||||
send("endpoint=" + peer.endpoint.DstToString())
|
send("endpoint=" + peer.endpoint.DstToString())
|
||||||
}
|
}
|
||||||
@@ -362,6 +362,13 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
|
|||||||
ones, _ := network.Mask.Size()
|
ones, _ := network.Mask.Size()
|
||||||
device.allowedips.Insert(network.IP, uint(ones), peer)
|
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:
|
default:
|
||||||
logError.Println("Invalid UAPI peer key:", key)
|
logError.Println("Invalid UAPI peer key:", key)
|
||||||
return &IPCError{Code: ipcErrorInvalid}
|
return &IPCError{Code: ipcErrorInvalid}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -18,12 +17,13 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var socketDirectory = "/var/run/wireguard"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ipcErrorIO = -int64(unix.EIO)
|
ipcErrorIO = -int64(unix.EIO)
|
||||||
ipcErrorProtocol = -int64(unix.EPROTO)
|
ipcErrorProtocol = -int64(unix.EPROTO)
|
||||||
ipcErrorInvalid = -int64(unix.EINVAL)
|
ipcErrorInvalid = -int64(unix.EINVAL)
|
||||||
ipcErrorPortInUse = -int64(unix.EADDRINUSE)
|
ipcErrorPortInUse = -int64(unix.EADDRINUSE)
|
||||||
socketDirectory = "/var/run/wireguard"
|
|
||||||
socketName = "%s.sock"
|
socketName = "%s.sock"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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.
|
||||||
* Copyright (C) 2017-2018 Mathias N. Hall-Andersen <mathias@hall-andersen.dk>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.zx2c4.com/wireguard-go/rwcancel"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.zx2c4.com/wireguard-go/rwcancel"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var socketDirectory = "/var/run/wireguard"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ipcErrorIO = -int64(unix.EIO)
|
ipcErrorIO = -int64(unix.EIO)
|
||||||
ipcErrorProtocol = -int64(unix.EPROTO)
|
ipcErrorProtocol = -int64(unix.EPROTO)
|
||||||
ipcErrorInvalid = -int64(unix.EINVAL)
|
ipcErrorInvalid = -int64(unix.EINVAL)
|
||||||
ipcErrorPortInUse = -int64(unix.EADDRINUSE)
|
ipcErrorPortInUse = -int64(unix.EADDRINUSE)
|
||||||
socketDirectory = "/var/run/wireguard"
|
|
||||||
socketName = "%s.sock"
|
socketName = "%s.sock"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
package main
|
package main
|
||||||
const WireGuardGoVersion = "0.0.20180524"
|
const WireGuardGoVersion = "0.0.20181001"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Andreas Auernhammer. All Rights Reserved.
|
* 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
|
package xchacha20poly1305
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0
|
/* 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
|
package xchacha20poly1305
|
||||||
|
|||||||
Reference in New Issue
Block a user