修改Wireguard-windows客户端支持优先解析ipv6地址方案

目录

资源及使用方案

资源地址

使用方式

源码修改思路

源码地址

修改后代码

endpoint解析代码


资源及使用方案

资源地址

链接: 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地址。。

源码修改思路

源码地址

GitHub - WireGuard/wireguard-windows: Download WireGuard for Windows at https://www.wireguard.com/install . This repo is a mirror only. Official repository is at https://git.zx2c4.com/wireguard-windows

修改后代码

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
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值