This commit is contained in:
Eliezer Croitoru 2026-09-09 16:45:56 +03:00
parent c89cea01a6
commit 2fe99008cb
5 changed files with 43 additions and 14 deletions

Binary file not shown.

Binary file not shown.

View File

@ -444,7 +444,8 @@ func (t *Tracer) sendProbeUDP(ttl int) {
t.hops[ttl-1].recordSent() t.hops[ttl-1].recordSent()
t.sendMu.Lock() t.sendMu.Lock()
_ = t.udpPC.SetTTL(ttl) _ = setUDPSocketTTL(t.udpPC, t.udpSend, ttl)
_, err := t.udpSend.WriteTo(payload, &net.UDPAddr{IP: t.targetIP, Port: dstPort}) _, err := t.udpSend.WriteTo(payload, &net.UDPAddr{IP: t.targetIP, Port: dstPort})
t.sendMu.Unlock() t.sendMu.Unlock()
@ -523,6 +524,8 @@ func (t *Tracer) receiveLoop() {
} }
} }
fmt.Fprintf(os.Stderr, "[debug] icmp recv %d bytes from %s\n", n, peer)
from := peerString(peer) from := peerString(peer)
now := time.Now() now := time.Now()
@ -624,19 +627,22 @@ func extractOriginalICMP(data []byte) (seq, id int, ok bool) {
// extractOriginalUDPPort reads the original UDP destination port from the // extractOriginalUDPPort reads the original UDP destination port from the
// embedded original IP+UDP header in a Time Exceeded or Dest Unreachable reply. // embedded original IP+UDP header in a Time Exceeded or Dest Unreachable reply.
func extractOriginalUDPPort(data []byte) (dstPort int, ok bool) { func extractOriginalUDPPort(data []byte) (dstPort int, ok bool) {
if len(data) < 28 { if len(data) < 28 {
return 0, false fmt.Fprintf(os.Stderr, "[debug] extractUDP: too short (%d bytes)\n", len(data))
} return 0, false
ihl := int(data[0]&0x0f) * 4 }
if ihl < 20 || len(data) < ihl+8 { ihl := int(data[0]&0x0f) * 4
return 0, false if ihl < 20 || len(data) < ihl+8 {
} fmt.Fprintf(os.Stderr, "[debug] extractUDP: bad IHL (%d)\n", ihl)
if data[9] != 17 { // protocol must be UDP (17) return 0, false
return 0, false }
} if data[9] != 17 {
// UDP: srcPort(2) dstPort(2) length(2) checksum(2) fmt.Fprintf(os.Stderr, "[debug] extractUDP: proto=%d (not UDP)\n", data[9])
dstPort = int(binary.BigEndian.Uint16(data[ihl+2 : ihl+4])) return 0, false
return dstPort, true }
dstPort = int(binary.BigEndian.Uint16(data[ihl+2 : ihl+4]))
fmt.Fprintf(os.Stderr, "[debug] extractUDP: dstPort=%d\n", dstPort)
return dstPort, true
} }
// ─── Reply handler ──────────────────────────────────────────────────────────── // ─── Reply handler ────────────────────────────────────────────────────────────

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"net" "net"
"time" "time"
"golang.org/x/net/ipv4"
) )
func winAPIProbe(_ net.IP, _ int, _ time.Duration, _ []byte) (float64, string, uint32, error) { func winAPIProbe(_ net.IP, _ int, _ time.Duration, _ []byte) (float64, string, uint32, error) {
@ -15,3 +16,7 @@ func winAPIProbe(_ net.IP, _ int, _ time.Duration, _ []byte) (float64, string, u
func (t *Tracer) sendProbeWinAPI(_ int) {} func (t *Tracer) sendProbeWinAPI(_ int) {}
func udpModeWarning() {} func udpModeWarning() {}
func setUDPSocketTTL(pc *ipv4.PacketConn, conn net.PacketConn, ttl int) error {
return pc.SetTTL(ttl)
}

View File

@ -9,6 +9,7 @@ import (
"time" "time"
"unsafe" "unsafe"
"os" "os"
"golang.org/x/net/ipv4"
) )
var ( var (
@ -142,3 +143,20 @@ func (t *Tracer) sendProbeWinAPI(ttl int) {
} }
}() }()
} }
func setUDPSocketTTL(pc *ipv4.PacketConn, conn net.PacketConn, ttl int) error {
udpConn, ok := conn.(*net.UDPConn)
if !ok {
return pc.SetTTL(ttl)
}
raw, err := udpConn.SyscallConn()
if err != nil {
return pc.SetTTL(ttl)
}
var sockErr error
raw.Control(func(fd uintptr) {
sockErr = syscall.SetsockoptInt(syscall.Handle(fd),
syscall.IPPROTO_IP, syscall.IP_TTL, ttl)
})
return sockErr
}