diff --git a/README.md b/README.md index 4043e1b..01aac49 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,12 @@ Please note, there are exceptions to this synchronization. If a version of NTrac ```shell yay -S nexttrace-bin ``` - * The AUR builds are maintained by ouuan + * Build from source (only supports amd64) + + ```shell + yay -S nexttrace + ``` + * The AUR builds are maintained by ouuan, huyz * Linuxbrew's installation command Same as the macOS Homebrew's installation method (homebrew-core version only supports amd64) diff --git a/README_zh_CN.md b/README_zh_CN.md index 24aa462..3598ffa 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -60,8 +60,6 @@ Document Language: [English](README.md) | 简体中文 使用 NextTrace 之前,我们建议您先阅读 [#IP 数据以及精准度说明](https://github.com/nxtrace/NTrace-core/blob/main/README_zh_CN.md#ip-%E6%95%B0%E6%8D%AE%E4%BB%A5%E5%8F%8A%E7%B2%BE%E5%87%86%E5%BA%A6%E8%AF%B4%E6%98%8E),在了解您自己的对数据精准度需求以后再进行抉择。 -[NextTrace 的Telegram频道](https://t.me/nexttrace)由项目成员负责,会传递一部分通知,也会发布一些成员自己分享的小工具。项目成员的意见可作为未来项目发展的可能方向,随着开发进度变化可能会有所改动,不代表未来一定会实装,正式定稿公告会发布于 Issue 中。 - ### Automated Install * Linux @@ -75,9 +73,14 @@ Document Language: [English](README.md) | 简体中文 * 直接下载bin包(仅支持amd64) ```shell - yay -S nexttrace-bin` + yay -S nexttrace-bin ``` - * AUR 的构建分别由 ouuan 维护 + * 从源码构建(仅支持amd64) + + ```shell + yay -S nexttrace + ``` + * AUR 的构建分别由 ouuan, huyz 维护 * Linuxbrew 安装命令 同macOS Homebrew安装方法(homebrew-core版仅支持amd64) diff --git a/fast_trace/fast_trace ipv6.go b/fast_trace/fast_trace ipv6.go index e6e8c3e..2aa7101 100644 --- a/fast_trace/fast_trace ipv6.go +++ b/fast_trace/fast_trace ipv6.go @@ -2,6 +2,7 @@ package fastTrace import ( "fmt" + "github.com/fatih/color" "github.com/nxtrace/NTrace-core/ipgeo" "github.com/nxtrace/NTrace-core/printer" "github.com/nxtrace/NTrace-core/trace" @@ -16,7 +17,7 @@ import ( //var pFastTracer ParamsFastTrace func (f *FastTracer) tracert_v6(location string, ispCollection ISPCollection) { - fmt.Printf("%s『%s %s 』%s\n", printer.YELLOW_PREFIX, location, ispCollection.ISPName, printer.RESET_PREFIX) + fmt.Fprintf(color.Output, "%s\n", color.New(color.FgYellow, color.Bold).Sprintf("『%s %s 』", location, ispCollection.ISPName)) fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IPv6, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize) ip, err := util.DomainLookUp(ispCollection.IPv6, "6", "", true) diff --git a/go.mod b/go.mod index 6adec78..1418874 100644 --- a/go.mod +++ b/go.mod @@ -5,12 +5,12 @@ go 1.22.3 require ( github.com/akamensky/argparse v1.4.0 github.com/google/gopacket v1.1.19 - github.com/oschwald/maxminddb-golang v1.12.0 - github.com/spf13/viper v1.18.2 + github.com/oschwald/maxminddb-golang v1.13.1 + github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 github.com/tsosunchia/powclient v0.1.5 - golang.org/x/net v0.25.0 + golang.org/x/net v0.27.0 golang.org/x/sync v0.7.0 ) @@ -24,7 +24,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect @@ -32,19 +32,19 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240529005216-23cca8864a10 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect + golang.org/x/text v0.16.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) require ( github.com/fatih/color v1.17.0 - github.com/gorilla/websocket v1.5.1 + github.com/gorilla/websocket v1.5.2 github.com/lionsoul2014/ip2region v2.11.2+incompatible github.com/rodaine/table v1.2.0 github.com/tidwall/gjson v1.17.1 github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect - golang.org/x/sys v0.20.0 // indirect + golang.org/x/sys v0.22.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0c02065..3033fc4 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.2 h1:qoW6V1GT3aZxybsbC6oLnailWnB+qTMVwMreOso9XUw= +github.com/gorilla/websocket v1.5.2/go.mod h1:0n9H61RBAcf5/38py2MCYbxzPIY9rOkpvvMT24Rqs30= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -35,8 +35,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs= -github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY= +github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE= +github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -48,8 +48,8 @@ github.com/rodaine/table v1.2.0 h1:38HEnwK4mKSHQJIkavVj+bst1TEY7j9zhLMWu4QJrMA= github.com/rodaine/table v1.2.0/go.mod h1:wejb/q/Yd4T/SVmBSRMr7GCq3KlcZp3gyNYdLSBhkaE= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= +github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= @@ -60,8 +60,8 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -88,14 +88,14 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20240529005216-23cca8864a10 h1:vpzMC/iZhYFAjJzHU0Cfuq+w1vLLsF2vLkDrPjzKYck= -golang.org/x/exp v0.0.0-20240529005216-23cca8864a10/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -103,11 +103,11 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/ipgeo/ipapicom.go b/ipgeo/ipapicom.go index 270ca55..2bad668 100644 --- a/ipgeo/ipapicom.go +++ b/ipgeo/ipapicom.go @@ -14,7 +14,7 @@ import ( ) func IPApiCom(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) { - url := "http://ip-api.com/json/" + ip + "?fields=status,message,country,regionName,city,isp,district,as,lat,lon" + url := token.BaseOrDefault("http://ip-api.com/json/") + ip + "?fields=status,message,country,regionName,city,isp,district,as,lat,lon" client := &http.Client{ // 2 秒超时 Timeout: timeout, diff --git a/ipgeo/ipinfo.go b/ipgeo/ipinfo.go index 30749c7..7d0e3e2 100644 --- a/ipgeo/ipinfo.go +++ b/ipgeo/ipinfo.go @@ -12,7 +12,7 @@ import ( ) func IPInfo(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) { - url := "http://ipinfo.io/" + ip + "?token=" + token.ipinfo + url := token.BaseOrDefault("http://ipinfo.io/") + ip + "?token=" + token.ipinfo client := &http.Client{ // 2 秒超时 Timeout: timeout, diff --git a/ipgeo/ipinsight.go b/ipgeo/ipinsight.go index 0e7cfda..4b45c9c 100644 --- a/ipgeo/ipinsight.go +++ b/ipgeo/ipinsight.go @@ -13,7 +13,7 @@ func IPInSight(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, // 2 秒超时 Timeout: timeout, } - resp, err := client.Get("https://api.ipinsight.io/ip/" + ip + "?token=" + token.ipinsight) + resp, err := client.Get(token.BaseOrDefault("https://api.ipinsight.io/ip/") + ip + "?token=" + token.ipinsight) if err != nil { return nil, err } diff --git a/ipgeo/ipsb.go b/ipgeo/ipsb.go index 1d9fbad..18fb9e4 100644 --- a/ipgeo/ipsb.go +++ b/ipgeo/ipsb.go @@ -11,7 +11,7 @@ import ( ) func IPSB(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) { - url := "https://api.ip.sb/geoip/" + ip + url := token.BaseOrDefault("https://api.ip.sb/geoip/") + ip client := &http.Client{ // 2 秒超时 Timeout: timeout, diff --git a/ipgeo/tokens.go b/ipgeo/tokens.go index 84d6a02..f10771f 100644 --- a/ipgeo/tokens.go +++ b/ipgeo/tokens.go @@ -6,10 +6,19 @@ type tokenData struct { ipinsight string ipinfo string ipleo string + baseUrl string +} + +func (t *tokenData) BaseOrDefault(def string) string { + if t.baseUrl == "" { + return def + } + return t.baseUrl } var token = tokenData{ ipinsight: util.GetenvDefault("NEXTTRACE_IPINSIGHT_TOKEN", ""), ipinfo: util.GetenvDefault("NEXTTRACE_IPINFO_TOKEN", ""), + baseUrl: util.GetenvDefault("NEXTTRACE_IPAPI_BASE", ""), ipleo: "NextTraceDemo", } diff --git a/trace/tcp_ipv4.go b/trace/tcp_ipv4.go index 4bf1c29..01e27c5 100644 --- a/trace/tcp_ipv4.go +++ b/trace/tcp_ipv4.go @@ -264,7 +264,7 @@ func (t *TCPTracer) send(ttl int) error { return err } t.inflightRequestLock.Lock() - hopCh := make(chan Hop) + hopCh := make(chan Hop, 1) t.inflightRequest[int(sequenceNumber)] = hopCh t.inflightRequestLock.Unlock() /* diff --git a/trace/tcp_ipv6.go b/trace/tcp_ipv6.go index 801d1c9..f622a41 100644 --- a/trace/tcp_ipv6.go +++ b/trace/tcp_ipv6.go @@ -251,7 +251,7 @@ func (t *TCPTracerv6) send(ttl int) error { } // log.Println(ttl, sequenceNumber) t.inflightRequestLock.Lock() - hopCh := make(chan Hop) + hopCh := make(chan Hop, 1) t.inflightRequest[int(sequenceNumber)] = hopCh t.inflightRequestLock.Unlock() diff --git a/trace/trace.go b/trace/trace.go index d49dba2..1d73347 100644 --- a/trace/trace.go +++ b/trace/trace.go @@ -42,7 +42,7 @@ type Config struct { AsyncPrinter func(res *Result) PktSize int Maptrace bool - DontFragment bool + DontFragment bool } type Method string diff --git a/trace/udp.go b/trace/udp.go index 3f68401..c9bc423 100644 --- a/trace/udp.go +++ b/trace/udp.go @@ -54,7 +54,7 @@ func (t *UDPTracer) Execute() (*Result, error) { go t.listenICMP() t.sem = semaphore.NewWeighted(int64(t.ParallelRequests)) - for ttl := 1; ttl <= t.MaxHops; ttl++ { + for ttl := t.BeginHop; ttl <= t.MaxHops; ttl++ { // 如果到达最终跳,则退出 if t.final != -1 && ttl > t.final { break @@ -225,7 +225,7 @@ func (t *UDPTracer) send(ttl int) error { // 在对inflightRequest进行写操作的时候应该加锁保护,以免多个goroutine协程试图同时写入造成panic t.inflightRequestLock.Lock() - hopCh := make(chan Hop) + hopCh := make(chan Hop, 1) t.inflightRequest[srcPort] = hopCh t.inflightRequestLock.Unlock() defer func() {