--- /dev/null
+/* 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
+}
--- /dev/null
+/* 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
--- /dev/null
+/* 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
* 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) {
func CreateBind(uport uint16, device *Device) (Bind, uint16, error) {
var err error
- var bind NativeBind
+ var bind nativeBind
port := int(uport)
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()
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
}
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
}
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 {
return (*unix.SockaddrInet6)(unsafe.Pointer(&endpoint.dst[0]))
}
-type NativeBind struct {
+type nativeBind struct {
sock4 int
sock6 int
netlinkSock int
}
var _ Endpoint = (*NativeEndpoint)(nil)
-var _ Bind = (*NativeBind)(nil)
+var _ Bind = (*nativeBind)(nil)
func CreateEndpoint(s string) (Endpoint, error) {
var end NativeEndpoint
}
-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()
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,
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)
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
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
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 {
return size, nil
}
-func (bind *NativeBind) routineRouteListener(device *Device) {
+func (bind *nativeBind) routineRouteListener(device *Device) {
type peerEndpointPtr struct {
peer *Peer
endpoint *Endpoint
package device
-func (bind *NativeBind) SetMark(mark uint32) error {
+func (bind *nativeBind) SetMark(mark uint32) error {
return nil
}
}
}
-func (bind *NativeBind) SetMark(mark uint32) error {
+func (bind *nativeBind) SetMark(mark uint32) error {
var operr error
if fwmarkIoctl == 0 {
return nil
peer.ZeroAndFlushAll()
}
-var roamingDisabled bool
+var RoamingDisabled bool
func (peer *Peer) SetEndpointFromPacket(endpoint Endpoint) {
- if roamingDisabled {
+ if RoamingDisabled {
return
}
peer.Lock()