Golang中的mDNS问题处理(mDNS系列3)
起因
为了在Windows上跨平台编译Linux上运行的Golang程序,选择了CGO_ENABLED=0
。此时DNS解析也被切换至了纯Go版本的解析器上,而这个版本的解析器不支持mDNS。为了方便我在自家使用mDNS,便有了下文的方案探究。
分析
首先查找了一些官方文档,发现官方明确短期内是不会在纯Go版本的解析器上支持mDNS的,具体详见参考1。为了通用,便想到了monkey patch
这一方式去处理,而这种在Python很好处理的方案,在Golang中却并不好写。
在我目前写的代码中就gorm.io/gorm(gorm.io/driver/postgres)
、github.com/influxdata/influxdb-client-go/v2
这两部分库会用到mDNS,追了一下源码,发现会公共调用func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IPAddr, error)
这个方法,那理论上只要处理它即可。之后查了使用较多的hook开源库,却发现gomonkey
支持hook私有方法,但是hook后却没有办法调用原方法,而gohook
支持调用原方法,却不支持hook私有方法。在衡量了一下处理难度后,决定对代码调用往上追踪一下,直到发现公有方法,之后在使用gohook
处理。而这两个方法便是func (r *Resolver) LookupHost(ctx context.Context, host string) (addrs []string, err error)
及 func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error)
。
处理
完整版代码如下:
1 | package main |
之后在进入主流程前调用AddMDNSSupport
即可,我个人是把调用放到了init
函数当中了。注意使用时必须保证主机上avahi-resolve-address
命令执行正常。