diff options
author | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2017-10-17 16:50:23 +0200 |
---|---|---|
committer | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2017-10-17 16:50:23 +0200 |
commit | fd6f2e1f554cb545c7c554b56e2ac77308822680 (patch) | |
tree | 9e382c6f549510a42f1fb9a0e8551fb96f54e7ed /src | |
parent | e86d03dca23e5adcbd1c7bd30157bc7d19a932d7 (diff) |
Fixed timer issue when failing to send handshake
+ Identified send4 issue
Diffstat (limited to 'src')
-rw-r--r-- | src/conn_linux.go | 62 | ||||
-rw-r--r-- | src/timers.go | 27 | ||||
-rw-r--r-- | 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 { |