Skip to content

[Feature Request] keepAliveLoop 失败后,自动重新尝试认证 #38

@WangYihang

Description

@WangYihang

背景

keepOnline 选项开启时,本工具会在 keepAliveLoop 中定期发送 HTTP 请求至 https://www.tsinghua.edu.cn/ / https://www.baidu.com/,在正常情况可以持续保持在线状态。

GoAuthing/cli/main.go

Lines 207 to 267 in e42c2fd

func keepAliveLoop(c *cli.Context, campusOnly bool) (ret error) {
logger.Infof("Accessing websites periodically to keep you online")
accessTarget := func(url string, ipv6 bool) (ret error) {
network := "tcp4"
if ipv6 {
network = "tcp6"
}
netClient := &http.Client{
Timeout: time.Second * 10,
Transport: &http.Transport{
DialContext: func(ctx context.Context, _network, addr string) (net.Conn, error) {
logger.Debugf("DialContext %s (%s)\n", addr, network)
myDial := &net.Dialer{
Timeout: 6 * time.Second,
KeepAlive: 0,
FallbackDelay: -1, // disable RFC 6555 Fast Fallback
}
return myDial.DialContext(ctx, network, addr)
},
},
}
resp, ret := netClient.Head(url)
if ret != nil {
return
}
defer resp.Body.Close()
logger.Debugf("HTTP status code %d\n", resp.StatusCode)
return
}
targetInside := "https://www.tsinghua.edu.cn/"
targetOutside := "https://www.baidu.com/"
stop := make(chan int, 1)
defer func() { stop <- 1 }()
go func() {
// Keep IPv6 online, ignore any errors
for {
select {
case <-stop:
break
case <-time.After(13 * time.Minute):
_ = accessTarget(targetInside, true)
}
}
}()
for {
target := targetOutside
if campusOnly || settings.V6 {
target = targetInside
}
if ret = accessTarget(target, settings.V6); ret != nil {
ret = fmt.Errorf("accessing %s failed (re-login might be required): %w", target, ret)
break
}
// Consumes ~5MB per day
time.Sleep(3 * time.Second)
}
return
}

然而,在某些特殊情况下(如:校园网因某种特殊原因被暂停使用,然后被恢复使用,且在外地出差无法手动重新认证),目前的实现似乎未能实现自动重新认证

潜在解决方案

选项一:添加新的命令行参数(如:--auto-reauth

该参数与 --keepOnline 同时使用,当用户添加该参数时,可支持断线重连功能,即:当 keepAliveLoop 遇到错误后,重新进行认证操作。另外,可以添加指数退避策略防止过多的认证请求。

选项二:直接为 keepAliveLoop 添加断线重连功能

同上,当原始的 keepAliveLoop 失败时,说明校园网已掉线(可能是欠费或其他特殊原因),则重新认证。选项二的副作用是:改变了 keepAliveLoop 函数的语义(由 仅保持在线状态 变为 保持在线状态且断线重连

其他

如果作者觉得合适的话,我可以协助实现该功能。

相关讨论

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions