aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2017-10-17 16:50:23 +0200
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2017-10-17 16:50:23 +0200
commitfd6f2e1f554cb545c7c554b56e2ac77308822680 (patch)
tree9e382c6f549510a42f1fb9a0e8551fb96f54e7ed
parentInitial implementation of source caching (diff)
downloadwireguard-go-fd6f2e1f554cb545c7c554b56e2ac77308822680.tar.xz
wireguard-go-fd6f2e1f554cb545c7c554b56e2ac77308822680.zip
Fixed timer issue when failing to send handshake
+ Identified send4 issue
-rw-r--r--src/conn_linux.go62
-rw-r--r--src/timers.go27
-rw-r--r--src/uapi.go3
3 files changed, 54 insertions, 38 deletions
diff --git a/src/conn_linux.go b/src/conn_linux.go
index 4a5a3f0..51ca4f3 100644
--- a/src/conn_linux.go
+++ b/src/conn_linux.go
@@ -8,6 +8,7 @@ package main
import (
"errors"
+ "fmt"
"golang.org/x/sys/unix"
"net"
"strconv"
@@ -31,14 +32,14 @@ type IPv4Source struct {
Ifindex int32
}
-type Bind struct {
+type NativeBind struct {
sock4 int
sock6 int
}
func CreateUDPBind(port uint16) (UDPBind, uint16, error) {
var err error
- var bind Bind
+ var bind NativeBind
bind.sock6, port, err = create6(port)
if err != nil {
@@ -52,7 +53,7 @@ func CreateUDPBind(port uint16) (UDPBind, uint16, error) {
return &bind, port, err
}
-func (bind *Bind) SetMark(value uint32) error {
+func (bind *NativeBind) SetMark(value uint32) error {
err := unix.SetsockoptInt(
bind.sock6,
unix.SOL_SOCKET,
@@ -72,7 +73,7 @@ func (bind *Bind) SetMark(value uint32) error {
)
}
-func (bind *Bind) Close() error {
+func (bind *NativeBind) Close() error {
err1 := unix.Close(bind.sock6)
err2 := unix.Close(bind.sock4)
if err1 != nil {
@@ -81,7 +82,7 @@ func (bind *Bind) Close() error {
return err2
}
-func (bind *Bind) ReceiveIPv6(buff []byte, end *Endpoint) (int, error) {
+func (bind *NativeBind) ReceiveIPv6(buff []byte, end *Endpoint) (int, error) {
return receive6(
bind.sock6,
buff,
@@ -89,7 +90,7 @@ func (bind *Bind) ReceiveIPv6(buff []byte, end *Endpoint) (int, error) {
)
}
-func (bind *Bind) ReceiveIPv4(buff []byte, end *Endpoint) (int, error) {
+func (bind *NativeBind) ReceiveIPv4(buff []byte, end *Endpoint) (int, error) {
return receive4(
bind.sock4,
buff,
@@ -97,14 +98,14 @@ func (bind *Bind) ReceiveIPv4(buff []byte, end *Endpoint) (int, error) {
)
}
-func (bind *Bind) Send(buff []byte, end *Endpoint) error {
- switch end.src.Family {
+func (bind *NativeBind) Send(buff []byte, end *Endpoint) error {
+ switch end.dst.Family {
case unix.AF_INET6:
return send6(bind.sock6, end, buff)
case unix.AF_INET:
return send4(bind.sock4, end, buff)
default:
- return errors.New("Unknown address family of source")
+ return errors.New("Unknown address family of destination")
}
}
@@ -288,12 +289,25 @@ func create6(port uint16) (int, uint16, error) {
return fd, uint16(addr.Port), err
}
-func (end *Endpoint) Set(s string) error {
+func (end *Endpoint) SetDst(s string) error {
addr, err := parseEndpoint(s)
if err != nil {
return err
}
+ fmt.Println(addr, err)
+
+ ipv4 := addr.IP.To4()
+ if ipv4 != nil {
+ dst := (*unix.RawSockaddrInet4)(unsafe.Pointer(&end.dst))
+ dst.Family = unix.AF_INET
+ dst.Port = uint16(addr.Port)
+ dst.Zero = [8]byte{}
+ copy(dst.Addr[:], ipv4)
+ end.ClearSrc()
+ return nil
+ }
+
ipv6 := addr.IP.To16()
if ipv6 != nil {
zone, err := zoneToUint32(addr.Zone)
@@ -310,17 +324,6 @@ func (end *Endpoint) Set(s string) error {
return nil
}
- ipv4 := addr.IP.To4()
- if ipv4 != nil {
- dst := (*unix.RawSockaddrInet4)(unsafe.Pointer(&end.dst))
- dst.Family = unix.AF_INET
- dst.Port = uint16(addr.Port)
- dst.Zero = [8]byte{}
- copy(dst.Addr[:], ipv4)
- end.ClearSrc()
- return nil
- }
-
return errors.New("Failed to recognize IP address format")
}
@@ -372,6 +375,8 @@ func send6(sock int, end *Endpoint, buff []byte) error {
}
func send4(sock int, end *Endpoint, buff []byte) error {
+ println("send 4")
+ println(end.DstToString())
// construct message header
@@ -403,7 +408,6 @@ func send4(sock int, end *Endpoint, buff []byte) error {
Namelen: unix.SizeofSockaddrInet4,
Control: (*byte)(unsafe.Pointer(&cmsg)),
}
-
msghdr.SetControllen(int(unsafe.Sizeof(cmsg)))
// sendmsg(sock, &msghdr, 0)
@@ -414,9 +418,23 @@ func send4(sock int, end *Endpoint, buff []byte) error {
uintptr(unsafe.Pointer(&msghdr)),
0,
)
+
+ println(sock)
+ fmt.Println(errno)
+
+ // clear source cache and try again
+
if errno == unix.EINVAL {
end.ClearSrc()
+ cmsg.pktinfo = unix.Inet4Pktinfo{}
+ _, _, errno = unix.Syscall(
+ unix.SYS_SENDMSG,
+ uintptr(sock),
+ uintptr(unsafe.Pointer(&msghdr)),
+ 0,
+ )
}
+
return errno
}
diff --git a/src/timers.go b/src/timers.go
index 2a94005..31165a3 100644
--- a/src/timers.go
+++ b/src/timers.go
@@ -279,34 +279,31 @@ func (peer *Peer) RoutineHandshakeInitiator() {
break AttemptHandshakes
}
- jitter := time.Millisecond * time.Duration(rand.Uint32()%334)
-
- // marshal and send
+ // marshal handshake message
writer := bytes.NewBuffer(temp[:0])
binary.Write(writer, binary.LittleEndian, msg)
packet := writer.Bytes()
peer.mac.AddMacs(packet)
+ // send to endpoint
+
err = peer.SendBuffer(packet)
- if err != nil {
+ jitter := time.Millisecond * time.Duration(rand.Uint32()%334)
+ timeout := time.NewTimer(RekeyTimeout + jitter)
+ if err == nil {
+ peer.TimerAnyAuthenticatedPacketTraversal()
+ logDebug.Println(
+ "Handshake initiation attempt",
+ attempts, "sent to", peer.String(),
+ )
+ } else {
logError.Println(
"Failed to send handshake initiation message to",
peer.String(), ":", err,
)
- continue
}
- peer.TimerAnyAuthenticatedPacketTraversal()
-
- // set handshake timeout
-
- timeout := time.NewTimer(RekeyTimeout + jitter)
- logDebug.Println(
- "Handshake initiation attempt",
- attempts, "sent to", peer.String(),
- )
-
// wait for handshake or timeout
select {
diff --git a/src/uapi.go b/src/uapi.go
index 2de26ee..accffd1 100644
--- a/src/uapi.go
+++ b/src/uapi.go
@@ -247,7 +247,8 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
// set endpoint destination and reset handshake timer
peer.mutex.Lock()
- err := peer.endpoint.value.Set(value)
+ err := peer.endpoint.value.SetDst(value)
+ fmt.Println(peer.endpoint.value.DstToString(), err)
peer.endpoint.set = (err == nil)
peer.mutex.Unlock()
if err != nil {