Skip to content

Commit

Permalink
fix: don't ignore bind6 error when iface has ipv6 address
Browse files Browse the repository at this point in the history
  • Loading branch information
wwqgtxx committed Apr 10, 2024
1 parent cff7df1 commit 9a57265
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
12 changes: 6 additions & 6 deletions component/dialer/bind_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func bind6(handle syscall.Handle, ifaceIdx int) error {
return err
}

func bindControl(ifaceIdx int) controlFn {
func bindControl(iface *iface.Interface) controlFn {
return func(ctx context.Context, network, address string, c syscall.RawConn) (err error) {
addrPort, err := netip.ParseAddrPort(address)
if err == nil && !addrPort.Addr().IsGlobalUnicast() {
Expand All @@ -46,16 +46,16 @@ func bindControl(ifaceIdx int) controlFn {
var innerErr error
err = c.Control(func(fd uintptr) {
handle := syscall.Handle(fd)
bind6err := bind6(handle, ifaceIdx)
bind4err := bind4(handle, ifaceIdx)
bind6err := bind6(handle, iface.Index)
bind4err := bind4(handle, iface.Index)
switch network {
case "ip6", "tcp6":
innerErr = bind6err
case "ip4", "tcp4", "udp4":
innerErr = bind4err
case "udp6":
// golang will set network to udp6 when listenUDP on wildcard ip (eg: ":0", "")
if (!addrPort.Addr().IsValid() || addrPort.Addr().IsUnspecified()) && bind6err != nil {
if (!addrPort.Addr().IsValid() || addrPort.Addr().IsUnspecified()) && bind6err != nil && !iface.HasV6 {
// try bind ipv6, if failed, ignore. it's a workaround for windows disable interface ipv6
if bind4err != nil {
innerErr = fmt.Errorf("%w (%s)", bind6err, bind4err)
Expand All @@ -82,7 +82,7 @@ func bindIfaceToDialer(ifaceName string, dialer *net.Dialer, _ string, _ netip.A
return err
}

addControlToDialer(dialer, bindControl(ifaceObj.Index))
addControlToDialer(dialer, bindControl(ifaceObj))
return nil
}

Expand All @@ -92,7 +92,7 @@ func bindIfaceToListenConfig(ifaceName string, lc *net.ListenConfig, _, address
return "", err
}

addControlToListenConfig(lc, bindControl(ifaceObj.Index))
addControlToListenConfig(lc, bindControl(ifaceObj))
return address, nil
}

Expand Down
12 changes: 12 additions & 0 deletions component/iface/iface.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type Interface struct {
Name string
Addrs []netip.Prefix
HardwareAddr net.HardwareAddr
HasV4 bool
HasV6 bool
}

var (
Expand All @@ -38,6 +40,8 @@ func ResolveInterface(name string) (*Interface, error) {
continue
}

hasV4 := false
hasV6 := false
ipNets := make([]netip.Prefix, 0, len(addrs))
for _, addr := range addrs {
var pf netip.Prefix
Expand All @@ -55,6 +59,12 @@ func ResolveInterface(name string) (*Interface, error) {
pf = netip.PrefixFrom(ip, ip.BitLen())
}
if pf.IsValid() {
if pf.Addr().Is4() {
hasV4 = true
}
if pf.Addr().Is6() {
hasV6 = true
}
ipNets = append(ipNets, pf)
}
}
Expand All @@ -64,6 +74,8 @@ func ResolveInterface(name string) (*Interface, error) {
Name: iface.Name,
Addrs: ipNets,
HardwareAddr: iface.HardwareAddr,
HasV4: hasV4,
HasV6: hasV6,
}
}

Expand Down

0 comments on commit 9a57265

Please sign in to comment.