From fd6f2e1f554cb545c7c554b56e2ac77308822680 Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Tue, 17 Oct 2017 16:50:23 +0200 Subject: [PATCH] Fixed timer issue when failing to send handshake + Identified send4 issue --- src/conn_linux.go | 62 ++++++++++++++++++++++++++++++----------------- src/timers.go | 27 +++++++++------------ src/uapi.go | 3 ++- 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 {