go x/net/ipv6: ControlMessage将HopLimit==0视为缺失

wz1wpwve  于 10个月前  发布在  Go
关注(0)|答案(1)|浏览(86)

你正在使用的Go版本是( go version )?

  1. $ go version
  2. go1.14.9

这个问题在最新版本的发布中是否会重现?
是的
你正在使用的操作系统和处理器架构是( go env )?
go env 输出

  1. $ go env
  2. GO111MODULE=""
  3. GOARCH="amd64"
  4. GOBIN=""
  5. GOCACHE="/home/luizluca/.cache/go-build"
  6. GOENV="/home/luizluca/.config/go/env"
  7. GOEXE=""
  8. GOFLAGS=""
  9. GOHOSTARCH="amd64"
  10. GOHOSTOS="linux"
  11. GOINSECURE=""
  12. GONOPROXY=""
  13. GONOSUMDB=""
  14. GOOS="linux"
  15. GOPATH="/home/luizluca/go"
  16. GOPRIVATE=""
  17. GOPROXY="https://proxy.golang.org,direct"
  18. GOROOT="/usr/lib64/go/1.14"
  19. GOSUMDB="sum.golang.org"
  20. GOTMPDIR=""
  21. GOTOOLDIR="/usr/lib64/go/1.14/pkg/tool/linux_amd64"
  22. GCCGO="gccgo"
  23. AR="ar"
  24. CC="gcc"
  25. CXX="g++"
  26. CGO_ENABLED="1"
  27. GOMOD="/home/luizluca/prog/blackbox_exporter/go.mod"
  28. CGO_CFLAGS="-g -O2"
  29. CGO_CPPFLAGS=""
  30. CGO_CXXFLAGS="-g -O2"
  31. CGO_FFLAGS="-g -O2"
  32. CGO_LDFLAGS="-g -O2"
  33. PKG_CONFIG="pkg-config"
  34. GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build078173291=/tmp/go-build -gno-record-gcc-switches"

你做了什么?
根据 RFC8200

  1. Hop Limit 8-bit unsigned integer. Decremented by 1 by
  2. each node that forwards the packet. When
  3. forwarding, the packet is discarded if Hop
  4. Limit was zero when received or is decremented
  5. to zero. A node that is the destination of a
  6. packet should not discard a packet with Hop
  7. Limit equal to zero; it should process the
  8. packet normally.

所以,HopLimit == 0 对于在同一子网内的目标发送或接收具有HopLimit 0的数据包是完全有效的。实际上,发送HopLimit==1或HopLimit==0与避免将其转发到不同的网络一样有效。区别在于接收数据包时的情况。如果主机收到具有HopLimit==0的数据包,它可以说它从未被转发过,而HopLimit==1可能只是使用了最后允许的跳数。
然而,ipv6.ControlMessage告诉我它必须在1到255之间。

  1. HopLimit int // hop limit, must be 1 <= value <= 255 when specifying
  2. https://github.com/golang/net/blob/a7d1128ccaa05167332a625f69773af1a0c6b39c/ipv6/control.go#L57

因此,它应该接受HopLimit值在0到255之间。这带来了一个问题:ControlMessage中的HopLimit的初始值(对于go中任何非显式初始化的整数)为0。没有直接的方法来判断ControlMessage中的HopLimit是否缺失或定义为零。
Go也会忽略我在WriteTo()中将其设置为0的情况。也许一个简单的解决方法是将其初始值设置为-1。
顺便说一下,IPv4 TTL没有与TTL==0的数据包必须无条件销毁的问题。
你期望看到什么?
类似于:

  1. +++ https://github.com/golang/net/blob/a7d1128ccaa05167332a625f69773af1a0c6b39c/ipv6/control.go#L57
  2. - HopLimit int // hop limit, must be 1 <= value <= 255 when specifying
  3. + HopLimit int = -1 // hop limit, must be 0 <= value <= 255 when specifying
  4. +++ https://github.com/golang/net/blob/a7d1128ccaa05167332a625f69773af1a0c6b39c/ipv6/control.go#L84
  5. - if ctlOpts[ctlHopLimit].name > 0 && cm.HopLimit > 0 {
  6. + if ctlOpts[ctlHopLimit].name > 0 && cm.HopLimit >= 0 {

我应该提交一个PR吗?
你看到了什么?
我无法在ipv6.WriteTo()中将ControlMessage.HopLimit设置为0,也无法判断ipv6.ReadFrom()中的ControlMessage.HopLimit是否缺失或为零。

0g0grzrc

0g0grzrc1#

CC @mikioh, @ianlancetaylor per owners

相关问题