13 type ScanRecord
struct {
18 type ScanRecords
struct {
19 recordMutex sync
.RWMutex
24 func (srs
*ScanRecords
) AddRecord(rec
*ScanRecord
) {
25 srs
.recordMutex
.Lock()
26 srs
.records
= append(srs
.records
, rec
)
27 srs
.recordMutex
.Unlock()
28 log
.Printf("Found a record: IP=%s, RTT=%s\n", rec
.IP
, rec
.RTT
.String())
31 func (srs
*ScanRecords
) IncScanCounter() {
32 scanCount
:= atomic
.AddInt32(&srs
.scanCounter
, 1)
33 if scanCount%1000
== 0 {
34 log
.Printf("Scanned %d IPs, Found %d records\n", scanCount
, srs
.RecordSize())
38 func (srs
*ScanRecords
) RecordSize() int {
39 srs
.recordMutex
.RLock()
40 defer srs
.recordMutex
.RUnlock()
41 return len(srs
.records
)
44 func (srs
*ScanRecords
) ScanCount() int32 {
45 return atomic
.LoadInt32(&srs
.scanCounter
)
48 var testIPFunc
func(ip
string, config
*ScanConfig
, record
*ScanRecord
) bool
50 func testip(ip
string, config
*ScanConfig
) *ScanRecord
{
51 record
:= new(ScanRecord
)
52 for i
:= 0; i
< config
.ScanCountPerIP
; i
++ {
53 if !testIPFunc(ip
, config
, record
) {
58 record
.RTT
= record
.RTT
/ time
.Duration(config
.ScanCountPerIP
)
62 func testip_worker(ctx context
.Context
, ch
chan string, gcfg
*GScanConfig
, cfg
*ScanConfig
, srs
*ScanRecords
, wg
*sync
.WaitGroup
) {
65 timer
:= time
.NewTimer(cfg
.ScanMaxRTT
+ 100*time
.Millisecond
)
68 ctx
, cancal
:= context
.WithCancel(ctx
)
76 if err
:= Ping(ip
, gcfg
.ScanMaxPingRTT
); err
!= nil {
79 if time
.Since(start
) < gcfg
.ScanMinPingRTT
{
84 done
:= make(chan struct{}, 1)
88 if srs
.RecordSize() >= cfg
.RecordLimit
{
97 timer
.Reset(cfg
.ScanMaxRTT
+ 100*time
.Millisecond
)
102 log
.Println(ip
, "timeout")
108 func StartScan(srs
*ScanRecords
, gcfg
*GScanConfig
, cfg
*ScanConfig
, ipqueue
chan string) {
109 var wg sync
.WaitGroup
110 wg
.Add(gcfg
.ScanWorker
)
112 interrupt
:= make(chan os
.Signal
, 1)
113 signal
.Notify(interrupt
, os
.Interrupt
)
115 ctx
, cancel
:= context
.WithCancel(context
.Background())
123 ch
:= make(chan string, 100)
124 for i
:= 0; i
< gcfg
.ScanWorker
; i
++ {
125 go testip_worker(ctx
, ch
, gcfg
, cfg
, srs
, &wg
)
128 for ip
:= range ipqueue
{
134 if srs
.RecordSize() >= cfg
.RecordLimit
{