diff --git a/README.md b/README.md index 32da7a2..cc43b20 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ eu3.sec-tunnel.com,77.111.244.22,443 | list-proxies | - | output proxy list and exit | | proxy | String | sets base proxy to use for all dial-outs. Format: `://[login:password@]host[:port]` Examples: `http://user:password@192.168.1.1:3128`, `socks5://10.0.0.1:1080` | | refresh | Duration | login refresh interval (default 4h0m0s) | +| refresh-retry | Duration | login refresh retry interval (default 5s) | | timeout | Duration | timeout for network operations (default 10s) | | verbosity | Number | logging verbosity (10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical) (default 20) | | version | - | show program version and exit | diff --git a/main.go b/main.go index 020b775..a78c185 100644 --- a/main.go +++ b/main.go @@ -55,6 +55,7 @@ type CLIArgs struct { apiAddress string bootstrapDNS string refresh time.Duration + refreshRetry time.Duration } func parse_args() CLIArgs { @@ -78,6 +79,7 @@ func parse_args() CLIArgs { "See https://github.com/ameshkov/dnslookup/ for upstream DNS URL format. "+ "Examples: https://1.1.1.1/dns-query, quic://dns.adguard.com") flag.DurationVar(&args.refresh, "refresh", 4*time.Hour, "login refresh interval") + flag.DurationVar(&args.refreshRetry, "refresh-retry", 5*time.Second, "login refresh retry interval") flag.Parse() if args.country == "" { arg_fail("Country can't be empty string.") @@ -229,14 +231,14 @@ func run() int { return 13 } - runTicker(context.Background(), args.refresh, func(ctx context.Context) { + runTicker(context.Background(), args.refresh, args.refreshRetry, func(ctx context.Context) error { mainLogger.Info("Refreshing login...") reqCtx, cl := context.WithTimeout(ctx, args.timeout) defer cl() err := seclient.Login(reqCtx) if err != nil { mainLogger.Error("Login refresh failed: %v", err) - return + return err } mainLogger.Info("Login refreshed.") @@ -246,9 +248,10 @@ func run() int { err = seclient.DeviceGeneratePassword(reqCtx) if err != nil { mainLogger.Error("Device password refresh failed: %v", err) - return + return err } mainLogger.Info("Device password refreshed.") + return nil }) endpoint := ips[0] diff --git a/utils.go b/utils.go index 566e0a4..4686055 100644 --- a/utils.go +++ b/utils.go @@ -171,14 +171,19 @@ func AfterWallClock(d time.Duration) <-chan time.Time { return ch } -func runTicker(ctx context.Context, interval time.Duration, cb func(context.Context)) { +func runTicker(ctx context.Context, interval, retryInterval time.Duration, cb func(context.Context) error) { go func() { + var err error for { + nextInterval := interval + if err != nil { + nextInterval = retryInterval + } select { case <-ctx.Done(): return - case <-AfterWallClock(interval): - cb(ctx) + case <-AfterWallClock(nextInterval): + err = cb(ctx) } } }()