Fixed timer issue when failing to send handshake

+ Identified send4 issue
This commit is contained in:
Mathias Hall-Andersen 2017-10-17 16:50:23 +02:00
parent e86d03dca2
commit fd6f2e1f55
3 changed files with 54 additions and 38 deletions

View file

@ -8,6 +8,7 @@ package main
import ( import (
"errors" "errors"
"fmt"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"net" "net"
"strconv" "strconv"
@ -31,14 +32,14 @@ type IPv4Source struct {
Ifindex int32 Ifindex int32
} }
type Bind struct { type NativeBind struct {
sock4 int sock4 int
sock6 int sock6 int
} }
func CreateUDPBind(port uint16) (UDPBind, uint16, error) { func CreateUDPBind(port uint16) (UDPBind, uint16, error) {
var err error var err error
var bind Bind var bind NativeBind
bind.sock6, port, err = create6(port) bind.sock6, port, err = create6(port)
if err != nil { if err != nil {
@ -52,7 +53,7 @@ func CreateUDPBind(port uint16) (UDPBind, uint16, error) {
return &bind, port, err return &bind, port, err
} }
func (bind *Bind) SetMark(value uint32) error { func (bind *NativeBind) SetMark(value uint32) error {
err := unix.SetsockoptInt( err := unix.SetsockoptInt(
bind.sock6, bind.sock6,
unix.SOL_SOCKET, 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) err1 := unix.Close(bind.sock6)
err2 := unix.Close(bind.sock4) err2 := unix.Close(bind.sock4)
if err1 != nil { if err1 != nil {
@ -81,7 +82,7 @@ func (bind *Bind) Close() error {
return err2 return err2
} }
func (bind *Bind) ReceiveIPv6(buff []byte, end *Endpoint) (int, error) { func (bind *NativeBind) ReceiveIPv6(buff []byte, end *Endpoint) (int, error) {
return receive6( return receive6(
bind.sock6, bind.sock6,
buff, 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( return receive4(
bind.sock4, bind.sock4,
buff, buff,
@ -97,14 +98,14 @@ func (bind *Bind) ReceiveIPv4(buff []byte, end *Endpoint) (int, error) {
) )
} }
func (bind *Bind) Send(buff []byte, end *Endpoint) error { func (bind *NativeBind) Send(buff []byte, end *Endpoint) error {
switch end.src.Family { switch end.dst.Family {
case unix.AF_INET6: case unix.AF_INET6:
return send6(bind.sock6, end, buff) return send6(bind.sock6, end, buff)
case unix.AF_INET: case unix.AF_INET:
return send4(bind.sock4, end, buff) return send4(bind.sock4, end, buff)
default: 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 return fd, uint16(addr.Port), err
} }
func (end *Endpoint) Set(s string) error { func (end *Endpoint) SetDst(s string) error {
addr, err := parseEndpoint(s) addr, err := parseEndpoint(s)
if err != nil { if err != nil {
return err 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() ipv6 := addr.IP.To16()
if ipv6 != nil { if ipv6 != nil {
zone, err := zoneToUint32(addr.Zone) zone, err := zoneToUint32(addr.Zone)
@ -310,17 +324,6 @@ func (end *Endpoint) Set(s string) error {
return nil 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") 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 { func send4(sock int, end *Endpoint, buff []byte) error {
println("send 4")
println(end.DstToString())
// construct message header // construct message header
@ -403,7 +408,6 @@ func send4(sock int, end *Endpoint, buff []byte) error {
Namelen: unix.SizeofSockaddrInet4, Namelen: unix.SizeofSockaddrInet4,
Control: (*byte)(unsafe.Pointer(&cmsg)), Control: (*byte)(unsafe.Pointer(&cmsg)),
} }
msghdr.SetControllen(int(unsafe.Sizeof(cmsg))) msghdr.SetControllen(int(unsafe.Sizeof(cmsg)))
// sendmsg(sock, &msghdr, 0) // sendmsg(sock, &msghdr, 0)
@ -414,9 +418,23 @@ func send4(sock int, end *Endpoint, buff []byte) error {
uintptr(unsafe.Pointer(&msghdr)), uintptr(unsafe.Pointer(&msghdr)),
0, 0,
) )
println(sock)
fmt.Println(errno)
// clear source cache and try again
if errno == unix.EINVAL { if errno == unix.EINVAL {
end.ClearSrc() end.ClearSrc()
cmsg.pktinfo = unix.Inet4Pktinfo{}
_, _, errno = unix.Syscall(
unix.SYS_SENDMSG,
uintptr(sock),
uintptr(unsafe.Pointer(&msghdr)),
0,
)
} }
return errno return errno
} }

View file

@ -279,33 +279,30 @@ func (peer *Peer) RoutineHandshakeInitiator() {
break AttemptHandshakes break AttemptHandshakes
} }
jitter := time.Millisecond * time.Duration(rand.Uint32()%334) // marshal handshake message
// marshal and send
writer := bytes.NewBuffer(temp[:0]) writer := bytes.NewBuffer(temp[:0])
binary.Write(writer, binary.LittleEndian, msg) binary.Write(writer, binary.LittleEndian, msg)
packet := writer.Bytes() packet := writer.Bytes()
peer.mac.AddMacs(packet) peer.mac.AddMacs(packet)
// send to endpoint
err = peer.SendBuffer(packet) err = peer.SendBuffer(packet)
if err != nil { jitter := time.Millisecond * time.Duration(rand.Uint32()%334)
logError.Println(
"Failed to send handshake initiation message to",
peer.String(), ":", err,
)
continue
}
peer.TimerAnyAuthenticatedPacketTraversal()
// set handshake timeout
timeout := time.NewTimer(RekeyTimeout + jitter) timeout := time.NewTimer(RekeyTimeout + jitter)
if err == nil {
peer.TimerAnyAuthenticatedPacketTraversal()
logDebug.Println( logDebug.Println(
"Handshake initiation attempt", "Handshake initiation attempt",
attempts, "sent to", peer.String(), attempts, "sent to", peer.String(),
) )
} else {
logError.Println(
"Failed to send handshake initiation message to",
peer.String(), ":", err,
)
}
// wait for handshake or timeout // wait for handshake or timeout

View file

@ -247,7 +247,8 @@ func ipcSetOperation(device *Device, socket *bufio.ReadWriter) *IPCError {
// set endpoint destination and reset handshake timer // set endpoint destination and reset handshake timer
peer.mutex.Lock() 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.endpoint.set = (err == nil)
peer.mutex.Unlock() peer.mutex.Unlock()
if err != nil { if err != nil {