This repository has been archived by the owner on Sep 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcheck.go
129 lines (113 loc) · 2.19 KB
/
check.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
120
121
122
123
124
125
126
127
128
129
package tgstatus
import (
"context"
"sync"
"time"
"github.com/go-faster/errors"
"go.uber.org/zap"
"github.com/gotd/td/telegram"
"github.com/gotd/td/telegram/dcs"
"github.com/gotd/td/tg"
)
type Check struct {
mux sync.Mutex
appID int
appHash string
rate time.Duration
id int
ip string
option tg.DCOption
port int
log *zap.Logger
seen time.Time
}
type Report struct {
ID int
IP string
Seen time.Time
}
func (c *Check) Report() Report {
c.mux.Lock()
defer c.mux.Unlock()
return Report{
ID: c.id,
IP: c.ip,
Seen: c.seen,
}
}
func (c *Check) updateAddrFromConfig(cfg *tg.Config) {
for _, dc := range cfg.DCOptions {
if dc.Ipv6 || dc.TCPObfuscatedOnly || dc.Static || dc.MediaOnly {
continue
}
if dc.ID != c.id {
continue
}
c.mux.Lock()
if c.ip != dc.IPAddress {
c.log.Debug("Updating addr",
zap.String("addr_old", c.ip),
zap.String("addr_new", dc.IPAddress),
)
c.ip = dc.IPAddress
c.option = dc
c.port = dc.Port
}
c.mux.Unlock()
break
}
}
func (c *Check) checkConnection(ctx context.Context, invoker tg.Invoker) error {
ctx, cancel := context.WithTimeout(ctx, time.Second*5)
defer cancel()
cfg, err := tg.NewClient(invoker).HelpGetConfig(ctx)
if err != nil {
return errors.Wrap(err, "getConfig")
}
// IP can change over time.
c.updateAddrFromConfig(cfg)
// Success.
c.mux.Lock()
c.seen = time.Now()
c.mux.Unlock()
return nil
}
func (c *Check) Run(ctx context.Context) error {
ticker := time.NewTicker(c.rate)
c.mux.Lock()
client := telegram.NewClient(c.appID, c.appHash, telegram.Options{
Logger: c.log,
DC: c.id,
DCList: dcs.List{
Options: []tg.DCOption{
c.option,
},
},
})
c.mux.Unlock()
return client.Run(ctx, func(ctx context.Context) error {
for {
select {
case <-ticker.C:
if err := c.checkConnection(ctx, client); err != nil {
return errors.Wrap(err, "check")
}
case <-ctx.Done():
return ctx.Err()
}
}
})
}
func (c *Check) Loop(ctx context.Context) error {
for {
if err := c.Run(ctx); err != nil {
c.log.Error("Run", zap.Error(err))
}
select {
case <-ctx.Done():
return ctx.Err()
default:
continue
}
}
}