@@ -19,6 +19,7 @@ import (
19
19
"context"
20
20
"fmt"
21
21
"net"
22
+ "sort"
22
23
"strconv"
23
24
"sync"
24
25
"time"
@@ -51,6 +52,8 @@ type ConnectionManager struct {
51
52
// ipTargets stores a map of DNS targets to their corresponding IP addresses.
52
53
ipTargets map [string ][]string
53
54
55
+ ticker * time.Ticker
56
+
54
57
// mu is a mutex used to synchronize access to targets map in ConnectionManager.
55
58
mu sync.Mutex
56
59
}
@@ -81,6 +84,47 @@ func logError(message string, err error) {
81
84
}
82
85
}
83
86
87
+ // StartMonitoring begins monitoring IP updates at regular intervals using a ticker and a goroutine.
88
+ func (m * ConnectionManager ) StartMonitoring (ctx context.Context ) {
89
+ m .ticker = time .NewTicker (time .Minute )
90
+
91
+ go func () {
92
+ for {
93
+ select {
94
+ case <- m .ticker .C :
95
+ m .checkForIPUpdates (ctx )
96
+ case <- ctx .Done ():
97
+ m .ticker .Stop ()
98
+
99
+ return
100
+ }
101
+ }
102
+ }()
103
+ }
104
+
105
+ // equalIPs compares two slices of IP address strings and returns true if they are equal, otherwise returns false.
106
+ func equalIPs (ipListA , ipListB []string ) bool {
107
+ if len (ipListA ) != len (ipListB ) {
108
+ return false
109
+ }
110
+
111
+ sort .Strings (ipListA )
112
+ sort .Strings (ipListB )
113
+
114
+ for i , v := range ipListA {
115
+ if ipListB [i ] != v {
116
+ return false
117
+ }
118
+ }
119
+
120
+ return true
121
+ }
122
+
123
+ // createDeadlineContext sets a deadline for the provided context based on the server DNS timeout configuration.
124
+ func createDeadlineContext (ctx context.Context ) (context.Context , context.CancelFunc ) {
125
+ return context .WithDeadline (ctx , time .Now ().Add (config .LoadableConfig .Server .DNS .Timeout * time .Second ))
126
+ }
127
+
84
128
// NewConnectionManager returns a new instance of ConnectionManager with an initialized targets map.
85
129
func NewConnectionManager () * ConnectionManager {
86
130
return & ConnectionManager {
@@ -94,6 +138,38 @@ func GetConnectionManager() *ConnectionManager {
94
138
return manager
95
139
}
96
140
141
+ // checkForIPUpdates updates the IP addresses for each target in the ConnectionManager.
142
+ func (m * ConnectionManager ) checkForIPUpdates (ctx context.Context ) {
143
+ m .mu .Lock ()
144
+
145
+ defer m .mu .Unlock ()
146
+
147
+ for target := range m .targets {
148
+ host , _ , err := net .SplitHostPort (target )
149
+ if err != nil {
150
+ continue
151
+ }
152
+
153
+ ctxTimeout , cancel := createDeadlineContext (ctx )
154
+ resolver := util .NewDNSResolver ()
155
+
156
+ ips , err := resolver .LookupHost (ctxTimeout , host )
157
+ if err != nil {
158
+ cancel ()
159
+
160
+ continue
161
+ }
162
+
163
+ if ! equalIPs (m .ipTargets [target ], ips ) {
164
+ m .ipTargets [target ] = ips
165
+
166
+ level .Debug (log .Logger ).Log (global .LogKeyMsg , fmt .Sprintf ("Updated IPs for target '%s': %v\n " , target , ips ))
167
+ }
168
+
169
+ cancel ()
170
+ }
171
+ }
172
+
97
173
// Register adds a new target with the specified description and direction to the ConnectionManager if it does not already exist.
98
174
func (m * ConnectionManager ) Register (ctx context.Context , target , direction string , description string ) {
99
175
m .mu .Lock ()
@@ -113,7 +189,7 @@ func (m *ConnectionManager) Register(ctx context.Context, target, direction stri
113
189
return
114
190
}
115
191
116
- ctxTimeut , cancel := context . WithDeadline (ctx , time . Now (). Add ( config . LoadableConfig . Server . DNS . Timeout * time . Second ) )
192
+ ctxTimeut , cancel := createDeadlineContext (ctx )
117
193
118
194
defer cancel ()
119
195
0 commit comments