summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-03-03 05:01:06 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2019-03-04 16:37:11 +0100
commitb8e85267cf22528a96cefba5f86bac5958ce0c58 (patch)
treed6441205ba32a2ea5cb6f8c5dcba80a6387024dd
parent69f0fe67b63d90e523a5a1241fb1b46c2e8dbe03 (diff)
boundif: introduce API for socket binding
-rw-r--r--device/boundif_android.go34
-rw-r--r--device/boundif_darwin.go44
-rw-r--r--device/boundif_windows.go56
-rw-r--r--device/conn_default.go14
-rw-r--r--device/conn_linux.go20
-rw-r--r--device/mark_default.go2
-rw-r--r--device/mark_unix.go2
-rw-r--r--device/peer.go4
8 files changed, 155 insertions, 21 deletions
diff --git a/device/boundif_android.go b/device/boundif_android.go
new file mode 100644
index 0000000..ecc9331
--- /dev/null
+++ b/device/boundif_android.go
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved.
+ */
+
+package device
+
+func (device *Device) PeekLookAtSocketFd4() (fd int, err error) {
+ sysconn, err := device.net.bind.(*nativeBind).ipv4.SyscallConn()
+ if err != nil {
+ return
+ }
+ err = sysconn.Control(func(f uintptr) {
+ fd = int(f)
+ })
+ if err != nil {
+ return
+ }
+ return
+}
+
+func (device *Device) PeekLookAtSocketFd6() (fd int, err error) {
+ sysconn, err := device.net.bind.(*nativeBind).ipv6.SyscallConn()
+ if err != nil {
+ return
+ }
+ err = sysconn.Control(func(f uintptr) {
+ fd = int(f)
+ })
+ if err != nil {
+ return
+ }
+ return
+}
diff --git a/device/boundif_darwin.go b/device/boundif_darwin.go
new file mode 100644
index 0000000..b3d10ba
--- /dev/null
+++ b/device/boundif_darwin.go
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved.
+ */
+
+package device
+
+import (
+ "golang.org/x/sys/unix"
+)
+
+func (device *Device) BindSocketToInterface4(interfaceIndex uint32) error {
+ sysconn, err := device.net.bind.(*nativeBind).ipv4.SyscallConn()
+ if err != nil {
+ return nil
+ }
+ err2 := sysconn.Control(func(fd uintptr) {
+ err = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, int(interfaceIndex))
+ })
+ if err2 != nil {
+ return err2
+ }
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (device *Device) BindSocketToInterface6(interfaceIndex uint32) error {
+ sysconn, err := device.net.bind.(*nativeBind).ipv4.SyscallConn()
+ if err != nil {
+ return nil
+ }
+ err2 := sysconn.Control(func(fd uintptr) {
+ err = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, int(interfaceIndex))
+ })
+ if err2 != nil {
+ return err2
+ }
+ if err != nil {
+ return err
+ }
+ return nil
+} \ No newline at end of file
diff --git a/device/boundif_windows.go b/device/boundif_windows.go
new file mode 100644
index 0000000..00631cb
--- /dev/null
+++ b/device/boundif_windows.go
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2017-2019 WireGuard LLC. All Rights Reserved.
+ */
+
+package device
+
+import (
+ "encoding/binary"
+ "golang.org/x/sys/windows"
+ "unsafe"
+)
+
+const (
+ sockoptIP_UNICAST_IF = 31
+ sockoptIPV6_UNICAST_IF = 31
+)
+
+func (device *Device) BindSocketToInterface4(interfaceIndex uint32) error {
+ /* MSDN says for IPv4 this needs to be in net byte order, so that it's like an IP address with leading zeros. */
+ bytes := make([]byte, 4)
+ binary.BigEndian.PutUint32(bytes, interfaceIndex)
+ interfaceIndex = *(*uint32)(unsafe.Pointer(&bytes[0]))
+
+ sysconn, err := device.net.bind.(*nativeBind).ipv4.SyscallConn()
+ if err != nil {
+ return err
+ }
+ err2 := sysconn.Control(func(fd uintptr) {
+ err = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, sockoptIP_UNICAST_IF, int(interfaceIndex))
+ })
+ if err2 != nil {
+ return err2
+ }
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (device *Device) BindSocketToInterface6(interfaceIndex uint32) error {
+ sysconn, err := device.net.bind.(*nativeBind).ipv6.SyscallConn()
+ if err != nil {
+ return err
+ }
+ err2 := sysconn.Control(func(fd uintptr) {
+ err = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, sockoptIPV6_UNICAST_IF, int(interfaceIndex))
+ })
+ if err2 != nil {
+ return err2
+ }
+ if err != nil {
+ return err
+ }
+ return nil
+} \ No newline at end of file
diff --git a/device/conn_default.go b/device/conn_default.go
index 8a86719..820bb96 100644
--- a/device/conn_default.go
+++ b/device/conn_default.go
@@ -20,14 +20,14 @@ import (
* See conn_linux.go for an implementation on the linux platform.
*/
-type NativeBind struct {
+type nativeBind struct {
ipv4 *net.UDPConn
ipv6 *net.UDPConn
}
type NativeEndpoint net.UDPAddr
-var _ Bind = (*NativeBind)(nil)
+var _ Bind = (*nativeBind)(nil)
var _ Endpoint = (*NativeEndpoint)(nil)
func CreateEndpoint(s string) (Endpoint, error) {
@@ -100,7 +100,7 @@ func extractErrno(err error) error {
func CreateBind(uport uint16, device *Device) (Bind, uint16, error) {
var err error
- var bind NativeBind
+ var bind nativeBind
port := int(uport)
@@ -119,7 +119,7 @@ func CreateBind(uport uint16, device *Device) (Bind, uint16, error) {
return &bind, uint16(port), nil
}
-func (bind *NativeBind) Close() error {
+func (bind *nativeBind) Close() error {
var err1, err2 error
if bind.ipv4 != nil {
err1 = bind.ipv4.Close()
@@ -133,7 +133,7 @@ func (bind *NativeBind) Close() error {
return err2
}
-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
}
@@ -144,7 +144,7 @@ func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
return n, (*NativeEndpoint)(endpoint), err
}
-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
}
@@ -152,7 +152,7 @@ func (bind *NativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
return n, (*NativeEndpoint)(endpoint), err
}
-func (bind *NativeBind) Send(buff []byte, endpoint Endpoint) error {
+func (bind *nativeBind) Send(buff []byte, endpoint Endpoint) error {
var err error
nend := endpoint.(*NativeEndpoint)
if nend.IP.To4() != nil {
diff --git a/device/conn_linux.go b/device/conn_linux.go
index 49949d5..6a8520e 100644
--- a/device/conn_linux.go
+++ b/device/conn_linux.go
@@ -63,7 +63,7 @@ func (endpoint *NativeEndpoint) dst6() *unix.SockaddrInet6 {
return (*unix.SockaddrInet6)(unsafe.Pointer(&endpoint.dst[0]))
}
-type NativeBind struct {
+type nativeBind struct {
sock4 int
sock6 int
netlinkSock int
@@ -72,7 +72,7 @@ type NativeBind struct {
}
var _ Endpoint = (*NativeEndpoint)(nil)
-var _ Bind = (*NativeBind)(nil)
+var _ Bind = (*nativeBind)(nil)
func CreateEndpoint(s string) (Endpoint, error) {
var end NativeEndpoint
@@ -127,9 +127,9 @@ 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 bind NativeBind
+ var bind nativeBind
var newPort uint16
bind.netlinkSock, err = createNetlinkRouteSocket()
@@ -176,7 +176,7 @@ func CreateBind(port uint16, device *Device) (*NativeBind, uint16, error) {
return &bind, port, nil
}
-func (bind *NativeBind) SetMark(value uint32) error {
+func (bind *nativeBind) SetMark(value uint32) error {
if bind.sock6 != -1 {
err := unix.SetsockoptInt(
bind.sock6,
@@ -213,7 +213,7 @@ func closeUnblock(fd int) error {
return unix.Close(fd)
}
-func (bind *NativeBind) Close() error {
+func (bind *nativeBind) Close() error {
var err1, err2, err3 error
if bind.sock6 != -1 {
err1 = closeUnblock(bind.sock6)
@@ -232,7 +232,7 @@ func (bind *NativeBind) Close() error {
return err3
}
-func (bind *NativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
+func (bind *nativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
var end NativeEndpoint
if bind.sock6 == -1 {
return 0, nil, syscall.EAFNOSUPPORT
@@ -245,7 +245,7 @@ func (bind *NativeBind) ReceiveIPv6(buff []byte) (int, Endpoint, error) {
return n, &end, err
}
-func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
+func (bind *nativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
var end NativeEndpoint
if bind.sock4 == -1 {
return 0, nil, syscall.EAFNOSUPPORT
@@ -258,7 +258,7 @@ func (bind *NativeBind) ReceiveIPv4(buff []byte) (int, Endpoint, error) {
return n, &end, err
}
-func (bind *NativeBind) Send(buff []byte, end Endpoint) error {
+func (bind *nativeBind) Send(buff []byte, end Endpoint) error {
nend := end.(*NativeEndpoint)
if !nend.isV6 {
if bind.sock4 == -1 {
@@ -592,7 +592,7 @@ func receive6(sock int, buff []byte, end *NativeEndpoint) (int, error) {
return size, nil
}
-func (bind *NativeBind) routineRouteListener(device *Device) {
+func (bind *nativeBind) routineRouteListener(device *Device) {
type peerEndpointPtr struct {
peer *Peer
endpoint *Endpoint
diff --git a/device/mark_default.go b/device/mark_default.go
index 76b1015..7de2524 100644
--- a/device/mark_default.go
+++ b/device/mark_default.go
@@ -7,6 +7,6 @@
package device
-func (bind *NativeBind) SetMark(mark uint32) error {
+func (bind *nativeBind) SetMark(mark uint32) error {
return nil
}
diff --git a/device/mark_unix.go b/device/mark_unix.go
index ee64cc9..a791c71 100644
--- a/device/mark_unix.go
+++ b/device/mark_unix.go
@@ -25,7 +25,7 @@ func init() {
}
}
-func (bind *NativeBind) SetMark(mark uint32) error {
+func (bind *nativeBind) SetMark(mark uint32) error {
var operr error
if fwmarkIoctl == 0 {
return nil
diff --git a/device/peer.go b/device/peer.go
index af3ef9d..815dff4 100644
--- a/device/peer.go
+++ b/device/peer.go
@@ -258,10 +258,10 @@ func (peer *Peer) Stop() {
peer.ZeroAndFlushAll()
}
-var roamingDisabled bool
+var RoamingDisabled bool
func (peer *Peer) SetEndpointFromPacket(endpoint Endpoint) {
- if roamingDisabled {
+ if RoamingDisabled {
return
}
peer.Lock()