目录
资源及使用方案
资源地址
链接: https://pan.baidu.com/s/1_iadA0k80ZeUB1qTAFayjQ?pwd=wry6 提取码: wry6
使用方式
0.使用资源中的文件替换安装目录下的原文件(默认安装地址是c:\program files\wireguard)
记得备份原文件,修改后重启wireguard客户端。
1.百度找一个公共dns服务器地址
2.在wireguard客户端原有配置上添加两个注释(端口是53)
3.保存后连接
日志内容可见ipv6地址
不知道为啥解析出来A记录也是ipv6地址,,凑合用吧- -。DnsServer不传值就还是原来的解析逻辑,能得到ipv4地址。。
源码修改思路
源码地址
修改后代码
https://github.com/xxxxssss12/wireguard-windows/tree/dnsresolve-ipv6
endpoint解析代码
https://github.com/WireGuard/wireguard-windows/blob/master/conf/dnsresolver_windows.go
这个逻辑是调用windowsApi做dns解析得到ip地址。自己调试发现针对http://www.baidu.com域名解析始终得到的是ipv4地址,需要修改其中逻辑。因为windowsApi不好改,经一番研究之后决定使用http://github.com/miekg/dns来做dns解析,替代原有的windowsApi解析逻辑
miekg/dns使用demo
由demo可知,他可以设置一个dns服务器,然后上服务器做域名解析记录。但是他需要有一个入参是dns服务器地址,所以要传参给他。
DNS解析结果中A记录ipv4地址,AAAA记录是ipv6地址。
修改代码逻辑的思路是在配置文件中通过注释添加dns服务器地址,若有填地址则优先miekg/dns来解析文件。
解析代码(conf/dnsresolver_windows.go):
func resolveHostnameOnce(name string, dnsServer string, ipv6Priority bool) (resolvedIPString string, err error) {
// use miekg.dns
log.Printf("dns resolve: domain=%s, dnsServer= %s, ipv6Priority= %t", name, dnsServer, ipv6Priority)
if dnsServer != "" {
log.Printf("miekg.dns resolve ipv6 address: %s", dnsServer)
c := new(dns.Client)
m := new(dns.Msg)
m.SetQuestion(dns.Fqdn(name), dns.TypeAAAA)
ipv6, _, err := c.Exchange(m, dnsServer)
ipv6Addr := ""
haveIpv6 := false
if err == nil && len(ipv6.Answer) > 0 {
for _, ans := range ipv6.Answer {
if aaaa, ok := ans.(*dns.AAAA); ok {
haveIpv6 = true
ipv6Addr = aaaa.AAAA.String()
log.Printf("miekg.dns resolve ipv6 address: %s", ipv6Addr)
break
}
}
} else if err != nil {
log.Printf("miekg.dns get ipv6 err: %s", err)
}
m = new(dns.Msg)
m.SetQuestion(dns.Fqdn(name), dns.TypeA)
ipv4, _, err := c.Exchange(m, dnsServer)
ipv4Addr := ""
haveIpv4 := false
if err == nil && len(ipv4.Answer) > 0 {
for _, ans := range ipv4.Answer {
if a, ok := ans.(*dns.A); ok {
haveIpv4 = true
ipv4Addr = a.A.String()
log.Printf("miekg.dns resolve ipv4 address: %s", ipv6Addr)
break
}
}
} else if err != nil {
log.Printf("miekg.dns get ipv6 err: %s", err)
}
if ipv6Priority && haveIpv6 {
return ipv6Addr, err
} else if haveIpv4 {
return ipv4Addr, err
} else if haveIpv6 {
return ipv6Addr, err
} else {
log.Printf("miekg.dns don't get result")
}
}
hints := windows.AddrinfoW{
Family: windows.AF_UNSPEC,
Socktype: windows.SOCK_DGRAM,
Protocol: windows.IPPROTO_IP,
}
var result *windows.AddrinfoW
name16, err := windows.UTF16PtrFromString(name)
if err != nil {
return
}
err = windows.GetAddrInfoW(name16, nil, &hints, &result)
if err != nil {
return
}
if result == nil {
err = windows.WSAHOST_NOT_FOUND
return
}
defer windows.FreeAddrInfoW(result)
var v6 netip.Addr
for ; result != nil; result = result.Next {
if result.Family != windows.AF_INET && result.Family != windows.AF_INET6 {
continue
}
addr := (*winipcfg.RawSockaddrInet)(unsafe.Pointer(result.Addr)).Addr()
if addr.Is4() {
return addr.String(), nil
} else if !v6.IsValid() && addr.Is6() {
v6 = addr
}
}
if v6.IsValid() {
return v6.String(), nil
}
err = windows.WSAHOST_NOT_FOUND
return
}