Use sync.Once for on-use initialization of interactsh

dev
Ice3man543 2021-09-10 00:32:05 +05:30
parent e10c4d68ff
commit c2c77de6f3
1 changed files with 34 additions and 21 deletions

View File

@ -6,6 +6,7 @@ import (
"net/url" "net/url"
"os" "os"
"strings" "strings"
"sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -35,8 +36,9 @@ type Client struct {
pollDuration time.Duration pollDuration time.Duration
cooldownDuration time.Duration cooldownDuration time.Duration
generated uint32 // decide to wait if we have a generated url firstTimeGroup sync.Once
matched bool generated uint32 // decide to wait if we have a generated url
matched bool
} }
var ( var (
@ -80,14 +82,6 @@ func New(options *Options) (*Client, error) {
return nil, errors.Wrap(err, "could not parse server url") return nil, errors.Wrap(err, "could not parse server url")
} }
interactsh, err := client.New(&client.Options{
ServerURL: options.ServerURL,
Token: options.Authorization,
PersistentSession: false,
})
if err != nil {
return nil, errors.Wrap(err, "could not create client")
}
configure := ccache.Configure() configure := ccache.Configure()
configure = configure.MaxSize(options.CacheSize) configure = configure.MaxSize(options.CacheSize)
cache := ccache.New(configure) cache := ccache.New(configure)
@ -97,7 +91,6 @@ func New(options *Options) (*Client, error) {
interactionsCache := ccache.New(interactionsCfg) interactionsCache := ccache.New(interactionsCfg)
interactClient := &Client{ interactClient := &Client{
interactsh: interactsh,
eviction: options.Eviction, eviction: options.Eviction,
interactions: interactionsCache, interactions: interactionsCache,
dotHostname: "." + parsed.Host, dotHostname: "." + parsed.Host,
@ -106,21 +99,34 @@ func New(options *Options) (*Client, error) {
pollDuration: options.PollDuration, pollDuration: options.PollDuration,
cooldownDuration: options.ColldownPeriod, cooldownDuration: options.ColldownPeriod,
} }
return interactClient, nil
}
interactClient.interactsh.StartPolling(interactClient.pollDuration, func(interaction *server.Interaction) { func (c *Client) firstTimeInitializeClient() error {
if options.Debug { interactsh, err := client.New(&client.Options{
ServerURL: c.options.ServerURL,
Token: c.options.Authorization,
PersistentSession: false,
})
if err != nil {
return errors.Wrap(err, "could not create client")
}
c.interactsh = interactsh
interactsh.StartPolling(c.pollDuration, func(interaction *server.Interaction) {
if c.options.Debug {
debugPrintInteraction(interaction) debugPrintInteraction(interaction)
} }
item := interactClient.requests.Get(interaction.UniqueID) item := c.requests.Get(interaction.UniqueID)
if item == nil { if item == nil {
// If we don't have any request for this ID, add it to temporary // If we don't have any request for this ID, add it to temporary
// lru cache so we can correlate when we get an add request. // lru cache so we can correlate when we get an add request.
gotItem := interactClient.interactions.Get(interaction.UniqueID) gotItem := c.interactions.Get(interaction.UniqueID)
if gotItem == nil { if gotItem == nil {
interactClient.interactions.Set(interaction.UniqueID, []*server.Interaction{interaction}, defaultInteractionDuration) c.interactions.Set(interaction.UniqueID, []*server.Interaction{interaction}, defaultInteractionDuration)
} else if items, ok := gotItem.Value().([]*server.Interaction); ok { } else if items, ok := gotItem.Value().([]*server.Interaction); ok {
items = append(items, interaction) items = append(items, interaction)
interactClient.interactions.Set(interaction.UniqueID, items, defaultInteractionDuration) c.interactions.Set(interaction.UniqueID, items, defaultInteractionDuration)
} }
return return
} }
@ -128,9 +134,9 @@ func New(options *Options) (*Client, error) {
if !ok { if !ok {
return return
} }
_ = interactClient.processInteractionForRequest(interaction, request) _ = c.processInteractionForRequest(interaction, request)
}) })
return interactClient, nil return nil
} }
// processInteractionForRequest processes an interaction for a request // processInteractionForRequest processes an interaction for a request
@ -170,6 +176,11 @@ func (c *Client) processInteractionForRequest(interaction *server.Interaction, d
// URL returns a new URL that can be interacted with // URL returns a new URL that can be interacted with
func (c *Client) URL() string { func (c *Client) URL() string {
c.firstTimeGroup.Do(func() {
if err := c.firstTimeInitializeClient(); err != nil {
gologger.Error().Msgf("Could not initialize interactsh client: %s", err)
}
})
atomic.CompareAndSwapUint32(&c.generated, 0, 1) atomic.CompareAndSwapUint32(&c.generated, 0, 1)
return c.interactsh.URL() return c.interactsh.URL()
} }
@ -179,8 +190,10 @@ func (c *Client) Close() bool {
if c.cooldownDuration > 0 && atomic.LoadUint32(&c.generated) == 1 { if c.cooldownDuration > 0 && atomic.LoadUint32(&c.generated) == 1 {
time.Sleep(c.cooldownDuration) time.Sleep(c.cooldownDuration)
} }
c.interactsh.StopPolling() if c.interactsh != nil {
c.interactsh.Close() c.interactsh.StopPolling()
c.interactsh.Close()
}
return c.matched return c.matched
} }