Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions pkg/net/addr_advertise.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,59 @@ func BuildAdvertisedAddresses(
}
return slices.UniqueSlice(result), nil
}

func MustBuildAdvertisedQUICAddresses(
log logger.AppLogger,
publicIPV4,
publicIPV6 string,
listenPort int,
) []multiaddr.Multiaddr {
mas, err := BuildAdvertisedQUICAddresses(log, publicIPV4, publicIPV6, listenPort)
if err != nil {
log.Fatal("failed to build advertised QUIC addresses", err,
logger.WithString("public_ipv4", publicIPV4),
logger.WithString("public_ipv6", publicIPV6),
logger.WithInt("listen_port", listenPort),
)
}
return mas
}

func BuildAdvertisedQUICAddresses(
log logger.AppLogger,
publicIPV4,
publicIPV6 string,
listenPort int,
) ([]multiaddr.Multiaddr, error) {
if listenPort <= 0 || listenPort > 65535 {
return nil, fmt.Errorf("invalid listenPort: %d", listenPort)
}
result := make([]multiaddr.Multiaddr, 0, 8)

publicAddressV4, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/udp/%d/quic-v1", publicIPV4, listenPort))
if err != nil {
return nil, fmt.Errorf("failed to build advertised address: %w", err)
}
result = append(result, publicAddressV4)

if publicIPV6 != "" {
publicAddressV6, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip6/%s/udp/%d/quic-v1", publicIPV6, listenPort))
if err != nil {
log.Error("failed to build advertised address v6", err, logger.WithString("public_ip", publicIPV6))
} else {
result = append(result, publicAddressV6)
}
}

for _, ipStr := range GetInterfaceIPs() {
if net.ParseIP(ipStr) == nil {
Comment thread
abergasov marked this conversation as resolved.
continue
}
ma, errI := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/udp/%d/quic-v1", ipStr, listenPort))
if errI != nil {
continue
}
result = append(result, ma)
}
return slices.UniqueSlice(result), nil
}
55 changes: 55 additions & 0 deletions pkg/net/addr_advertise_quic_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package net_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/getoptimum/optimum-common/pkg/logger"
"github.com/getoptimum/optimum-common/pkg/net"
)
Comment on lines +3 to +10

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Apply the repository’s gci import grouping.

The lint job fails on this import block, blocking CI.

Proposed fix
 import (
 	"testing"
 
 	"github.com/getoptimum/optimum-common/pkg/logger"
 	"github.com/getoptimum/optimum-common/pkg/net"
+
 	"github.com/stretchr/testify/require"
 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import (
"testing"
"github.com/getoptimum/optimum-common/pkg/logger"
"github.com/getoptimum/optimum-common/pkg/net"
"github.com/stretchr/testify/require"
)
import (
"testing"
"github.com/getoptimum/optimum-common/pkg/logger"
"github.com/getoptimum/optimum-common/pkg/net"
"github.com/stretchr/testify/require"
)
🧰 Tools
🪛 GitHub Actions: Lint / golangci _ golangci-lint

[error] 5-5: golangci-lint reported formatting issue (gci): File is not properly formatted (gci).

🪛 GitHub Check: golangci / golangci-lint

[failure] 5-5:
File is not properly formatted (gci)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/net/addr_advertise_quic_test.go` around lines 3 - 9, Update the import
block in the test file to match the repository’s gci grouping and ordering
rules, keeping standard-library imports separated from third-party imports and
preserving all existing dependencies.

Sources: Linters/SAST tools, Pipeline failures


func TestBuildAdvertisedQUICAddresses(t *testing.T) {
l := logger.NewAppSLogger(logger.Debug)

t.Run("valid payload", func(t *testing.T) {
res, err := net.BuildAdvertisedQUICAddresses(l, "1.2.3.4", "2001:db8::1", 4001)
require.NoError(t, err)

require.Contains(t, res, mustMA(t, "/ip4/1.2.3.4/udp/4001/quic-v1"))
require.Contains(t, res, mustMA(t, "/ip6/2001:db8::1/udp/4001/quic-v1"))
})
t.Run("should return err on invalid ipv4", func(t *testing.T) {
res, err := net.BuildAdvertisedQUICAddresses(l, "not-an-ip", "2001:db8::1", 4001)
require.Error(t, err)
require.Empty(t, res)
})
t.Run("should work with empty ipv6", func(t *testing.T) {
res, err := net.BuildAdvertisedQUICAddresses(l, "1.2.3.4", "", 4001)
require.NoError(t, err)
require.Contains(t, res, mustMA(t, "/ip4/1.2.3.4/udp/4001/quic-v1"))
})
t.Run("should not fail on invalid ipv6 and still return ipv4", func(t *testing.T) {
res, err := net.BuildAdvertisedQUICAddresses(l, "1.2.3.4", "not-an-ip", 4001)
require.NoError(t, err)
require.Contains(t, res, mustMA(t, "/ip4/1.2.3.4/udp/4001/quic-v1"))
})
t.Run("should return err on invalid port", func(t *testing.T) {
res, err := net.BuildAdvertisedQUICAddresses(l, "1.2.3.4", "2001:db8::1", 0)
require.Error(t, err)
require.Empty(t, res)

res, err = net.BuildAdvertisedQUICAddresses(l, "1.2.3.4", "2001:db8::1", 70000)
require.Error(t, err)
require.Empty(t, res)
})
t.Run("should accept boundary ports", func(t *testing.T) {
res, err := net.BuildAdvertisedQUICAddresses(l, "1.2.3.4", "", 1)
require.NoError(t, err)
require.Contains(t, res, mustMA(t, "/ip4/1.2.3.4/udp/1/quic-v1"))

res, err = net.BuildAdvertisedQUICAddresses(l, "1.2.3.4", "", 65535)
require.NoError(t, err)
require.Contains(t, res, mustMA(t, "/ip4/1.2.3.4/udp/65535/quic-v1"))
})
}
Loading