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 go mod init ngtech.co.il/network/livtrace/v2 && go mod tidy
|
||||||
|
|
||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o /out/livetrace-linux-amd64 .
|
||||||
go build -ldflags="-s -w" -o /out/livetrace-linux-amd64 .
|
|
||||||
|
|
||||||
RUN CGO_ENABLED=0 GOOS=windows GOARCH=amd64 \
|
RUN CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o /out/livetrace-windows-amd64.exe .
|
||||||
go build -ldflags="-s -w" -o /out/livetrace-windows-amd64.exe .
|
|
||||||
|
|
||||||
# Stage 2: Export target
|
|
||||||
FROM scratch AS bin
|
FROM scratch AS bin
|
||||||
COPY --from=builder /out/ /
|
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) Done() <-chan struct{} { return t.stopCh }
|
||||||
|
|
||||||
func (t *Tracer) Start() error {
|
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")
|
t.icmpConn, err = icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||||
if err != nil {
|
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")
|
t.icmpConn, err = icmp.ListenPacket("udp4", "0.0.0.0:0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hint := "try: sudo ./livetrace"
|
hint := "try: sudo ./livetrace"
|
||||||
@ -312,7 +316,6 @@ func (t *Tracer) Start() error {
|
|||||||
}
|
}
|
||||||
t.icmpPC = t.icmpConn.IPv4PacketConn()
|
t.icmpPC = t.icmpConn.IPv4PacketConn()
|
||||||
|
|
||||||
// UDP sending socket — only needed in UDP mode.
|
|
||||||
if t.proto == "udp" {
|
if t.proto == "udp" {
|
||||||
t.udpSend, err = net.ListenPacket("udp4", ":0")
|
t.udpSend, err = net.ListenPacket("udp4", ":0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -334,7 +337,9 @@ func (t *Tracer) Stop() {
|
|||||||
default:
|
default:
|
||||||
close(t.stopCh)
|
close(t.stopCh)
|
||||||
}
|
}
|
||||||
_ = t.icmpConn.Close()
|
if t.icmpConn != nil {
|
||||||
|
_ = t.icmpConn.Close()
|
||||||
|
}
|
||||||
if t.udpSend != nil {
|
if t.udpSend != nil {
|
||||||
_ = t.udpSend.Close()
|
_ = t.udpSend.Close()
|
||||||
}
|
}
|
||||||
@ -386,9 +391,12 @@ func (t *Tracer) makeUDPBytes() []byte {
|
|||||||
// ─── Sending ──────────────────────────────────────────────────────────────────
|
// ─── Sending ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func (t *Tracer) sendProbe(ttl int) {
|
func (t *Tracer) sendProbe(ttl int) {
|
||||||
if t.proto == "udp" {
|
switch t.proto {
|
||||||
|
case "udp":
|
||||||
t.sendProbeUDP(ttl)
|
t.sendProbeUDP(ttl)
|
||||||
} else {
|
case "winapi":
|
||||||
|
t.sendProbeWinAPI(ttl)
|
||||||
|
default:
|
||||||
t.sendProbeICMP(ttl)
|
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 ───────────────────────────────────────────────────────────────
|
// ─── Probe loop ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func (t *Tracer) probeLoop() {
|
func (t *Tracer) probeLoop() {
|
||||||
@ -898,7 +912,7 @@ func main() {
|
|||||||
maxHops := flag.Int("m", 30, "maximum hops")
|
maxHops := flag.Int("m", 30, "maximum hops")
|
||||||
intervalMS := flag.Int("i", 1000, "probe interval in milliseconds")
|
intervalMS := flag.Int("i", 1000, "probe interval in milliseconds")
|
||||||
timeoutMS := flag.Int("t", 3000, "probe timeout 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)")
|
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")
|
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)")
|
noDNS := flag.Bool("n", false, "disable reverse DNS (show numeric IPs only)")
|
||||||
@ -930,10 +944,15 @@ Examples:
|
|||||||
}
|
}
|
||||||
|
|
||||||
p := strings.ToLower(*proto)
|
p := strings.ToLower(*proto)
|
||||||
if p != "icmp" && p != "udp" {
|
|
||||||
fmt.Fprintln(os.Stderr, "Error: -proto must be icmp or udp")
|
if p != "icmp" && p != "udp" && p != "winapi" {
|
||||||
os.Exit(1)
|
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(
|
tracer, err := NewTracer(
|
||||||
flag.Arg(0),
|
flag.Arg(0),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user