2021-10-27 16:50:36 +05:30
|
|
|
package core
|
2021-10-27 15:53:04 +05:30
|
|
|
|
|
|
|
|
import (
|
2024-05-01 00:28:11 +05:30
|
|
|
"context"
|
|
|
|
|
|
|
|
|
|
"github.com/projectdiscovery/gologger"
|
2023-10-17 17:44:13 +05:30
|
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
|
2024-04-03 17:50:57 +02:00
|
|
|
syncutil "github.com/projectdiscovery/utils/sync"
|
2021-10-27 15:53:04 +05:30
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// WorkPool implements an execution pool for executing different
|
2021-11-25 18:54:16 +02:00
|
|
|
// types of task with different concurrency requirements.
|
2021-10-27 15:53:04 +05:30
|
|
|
//
|
|
|
|
|
// It also allows Configuration of such requirements. This is used
|
|
|
|
|
// for per-module like separate headless concurrency etc.
|
|
|
|
|
type WorkPool struct {
|
2024-04-03 17:50:57 +02:00
|
|
|
Headless *syncutil.AdaptiveWaitGroup
|
|
|
|
|
Default *syncutil.AdaptiveWaitGroup
|
2021-10-28 17:20:07 +05:30
|
|
|
config WorkPoolConfig
|
2021-10-27 15:53:04 +05:30
|
|
|
}
|
|
|
|
|
|
2021-11-25 18:54:16 +02:00
|
|
|
// WorkPoolConfig is the configuration for work pool
|
2021-10-27 15:53:04 +05:30
|
|
|
type WorkPoolConfig struct {
|
|
|
|
|
// InputConcurrency is the concurrency for inputs values.
|
|
|
|
|
InputConcurrency int
|
|
|
|
|
// TypeConcurrency is the concurrency for the request type templates.
|
|
|
|
|
TypeConcurrency int
|
|
|
|
|
// HeadlessInputConcurrency is the concurrency for headless inputs values.
|
|
|
|
|
HeadlessInputConcurrency int
|
|
|
|
|
// TypeConcurrency is the concurrency for the headless request type templates.
|
|
|
|
|
HeadlessTypeConcurrency int
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 16:50:36 +05:30
|
|
|
// NewWorkPool returns a new WorkPool instance
|
|
|
|
|
func NewWorkPool(config WorkPoolConfig) *WorkPool {
|
2024-04-03 17:50:57 +02:00
|
|
|
headlessWg, _ := syncutil.New(syncutil.WithSize(config.HeadlessTypeConcurrency))
|
|
|
|
|
defaultWg, _ := syncutil.New(syncutil.WithSize(config.TypeConcurrency))
|
2021-10-28 17:20:07 +05:30
|
|
|
|
|
|
|
|
return &WorkPool{
|
|
|
|
|
config: config,
|
2024-04-03 17:50:57 +02:00
|
|
|
Headless: headlessWg,
|
|
|
|
|
Default: defaultWg,
|
2021-10-28 17:20:07 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-25 18:54:16 +02:00
|
|
|
// Wait waits for all the work pool wait groups to finish
|
2021-10-28 17:20:07 +05:30
|
|
|
func (w *WorkPool) Wait() {
|
|
|
|
|
w.Default.Wait()
|
|
|
|
|
w.Headless.Wait()
|
2021-10-27 15:53:04 +05:30
|
|
|
}
|
|
|
|
|
|
2021-11-25 18:54:16 +02:00
|
|
|
// InputPool returns a work pool for an input type
|
2024-04-03 17:50:57 +02:00
|
|
|
func (w *WorkPool) InputPool(templateType types.ProtocolType) *syncutil.AdaptiveWaitGroup {
|
2021-10-28 17:20:07 +05:30
|
|
|
var count int
|
2021-11-03 18:58:00 +05:30
|
|
|
if templateType == types.HeadlessProtocol {
|
2021-10-28 17:20:07 +05:30
|
|
|
count = w.config.HeadlessInputConcurrency
|
|
|
|
|
} else {
|
|
|
|
|
count = w.config.InputConcurrency
|
|
|
|
|
}
|
2024-04-03 17:50:57 +02:00
|
|
|
swg, _ := syncutil.New(syncutil.WithSize(count))
|
|
|
|
|
return swg
|
2021-10-27 15:53:04 +05:30
|
|
|
}
|
2024-04-03 18:50:46 +02:00
|
|
|
|
|
|
|
|
func (w *WorkPool) RefreshWithConfig(config WorkPoolConfig) {
|
|
|
|
|
if w.config.TypeConcurrency != config.TypeConcurrency {
|
|
|
|
|
w.config.TypeConcurrency = config.TypeConcurrency
|
|
|
|
|
}
|
|
|
|
|
if w.config.HeadlessTypeConcurrency != config.HeadlessTypeConcurrency {
|
|
|
|
|
w.config.HeadlessTypeConcurrency = config.HeadlessTypeConcurrency
|
|
|
|
|
}
|
|
|
|
|
if w.config.InputConcurrency != config.InputConcurrency {
|
|
|
|
|
w.config.InputConcurrency = config.InputConcurrency
|
|
|
|
|
}
|
|
|
|
|
if w.config.HeadlessInputConcurrency != config.HeadlessInputConcurrency {
|
|
|
|
|
w.config.HeadlessInputConcurrency = config.HeadlessInputConcurrency
|
|
|
|
|
}
|
2024-05-01 00:28:11 +05:30
|
|
|
w.Refresh(context.Background())
|
2024-04-03 18:50:46 +02:00
|
|
|
}
|
|
|
|
|
|
2024-05-01 00:28:11 +05:30
|
|
|
func (w *WorkPool) Refresh(ctx context.Context) {
|
2024-04-03 18:50:46 +02:00
|
|
|
if w.Default.Size != w.config.TypeConcurrency {
|
2024-05-01 00:28:11 +05:30
|
|
|
if err := w.Default.Resize(ctx, w.config.TypeConcurrency); err != nil {
|
|
|
|
|
gologger.Warning().Msgf("Could not resize workpool: %s\n", err)
|
|
|
|
|
}
|
2024-04-03 18:50:46 +02:00
|
|
|
}
|
|
|
|
|
if w.Headless.Size != w.config.HeadlessTypeConcurrency {
|
2024-05-01 00:28:11 +05:30
|
|
|
if err := w.Headless.Resize(ctx, w.config.HeadlessTypeConcurrency); err != nil {
|
|
|
|
|
gologger.Warning().Msgf("Could not resize workpool: %s\n", err)
|
|
|
|
|
}
|
2024-04-03 18:50:46 +02:00
|
|
|
}
|
|
|
|
|
}
|