@@ -6,11 +6,13 @@ import (
6
6
"crypto/x509"
7
7
"fmt"
8
8
"net"
9
+ "os"
9
10
"strings"
10
11
"sync"
11
12
"time"
12
13
13
14
"github.com/Infisical/infisical-merge/packages/api"
15
+ "github.com/Infisical/infisical-merge/packages/systemd"
14
16
"github.com/go-resty/resty/v2"
15
17
"github.com/pion/logging"
16
18
"github.com/pion/turn/v4"
@@ -75,14 +77,18 @@ func (g *Gateway) ConnectWithRelay() error {
75
77
76
78
// Start a new TURN Client and wrap our net.Conn in a STUNConn
77
79
// This allows us to simulate datagram based communication over a net.Conn
80
+ logger := logging .NewDefaultLoggerFactory ()
81
+ if os .Getenv ("LOG_LEVEL" ) == "debug" {
82
+ logger .DefaultLogLevel = logging .LogLevelDebug
83
+ }
78
84
cfg := & turn.ClientConfig {
79
85
STUNServerAddr : relayDetails .TurnServerAddress ,
80
86
TURNServerAddr : relayDetails .TurnServerAddress ,
81
87
Conn : turn .NewSTUNConn (conn ),
82
88
Username : relayDetails .TurnServerUsername ,
83
89
Password : relayDetails .TurnServerPassword ,
84
90
Realm : relayDetails .TurnServerRealm ,
85
- LoggerFactory : logging . NewDefaultLoggerFactory () ,
91
+ LoggerFactory : logger ,
86
92
}
87
93
88
94
client , err := turn .NewClient (cfg )
@@ -96,10 +102,6 @@ func (g *Gateway) ConnectWithRelay() error {
96
102
TurnServerAddress : relayDetails .TurnServerAddress ,
97
103
InfisicalStaticIp : relayDetails .InfisicalStaticIp ,
98
104
}
99
- // if port not specific allow all port
100
- if relayDetails .InfisicalStaticIp != "" && ! strings .Contains (relayDetails .InfisicalStaticIp , ":" ) {
101
- g .config .InfisicalStaticIp = g .config .InfisicalStaticIp + ":0"
102
- }
103
105
104
106
g .client = client
105
107
return nil
@@ -144,7 +146,10 @@ func (g *Gateway) Listen(ctx context.Context) error {
144
146
errCh := make (chan error , 1 )
145
147
shutdownCh := make (chan bool , 1 )
146
148
147
- g .registerPermissionRefresh (ctx , errCh )
149
+ if err = g .createPermissionForStaticIps (g .config .InfisicalStaticIp ); err != nil {
150
+ return err
151
+ }
152
+
148
153
g .registerHeartBeat (ctx , errCh )
149
154
150
155
cert , err := tls .X509KeyPair ([]byte (gatewayCert .Certificate ), []byte (gatewayCert .PrivateKey ))
@@ -171,8 +176,7 @@ func (g *Gateway) Listen(ctx context.Context) error {
171
176
KeepAlivePeriod : 2 * time .Second ,
172
177
}
173
178
174
- g .registerRelayIsActive (ctx , relayUdpConnection .LocalAddr ().String (), tlsConfig , quicConfig , errCh )
175
-
179
+ g .registerRelayIsActive (ctx , relayUdpConnection .LocalAddr ().String (), errCh )
176
180
quicListener , err := quic .Listen (relayUdpConnection , tlsConfig , quicConfig )
177
181
if err != nil {
178
182
return fmt .Errorf ("Failed to listen for QUIC: %w" , err )
@@ -234,6 +238,8 @@ func (g *Gateway) Listen(ctx context.Context) error {
234
238
}
235
239
}()
236
240
241
+ // make this compatiable with systemd notify mode
242
+ systemd .SdNotify (false , systemd .SdNotifyReady )
237
243
select {
238
244
case <- ctx .Done ():
239
245
log .Info ().Msg ("Shutting down gateway..." )
@@ -282,90 +288,76 @@ func (g *Gateway) registerHeartBeat(ctx context.Context, errCh chan error) {
282
288
}()
283
289
}
284
290
285
- func (g * Gateway ) registerRelayIsActive ( ctx context. Context , serverAddr string , tlsConf * tls. Config , quicConf * quic. Config , errCh chan error ) {
286
- ticker := time . NewTicker ( 5 * time . Second )
287
- maxFailures := 3
288
- failures := 0
291
+ func (g * Gateway ) createPermissionForStaticIps ( staticIps string ) error {
292
+ if staticIps == "" {
293
+ return fmt . Errorf ( "Missing Infisical static ips for permission" )
294
+ }
289
295
290
- go func () {
291
- time .Sleep (2 * time .Second )
292
- for {
293
- select {
294
- case <- ctx .Done ():
295
- return
296
- case <- ticker .C :
297
- conn , err := quic .DialAddr (ctx , serverAddr , tlsConf , quicConf )
298
- if conn != nil {
299
- failures = 0
300
- conn .CloseWithError (0 , "connection closed" )
301
- }
296
+ splittedIps := strings .Split (staticIps , "," )
297
+ resolvedIps := make ([]net.Addr , 0 )
298
+ for _ , ip := range splittedIps {
299
+ ip = strings .TrimSpace (ip )
300
+ if ip == "" {
301
+ continue
302
+ }
302
303
303
- if err != nil && ! strings .Contains (err .Error (), "tls: failed to verify certificate" ) {
304
- failures ++
305
- log .Warn ().Err (err ).Int ("failures" , failures ).Msg ("Relay connection check failed" )
304
+ // if port not specific allow all port
305
+ if ! strings .Contains (ip , ":" ) {
306
+ ip = ip + ":0"
307
+ }
306
308
307
- if failures >= maxFailures {
308
- errCh <- fmt .Errorf ("relay connection check failed: %w" , err )
309
- }
310
- }
311
- }
309
+ peerAddr , err := net .ResolveUDPAddr ("udp" , ip )
310
+ if err != nil {
311
+ return fmt .Errorf ("Failed to resolve static ip for permission: %w" , err )
312
312
}
313
- }()
314
- }
315
313
316
- func (g * Gateway ) registerPermissionRefresh (ctx context.Context , errCh chan error ) {
317
- if g .config .InfisicalStaticIp == "" {
318
- return
314
+ resolvedIps = append (resolvedIps , peerAddr )
319
315
}
320
316
321
- log . Info (). Msg ( "Starting TURN permission refresh routine" )
322
-
323
- go func () {
324
- ticker := time . NewTicker ( 30 * time . Second )
325
- defer ticker . Stop ()
317
+ if err := g . client . CreatePermission ( resolvedIps ... ); err != nil {
318
+ return fmt . Errorf ( "Failed to set ip permission: %w" , err )
319
+ }
320
+ return nil
321
+ }
326
322
327
- g .refreshPermission (errCh )
323
+ func (g * Gateway ) registerRelayIsActive (ctx context.Context , relayAddress string , errCh chan error ) error {
324
+ ticker := time .NewTicker (10 * time .Second )
325
+ maxFailures := 3
326
+ failures := 0
328
327
328
+ go func () {
329
+ time .Sleep (2 * time .Second )
329
330
for {
330
331
select {
331
332
case <- ctx .Done ():
332
- log .Info ().Msg ("Context cancelled, stopping TURN permission refresh" )
333
333
return
334
334
case <- ticker .C :
335
- g .refreshPermission (errCh )
335
+ // Configure TLS to skip verification
336
+ tlsConfig := & tls.Config {
337
+ InsecureSkipVerify : true ,
338
+ NextProtos : []string {"infisical-gateway" },
339
+ }
340
+ quicConfig := & quic.Config {
341
+ EnableDatagrams : true ,
342
+ }
343
+ func () {
344
+ checkCtx , cancel := context .WithTimeout (ctx , 3 * time .Second )
345
+ defer cancel ()
346
+ conn , err := quic .DialAddr (checkCtx , relayAddress , tlsConfig , quicConfig )
347
+ if err != nil {
348
+ failures ++
349
+ log .Warn ().Err (err ).Int ("failures" , failures ).Msg ("Relay connection check failed" )
350
+ if failures >= maxFailures {
351
+ errCh <- fmt .Errorf ("relay connection check failed: %w" , err )
352
+ }
353
+ }
354
+ if conn != nil {
355
+ conn .CloseWithError (0 , "closed" )
356
+ }
357
+ }()
336
358
}
337
359
}
338
360
}()
339
- }
340
361
341
- func (g * Gateway ) refreshPermission (errCh chan error ) {
342
- log .Info ().Msg ("Attempting to refresh TURN permission" )
343
- maxRetries := 3
344
- retryDelay := 5 * time .Second
345
-
346
- var lastErr error
347
- for i := 0 ; i < maxRetries ; i ++ {
348
- peerAddr , err := net .ResolveUDPAddr ("udp" , g .config .InfisicalStaticIp )
349
- if err != nil {
350
- log .Error ().Err (err ).Msg ("Failed to resolve static IP for permission refresh" )
351
- continue
352
- }
353
-
354
- if err := g .client .CreatePermission (peerAddr ); err != nil {
355
- lastErr = err
356
- log .Warn ().Err (err ).Int ("attempt" , i + 1 ).Msg ("Failed to refresh TURN permission, retrying..." )
357
- time .Sleep (retryDelay )
358
- continue
359
- }
360
-
361
- log .Info ().Msg ("Successfully refreshed TURN permission" )
362
- return
363
- }
364
-
365
- if lastErr != nil {
366
- log .Error ().Err (lastErr ).Msg ("Failed to refresh TURN permission after retries" )
367
- if reconnectErr := g .ConnectWithRelay (); reconnectErr != nil {
368
- errCh <- fmt .Errorf ("failed to refresh permissions and reconnect: %w" , reconnectErr )
369
- }
370
- }
362
+ return nil
371
363
}
0 commit comments