V3 release
This commit is contained in:
parent
4d67f8be82
commit
db9f887958
@ -6,12 +6,9 @@ COPY src/ .
|
||||
|
||||
RUN go mod init ngtech.co.il/network/livtrace/v2 && go mod tidy
|
||||
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
|
||||
go build -ldflags="-s -w" -o /out/livetrace-linux-amd64 .
|
||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o /out/livetrace-linux-amd64 .
|
||||
|
||||
RUN CGO_ENABLED=0 GOOS=windows GOARCH=amd64 \
|
||||
go build -ldflags="-s -w" -o /out/livetrace-windows-amd64.exe .
|
||||
RUN CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o /out/livetrace-windows-amd64.exe .
|
||||
|
||||
# Stage 2: Export target
|
||||
FROM scratch AS bin
|
||||
COPY --from=builder /out/ /
|
||||
|
||||
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.
43
src/main.go
43
src/main.go
@ -295,12 +295,16 @@ func NewTracer(
|
||||
func (t *Tracer) Done() <-chan struct{} { return t.stopCh }
|
||||
|
||||
func (t *Tracer) Start() error {
|
||||
var err error
|
||||
if t.proto == "winapi" {
|
||||
// Windows ICMP API manages its own sockets per probe.
|
||||
// No raw socket, no receive loop, no cleanup loop needed.
|
||||
go t.probeLoop()
|
||||
return nil
|
||||
}
|
||||
|
||||
// ICMP socket — always required (receiving ICMP errors, and sending in ICMP mode).
|
||||
var err error
|
||||
t.icmpConn, err = icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
if err != nil {
|
||||
// Fallback: unprivileged ICMP dgram (Linux ≥5.x with ping_group_range).
|
||||
t.icmpConn, err = icmp.ListenPacket("udp4", "0.0.0.0:0")
|
||||
if err != nil {
|
||||
hint := "try: sudo ./livetrace"
|
||||
@ -312,7 +316,6 @@ func (t *Tracer) Start() error {
|
||||
}
|
||||
t.icmpPC = t.icmpConn.IPv4PacketConn()
|
||||
|
||||
// UDP sending socket — only needed in UDP mode.
|
||||
if t.proto == "udp" {
|
||||
t.udpSend, err = net.ListenPacket("udp4", ":0")
|
||||
if err != nil {
|
||||
@ -334,7 +337,9 @@ func (t *Tracer) Stop() {
|
||||
default:
|
||||
close(t.stopCh)
|
||||
}
|
||||
_ = t.icmpConn.Close()
|
||||
if t.icmpConn != nil {
|
||||
_ = t.icmpConn.Close()
|
||||
}
|
||||
if t.udpSend != nil {
|
||||
_ = t.udpSend.Close()
|
||||
}
|
||||
@ -386,9 +391,12 @@ func (t *Tracer) makeUDPBytes() []byte {
|
||||
// ─── Sending ──────────────────────────────────────────────────────────────────
|
||||
|
||||
func (t *Tracer) sendProbe(ttl int) {
|
||||
if t.proto == "udp" {
|
||||
switch t.proto {
|
||||
case "udp":
|
||||
t.sendProbeUDP(ttl)
|
||||
} else {
|
||||
case "winapi":
|
||||
t.sendProbeWinAPI(ttl)
|
||||
default:
|
||||
t.sendProbeICMP(ttl)
|
||||
}
|
||||
}
|
||||
@ -449,6 +457,12 @@ func (t *Tracer) sendProbeUDP(ttl int) {
|
||||
}
|
||||
}
|
||||
|
||||
func winAPIProbe(_ net.IP, _ int, _ time.Duration, _ []byte) (float64, string, uint32, error) {
|
||||
return 0, "", 0, fmt.Errorf("winapi probe not supported on this platform")
|
||||
}
|
||||
|
||||
func (t *Tracer) sendProbeWinAPI(_ int) {}
|
||||
|
||||
// ─── Probe loop ───────────────────────────────────────────────────────────────
|
||||
|
||||
func (t *Tracer) probeLoop() {
|
||||
@ -898,7 +912,7 @@ func main() {
|
||||
maxHops := flag.Int("m", 30, "maximum hops")
|
||||
intervalMS := flag.Int("i", 1000, "probe interval in milliseconds")
|
||||
timeoutMS := flag.Int("t", 3000, "probe timeout in milliseconds")
|
||||
proto := flag.String("proto", "icmp", "probe protocol: icmp or udp")
|
||||
proto := flag.String("proto", "icmp", "probe protocol: icmp, udp, or winapi (Windows ICMP API, Windows only)")
|
||||
port := flag.Int("port", 33434, "base destination port (UDP mode only)")
|
||||
size := flag.Int("size", defPktSize, "total IP packet size in bytes (min 28); use 1500 for MTU test")
|
||||
noDNS := flag.Bool("n", false, "disable reverse DNS (show numeric IPs only)")
|
||||
@ -930,10 +944,15 @@ Examples:
|
||||
}
|
||||
|
||||
p := strings.ToLower(*proto)
|
||||
if p != "icmp" && p != "udp" {
|
||||
fmt.Fprintln(os.Stderr, "Error: -proto must be icmp or udp")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if p != "icmp" && p != "udp" && p != "winapi" {
|
||||
fmt.Fprintln(os.Stderr, "Error: -proto must be icmp, udp, or winapi")
|
||||
os.Exit(1)
|
||||
}
|
||||
if p == "winapi" && runtime.GOOS != "windows" {
|
||||
fmt.Fprintln(os.Stderr, "Error: -proto winapi is only available on Windows")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
tracer, err := NewTracer(
|
||||
flag.Arg(0),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user