Skip to content

Commit edc94c3

Browse files
committed
optimize: run once ipv6 multicast per nic
1 parent 8a96ef5 commit edc94c3

File tree

1 file changed

+32
-31
lines changed

1 file changed

+32
-31
lines changed

disc/disc.go

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func WalkIP(cidr string) chan string {
8686
// PingLan tries to send a tiny UDP packet to all LAN hosts
8787
func (a *disc) PingLan() {
8888
var (
89-
isV4 bool
89+
isV6 bool
9090
b [16]byte
9191
)
9292

@@ -99,12 +99,8 @@ func (a *disc) PingLan() {
9999
// ip network(s) that assigned to interface(s)
100100
for _, addr := range addrs {
101101
if strings.IndexAny(addr.String(), "::") != -1 {
102-
isV4 = false
102+
isV6 = true
103103
} else {
104-
isV4 = true
105-
}
106-
107-
if isV4 {
108104
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
109105
if err != nil {
110106
println(err.Error())
@@ -125,36 +121,41 @@ func (a *disc) PingLan() {
125121
},
126122
}).Marshal(nil)
127123
if err := syscall.Sendto(fd, m, 0, &addr); err != nil {
128-
println(err.Error())
124+
if b[3] != 0 && b[3] != 255 {
125+
println(err.Error())
126+
}
129127
}
130128
}
131129
syscall.Close(fd)
132-
} else {
133-
fd, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_RAW, syscall.IPPROTO_ICMPV6)
134-
if err != nil {
135-
println(err.Error())
136-
return
137-
}
138-
syscall.SetsockoptInt(fd, syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, 1)
139-
copy(b[:], net.ParseIP(fmt.Sprintf("ff02::1")).To16())
140-
addr := syscall.SockaddrInet6{
141-
Port: 33434,
142-
ZoneId: uint32(i.Index),
143-
Addr: b,
144-
}
145-
m, _ := (&icmp.Message{
146-
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
147-
Body: &icmp.Echo{
148-
ID: 2016, Seq: 1,
149-
Data: make([]byte, 52-48),
150-
},
151-
}).Marshal(nil)
152-
if err := syscall.Sendto(fd, m, 0, &addr); err != nil {
153-
println(err.Error())
154-
}
155-
syscall.Close(fd)
156130
}
157131
}
132+
// sending a solicited-node multicast/icmp if there is IPv6 address
133+
if isV6 {
134+
fd, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_RAW, syscall.IPPROTO_ICMPV6)
135+
if err != nil {
136+
println(err.Error())
137+
return
138+
}
139+
syscall.SetsockoptInt(fd, syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, 1)
140+
copy(b[:], net.ParseIP(fmt.Sprintf("ff02::1")).To16())
141+
addr := syscall.SockaddrInet6{
142+
Port: 33434,
143+
ZoneId: uint32(i.Index),
144+
Addr: b,
145+
}
146+
m, _ := (&icmp.Message{
147+
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
148+
Body: &icmp.Echo{
149+
ID: 2016, Seq: 1,
150+
Data: make([]byte, 52-48),
151+
},
152+
}).Marshal(nil)
153+
if err := syscall.Sendto(fd, m, 0, &addr); err != nil {
154+
println(err.Error())
155+
}
156+
isV6 = false
157+
syscall.Close(fd)
158+
}
158159
}
159160
}
160161
func nextIP(ip net.IP) {

0 commit comments

Comments
 (0)