Myzel394 eb076dbf53
refactor(server): Improve Wireguard analyzer
Signed-off-by: Myzel394 <github.7a2op@simplelogin.co>
2025-03-16 00:23:54 +01:00

137 lines
4.1 KiB
Go

package analyzer
import (
"config-lsp/common"
"config-lsp/utils"
"context"
"fmt"
"net/netip"
"strings"
protocol "github.com/tliron/glsp/protocol_3_16"
)
func analyzeDNSPropertyContainsFallback(
ctx *analyzerContext,
) {
sections, found := ctx.document.Indexes.SectionsByName["Interface"]
if !found {
return
}
interfaceSection := sections[0]
property := interfaceSection.FindFirstPropertyByName("DNS")
if property == nil {
return
}
dnsAmount := len(strings.Split(property.Value.Value, ","))
if dnsAmount == 1 {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Message: "There is only one DNS server specified. It is recommended to set up fallback DNS servers",
Severity: &common.SeverityHint,
Range: property.Value.ToLSPRange(),
})
}
}
func analyzeKeepAlivePropertyIsSet(
ctx *analyzerContext,
) {
for _, section := range ctx.document.Indexes.SectionsByName["Peer"] {
// If an endpoint is set, then we should only check for the keepalive property
if section.FindFirstPropertyByName("Endpoint") != nil && section.FindFirstPropertyByName("PersistentKeepalive") == nil {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Message: "PersistentKeepalive is not set. It is recommended to set this property, as it helps to maintain the connection when users are behind NAT",
Severity: &common.SeverityHint,
Range: section.Header.ToLSPRange(),
})
}
}
}
func analyzeSymmetricPropertiesSet(
ctx *analyzerContext,
) {
for _, section := range ctx.document.Indexes.SectionsByName["Interface"] {
preUpProperty := section.FindFirstPropertyByName("PreUp")
preDownProperty := section.FindFirstPropertyByName("PreDown")
postUpProperty := section.FindFirstPropertyByName("PostUp")
postDownProperty := section.FindFirstPropertyByName("PostDown")
if preUpProperty != nil && preDownProperty == nil {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Message: "PreUp is set, but PreDown is not. It is recommended to set both properties symmetrically",
Range: preUpProperty.ToLSPRange(),
Severity: &common.SeverityHint,
})
} else if preUpProperty == nil && preDownProperty != nil {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Message: "PreDown is set, but PreUp is not. It is recommended to set both properties symmetrically",
Range: preDownProperty.ToLSPRange(),
Severity: &common.SeverityHint,
})
}
if postUpProperty != nil && postDownProperty == nil {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Message: "PostUp is set, but PostDown is not. It is recommended to set both properties symmetrically",
Range: postUpProperty.ToLSPRange(),
Severity: &common.SeverityHint,
})
} else if postUpProperty == nil && postDownProperty != nil {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Message: "PostDown is set, but PostUp is not. It is recommended to set both properties symmetrically",
Range: postDownProperty.ToLSPRange(),
Severity: &common.SeverityHint,
})
}
}
}
// Strategy
// Simply compare the host bits of the IP addresses.
// Use a binary tree to store the host bits.
func analyzeDuplicateAllowedIPs(
ctx *analyzerContext,
) {
ipHostSet := utils.CreateIPv4HostSet()
for _, section := range ctx.document.Indexes.SectionsByName["Peer"] {
property := section.FindFirstPropertyByName("AllowedIPs")
if property == nil {
continue
}
ipAddress, err := netip.ParsePrefix(property.Value.Value)
if err != nil {
// This should not happen...
continue
}
if ipContext, _ := ipHostSet.ContainsIP(ipAddress); ipContext != nil {
definedLine := (*ipContext).Value("line").(uint32)
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Message: fmt.Sprintf("This IP range is already covered on line %d", definedLine+1),
Severity: &common.SeverityError,
Range: property.ToLSPRange(),
})
} else {
ipContext := context.WithValue(context.Background(), "line", property.Start.Line)
ipHostSet.AddIP(
ipAddress,
ipContext,
)
}
}
}