Skip to content

Commit bb2aaec

Browse files
author
Christian Roessner
committed
Feat: Add IP monitoring functionality to ConnectionManager
Introduced a ticker-based IP monitoring system to the ConnectionManager to check for IP updates at regular intervals. This includes adding `StartMonitoring` and auxiliary functions such as `equalIPs`, and `checkForIPUpdates`, as well as integrating the new monitoring process into the server's lifecycle. Signed-off-by: Christian Roessner <[email protected]>
1 parent e529c27 commit bb2aaec

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

server/lualib/connmgr/netstats.go

+77-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"context"
2020
"fmt"
2121
"net"
22+
"sort"
2223
"strconv"
2324
"sync"
2425
"time"
@@ -51,6 +52,8 @@ type ConnectionManager struct {
5152
// ipTargets stores a map of DNS targets to their corresponding IP addresses.
5253
ipTargets map[string][]string
5354

55+
ticker *time.Ticker
56+
5457
// mu is a mutex used to synchronize access to targets map in ConnectionManager.
5558
mu sync.Mutex
5659
}
@@ -81,6 +84,47 @@ func logError(message string, err error) {
8184
}
8285
}
8386

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+
84128
// NewConnectionManager returns a new instance of ConnectionManager with an initialized targets map.
85129
func NewConnectionManager() *ConnectionManager {
86130
return &ConnectionManager{
@@ -94,6 +138,38 @@ func GetConnectionManager() *ConnectionManager {
94138
return manager
95139
}
96140

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+
97173
// Register adds a new target with the specified description and direction to the ConnectionManager if it does not already exist.
98174
func (m *ConnectionManager) Register(ctx context.Context, target, direction string, description string) {
99175
m.mu.Lock()
@@ -113,7 +189,7 @@ func (m *ConnectionManager) Register(ctx context.Context, target, direction stri
113189
return
114190
}
115191

116-
ctxTimeut, cancel := context.WithDeadline(ctx, time.Now().Add(config.LoadableConfig.Server.DNS.Timeout*time.Second))
192+
ctxTimeut, cancel := createDeadlineContext(ctx)
117193

118194
defer cancel()
119195

server/main.go

+2
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,8 @@ func runConnectionManager(ctx context.Context) {
10941094

10951095
go manager.StartTicker(5 * time.Second)
10961096
go stats.UpdateGenericConnections()
1097+
1098+
manager.StartMonitoring(ctx)
10971099
}
10981100

10991101
// main initializes the application and manages the lifecycle of various components.

0 commit comments

Comments
 (0)