V3.3
This commit is contained in:
parent
c89cea01a6
commit
2fe99008cb
BIN
dist/livetrace-linux-amd64
vendored
BIN
dist/livetrace-linux-amd64
vendored
Binary file not shown.
BIN
dist/livetrace-windows-amd64.exe
vendored
BIN
dist/livetrace-windows-amd64.exe
vendored
Binary file not shown.
34
src/main.go
34
src/main.go
@ -444,7 +444,8 @@ func (t *Tracer) sendProbeUDP(ttl int) {
|
||||
t.hops[ttl-1].recordSent()
|
||||
|
||||
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})
|
||||
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)
|
||||
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
|
||||
// embedded original IP+UDP header in a Time Exceeded or Dest Unreachable reply.
|
||||
func extractOriginalUDPPort(data []byte) (dstPort int, ok bool) {
|
||||
if len(data) < 28 {
|
||||
return 0, false
|
||||
}
|
||||
ihl := int(data[0]&0x0f) * 4
|
||||
if ihl < 20 || len(data) < ihl+8 {
|
||||
return 0, false
|
||||
}
|
||||
if data[9] != 17 { // protocol must be UDP (17)
|
||||
return 0, false
|
||||
}
|
||||
// UDP: srcPort(2) dstPort(2) length(2) checksum(2)
|
||||
dstPort = int(binary.BigEndian.Uint16(data[ihl+2 : ihl+4]))
|
||||
return dstPort, true
|
||||
if len(data) < 28 {
|
||||
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 {
|
||||
fmt.Fprintf(os.Stderr, "[debug] extractUDP: bad IHL (%d)\n", ihl)
|
||||
return 0, false
|
||||
}
|
||||
if data[9] != 17 {
|
||||
fmt.Fprintf(os.Stderr, "[debug] extractUDP: proto=%d (not UDP)\n", data[9])
|
||||
return 0, false
|
||||
}
|
||||
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 ────────────────────────────────────────────────────────────
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
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 udpModeWarning() {}
|
||||
|
||||
func setUDPSocketTTL(pc *ipv4.PacketConn, conn net.PacketConn, ttl int) error {
|
||||
return pc.SetTTL(ttl)
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
"os"
|
||||
"golang.org/x/net/ipv4"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user