forked from projectdiscovery/nuclei
-
Notifications
You must be signed in to change notification settings - Fork 1
/
resume.go
119 lines (104 loc) · 2.79 KB
/
resume.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package types
import (
"fmt"
"math"
"path/filepath"
"sync"
"github.com/projectdiscovery/nuclei/v2/pkg/catalog/config"
"github.com/rs/xid"
)
// Default resume file
const DefaultResumeFileName = "resume-%s.cfg"
func DefaultResumeFilePath() string {
configDir, err := config.GetConfigDir()
if err != nil {
return fmt.Sprintf(DefaultResumeFileName, xid.New().String())
}
resumeFile := filepath.Join(configDir, fmt.Sprintf(DefaultResumeFileName, xid.New().String()))
return resumeFile
}
// ResumeCfg contains the scan progression
type ResumeCfg struct {
sync.RWMutex
ResumeFrom map[string]*ResumeInfo `json:"resumeFrom"`
Current map[string]*ResumeInfo `json:"-"`
}
type ResumeInfo struct {
sync.RWMutex
Completed bool `json:"completed"`
InFlight map[uint32]struct{} `json:"inFlight"`
SkipUnder uint32 `json:"-"`
Repeat map[uint32]struct{} `json:"-"`
DoAbove uint32 `json:"-"`
}
// Clone the ResumeInfo structure
func (resumeInfo *ResumeInfo) Clone() *ResumeInfo {
resumeInfo.Lock()
defer resumeInfo.Unlock()
inFlight := make(map[uint32]struct{})
for u := range resumeInfo.InFlight {
inFlight[u] = struct{}{}
}
repeat := make(map[uint32]struct{})
for u := range resumeInfo.Repeat {
repeat[u] = struct{}{}
}
return &ResumeInfo{
Completed: resumeInfo.Completed,
InFlight: inFlight,
SkipUnder: resumeInfo.SkipUnder,
Repeat: repeat,
DoAbove: resumeInfo.DoAbove,
}
}
// NewResumeCfg creates a new scan progression structure
func NewResumeCfg() *ResumeCfg {
return &ResumeCfg{
ResumeFrom: make(map[string]*ResumeInfo),
Current: make(map[string]*ResumeInfo),
}
}
// Clone the resume structure
func (resumeCfg *ResumeCfg) Clone() *ResumeCfg {
resumeCfg.Lock()
defer resumeCfg.Unlock()
resumeFrom := make(map[string]*ResumeInfo)
for id, resumeInfo := range resumeCfg.ResumeFrom {
resumeFrom[id] = resumeInfo.Clone()
}
current := make(map[string]*ResumeInfo)
for id, resumeInfo := range resumeCfg.Current {
current[id] = resumeInfo.Clone()
}
return &ResumeCfg{
ResumeFrom: resumeFrom,
Current: current,
}
}
// Clone the resume structure
func (resumeCfg *ResumeCfg) Compile() {
resumeCfg.Lock()
defer resumeCfg.Unlock()
for _, resumeInfo := range resumeCfg.ResumeFrom {
if resumeInfo.Completed && len(resumeInfo.InFlight) > 0 {
resumeInfo.InFlight = make(map[uint32]struct{})
}
min := uint32(math.MaxUint32)
max := uint32(0)
for index := range resumeInfo.InFlight {
if index < min {
min = index
}
if index > max {
max = index
}
}
// maybe redundant but ensures we track the indexes to be repeated
resumeInfo.Repeat = map[uint32]struct{}{}
for index := range resumeInfo.InFlight {
resumeInfo.Repeat[index] = struct{}{}
}
resumeInfo.SkipUnder = min
resumeInfo.DoAbove = max
}
}