mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
固定UDP模式的源端口,改善在一些负载均衡网络环境下的效果,在使用ENV "NEXTTRACE_RANDOMPORT" 支持继续随机分配源端口。
https://github.com/nxtrace/NTrace-core/issues/296 https://github.com/nxtrace/NTrace-core/pull/297 Co-authored-by: Yunlq <vinculo025@gmail.com> Co-authored-by: tsosunchia <59512455+tsosunchia@users.noreply.github.com>
This commit is contained in:
47
trace/udp.go
47
trace/udp.go
@@ -4,6 +4,7 @@ import (
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -135,9 +136,11 @@ func (t *UDPTracer) handleICMPMessage(msg ReceivedMessage, data []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *UDPTracer) getUDPConn(try int) (net.IP, int, net.PacketConn) {
|
||||
srcIP, _ := util.LocalIPPort(t.DestIP)
|
||||
var cachedLocalPort int
|
||||
var localPortOnce sync.Once
|
||||
|
||||
func (t *UDPTracer) getUDPConn(try int) (net.IP, int, net.PacketConn, error) {
|
||||
srcIP, _ := util.LocalIPPort(t.DestIP)
|
||||
var ipString string
|
||||
if srcIP == nil {
|
||||
ipString = ""
|
||||
@@ -145,14 +148,37 @@ func (t *UDPTracer) getUDPConn(try int) (net.IP, int, net.PacketConn) {
|
||||
ipString = srcIP.String()
|
||||
}
|
||||
|
||||
udpConn, err := net.ListenPacket("udp", ipString+":0")
|
||||
if err != nil {
|
||||
if try > 3 {
|
||||
log.Fatal(err)
|
||||
// Check environment variable to decide caching behavior
|
||||
if util.GetenvDefault("NEXTTRACE_RANDOMPORT", "") == "" {
|
||||
// Use cached random port logic
|
||||
if cachedLocalPort == 0 {
|
||||
// First time: listen on a random port
|
||||
udpConn, err := net.ListenPacket("udp", ipString+":0")
|
||||
if err != nil {
|
||||
if try > 3 {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return srcIP, 0, nil, err
|
||||
}
|
||||
cachedLocalPort = udpConn.LocalAddr().(*net.UDPAddr).Port
|
||||
// Close the initial connection after obtaining the port
|
||||
udpConn.Close()
|
||||
}
|
||||
return t.getUDPConn(try + 1)
|
||||
// Use the cached local port to establish a new connection
|
||||
udpConn, err := net.ListenPacket("udp", ipString+":"+strconv.Itoa(cachedLocalPort))
|
||||
if err != nil {
|
||||
return srcIP, cachedLocalPort, nil, err
|
||||
}
|
||||
return srcIP, cachedLocalPort, udpConn, nil
|
||||
} else {
|
||||
// Without caching: create a new connection each time using a new random port
|
||||
udpConn, err := net.ListenPacket("udp", ipString+":0")
|
||||
if err != nil {
|
||||
return srcIP, 0, nil, err
|
||||
}
|
||||
localPort := udpConn.LocalAddr().(*net.UDPAddr).Port
|
||||
return srcIP, localPort, udpConn, nil
|
||||
}
|
||||
return srcIP, udpConn.LocalAddr().(*net.UDPAddr).Port, udpConn
|
||||
}
|
||||
|
||||
func (t *UDPTracer) send(ttl int) error {
|
||||
@@ -167,7 +193,10 @@ func (t *UDPTracer) send(ttl int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
srcIP, srcPort, udpConn := t.getUDPConn(0)
|
||||
srcIP, srcPort, udpConn, err := t.getUDPConn(0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer udpConn.Close()
|
||||
|
||||
//var payload []byte
|
||||
|
||||
Reference in New Issue
Block a user