fix IPv6 pings

This commit is contained in:
pufferffish 2024-04-11 02:25:09 +01:00
parent bf46e5a3da
commit 1b6b1881ee

View file

@ -5,10 +5,12 @@ import (
"context" "context"
srand "crypto/rand" srand "crypto/rand"
"crypto/subtle" "crypto/subtle"
"encoding/binary"
"encoding/json" "encoding/json"
"errors" "errors"
"golang.org/x/net/icmp" "golang.org/x/net/icmp"
"golang.org/x/net/ipv4" "golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"golang.zx2c4.com/wireguard/device" "golang.zx2c4.com/wireguard/device"
"io" "io"
"log" "log"
@ -415,7 +417,16 @@ func (d VirtualTun) pingIPs() {
Data: data, Data: data,
} }
icmpBytes, _ := (&icmp.Message{Type: ipv4.ICMPTypeEcho, Code: 0, Body: &requestPing}).Marshal(nil) var icmpBytes []byte
if addr.Is4() {
icmpBytes, _ = (&icmp.Message{Type: ipv4.ICMPTypeEcho, Code: 0, Body: &requestPing}).Marshal(nil)
} else if addr.Is6() {
icmpBytes, _ = (&icmp.Message{Type: ipv6.ICMPTypeEchoRequest, Code: 0, Body: &requestPing}).Marshal(nil)
} else {
errorLogger.Printf("Failed to ping %s: invalid address: %s\n", addr, addr.String())
continue
}
_ = socket.SetReadDeadline(time.Now().Add(time.Duration(d.Conf.CheckAliveInterval) * time.Second)) _ = socket.SetReadDeadline(time.Now().Add(time.Duration(d.Conf.CheckAliveInterval) * time.Second))
_, err = socket.Write(icmpBytes) _, err = socket.Write(icmpBytes)
if err != nil { if err != nil {
@ -437,14 +448,31 @@ func (d VirtualTun) pingIPs() {
return return
} }
replyPing, ok := replyPacket.Body.(*icmp.Echo) if addr.Is4() {
if !ok { replyPing, ok := replyPacket.Body.(*icmp.Echo)
errorLogger.Printf("Failed to parse ping response from %s: invalid reply type: %v\n", addr, replyPacket) if !ok {
return errorLogger.Printf("Failed to parse ping response from %s: invalid reply type: %s\n", addr, replyPacket.Type)
return
}
if !bytes.Equal(replyPing.Data, requestPing.Data) || replyPing.Seq != requestPing.Seq {
errorLogger.Printf("Failed to parse ping response from %s: invalid ping reply: %v\n", addr, replyPing)
return
}
} }
if !bytes.Equal(replyPing.Data, requestPing.Data) || replyPing.Seq != requestPing.Seq {
errorLogger.Printf("Failed to parse ping response from %s: invalid ping reply: %v\n", addr, replyPing) if addr.Is6() {
return replyPing, ok := replyPacket.Body.(*icmp.RawBody)
if !ok {
errorLogger.Printf("Failed to parse ping response from %s: invalid reply type: %s\n", addr, replyPacket.Type)
return
}
seq := binary.BigEndian.Uint16(replyPing.Data[2:4])
pongBody := replyPing.Data[4:]
if !bytes.Equal(pongBody, requestPing.Data) || int(seq) != requestPing.Seq {
errorLogger.Printf("Failed to parse ping response from %s: invalid ping reply: %v\n", addr, replyPing)
return
}
} }
d.PingRecord[addr.String()] = uint64(time.Now().Unix()) d.PingRecord[addr.String()] = uint64(time.Now().Unix())