Skip to content

Commit 3cb16c6

Browse files
committed
fix data race & add look-free append
1 parent fd94901 commit 3cb16c6

1 file changed

Lines changed: 26 additions & 18 deletions

File tree

lmap.go

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
package main
22

33
import (
4-
"os"
5-
"flag"
6-
"sort"
74
"bytes"
85
"encoding/binary"
6+
"flag"
97
"fmt"
108
"log"
119
"net"
10+
"os"
11+
"sort"
1212
"sync"
13+
"sync/atomic"
1314
"time"
1415
)
1516

16-
var icmp ICMP
17-
1817
type ICMP struct {
1918
Type uint8
2019
Code uint8
@@ -36,35 +35,47 @@ func main() {
3635
}
3736

3837
func CheckIP(subnet string, isVerbose bool) {
39-
var usedIP []string
40-
var unusedIP []string
4138
checkerGroup := &sync.WaitGroup{}
4239
t := time.Now()
4340
hosts, _ := getAllHostsFromCIDR(subnet)
41+
usedIP := make([]string, len(hosts))
42+
unusedIP := make([]string, len(hosts))
43+
var (
44+
usedIndex int64 = 0
45+
unusedIndex int64 = 0
46+
)
4447
for _, ip := range hosts {
4548
time.Sleep(500)
4649
checkerGroup.Add(1)
4750
go func(data string) {
4851
defer checkerGroup.Done()
4952
isUsed := ping(data)
5053
if isUsed {
51-
usedIP = append(usedIP, data)
54+
old := atomic.LoadInt64(&usedIndex)
55+
for !atomic.CompareAndSwapInt64(&usedIndex, old, old+1) {
56+
old = atomic.LoadInt64(&usedIndex)
57+
}
58+
usedIP[old] = data
5259
if isVerbose {
53-
fmt.Println("已使用IP:", usedIP)
60+
fmt.Println("已使用IP:", usedIP[:usedIndex])
5461
}
5562
} else {
56-
unusedIP = append(unusedIP, data)
63+
old := atomic.LoadInt64(&unusedIndex)
64+
for !atomic.CompareAndSwapInt64(&unusedIndex, old, old+1) {
65+
old = atomic.LoadInt64(&unusedIndex)
66+
}
67+
unusedIP[old] = data
5768
if isVerbose {
58-
fmt.Println("未使用IP:", unusedIP)
69+
fmt.Println("未使用IP:", unusedIP[:unusedIndex])
5970
}
6071
}
6172
}(ip)
6273
}
6374
checkerGroup.Wait()
6475
elapsed := time.Since(t)
6576
fmt.Println("IP扫描完成,耗时", elapsed)
66-
fmt.Println("已使用IP:", sortIPList(usedIP))
67-
fmt.Println("未使用IP:", sortIPList(unusedIP))
77+
fmt.Println("已使用IP:", sortIPList(usedIP[:usedIndex]))
78+
fmt.Println("未使用IP:", sortIPList(unusedIP[:unusedIndex]))
6879
}
6980

7081
func sortIPList(ipStrings []string) (result []string) {
@@ -104,12 +115,9 @@ func inc(ip net.IP) {
104115
}
105116

106117
func ping(ip string) bool {
118+
var icmp ICMP
107119
//开始填充数据包
108120
icmp.Type = 8 //8->echo message 0->reply message
109-
icmp.Code = 0
110-
icmp.Checksum = 0
111-
icmp.Identifier = 0
112-
icmp.SequenceNum = 0
113121

114122
recvBuf := make([]byte, 32)
115123
var buffer bytes.Buffer
@@ -121,7 +129,7 @@ func ping(ip string) bool {
121129
buffer.Reset()
122130
binary.Write(&buffer, binary.BigEndian, icmp)
123131

124-
conn, err := net.DialTimeout("ip4:icmp", ip, 1 * time.Second)
132+
conn, err := net.DialTimeout("ip4:icmp", ip, 1*time.Second)
125133
if err != nil {
126134
return false
127135
}

0 commit comments

Comments
 (0)