-
-
Notifications
You must be signed in to change notification settings - Fork 210
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* added util for handling EDNS0 options * disable caching if the request contains a netmask size greater than 1 * added config section for ECS handling and validation for it *added ecs_resolver for enhancing and cleaning subnet and client IP information
- Loading branch information
Showing
19 changed files
with
1,116 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package config | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
|
||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
const ( | ||
ecsIpv4MaskMax = uint8(32) | ||
ecsIpv6MaskMax = uint8(128) | ||
) | ||
|
||
// ECSv4Mask is the subnet mask to be added as EDNS0 option for IPv4 | ||
type ECSv4Mask uint8 | ||
|
||
// UnmarshalText implements the encoding.TextUnmarshaler interface | ||
func (x *ECSv4Mask) UnmarshalText(text []byte) error { | ||
res, err := unmarshalInternal(text, ecsIpv4MaskMax, "IPv4") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
*x = ECSv4Mask(res) | ||
|
||
return nil | ||
} | ||
|
||
// ECSv6Mask is the subnet mask to be added as EDNS0 option for IPv6 | ||
type ECSv6Mask uint8 | ||
|
||
// UnmarshalText implements the encoding.TextUnmarshaler interface | ||
func (x *ECSv6Mask) UnmarshalText(text []byte) error { | ||
res, err := unmarshalInternal(text, ecsIpv6MaskMax, "IPv6") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
*x = ECSv6Mask(res) | ||
|
||
return nil | ||
} | ||
|
||
// ECSConfig is the configuration of the ECS resolver | ||
type ECSConfig struct { | ||
UseAsClient bool `yaml:"useAsClient" default:"false"` | ||
Forward bool `yaml:"forward" default:"false"` | ||
IPv4Mask ECSv4Mask `yaml:"ipv4Mask" default:"0"` | ||
IPv6Mask ECSv6Mask `yaml:"ipv6Mask" default:"0"` | ||
} | ||
|
||
// IsEnabled returns true if the ECS resolver is enabled | ||
func (c *ECSConfig) IsEnabled() bool { | ||
return c.UseAsClient || c.Forward || c.IPv4Mask > 0 || c.IPv6Mask > 0 | ||
} | ||
|
||
// LogConfig logs the configuration | ||
func (c *ECSConfig) LogConfig(logger *logrus.Entry) { | ||
logger.Infof("Use as client = %t", c.UseAsClient) | ||
logger.Infof("Forward = %t", c.Forward) | ||
logger.Infof("IPv4 netmask = %d", c.IPv4Mask) | ||
logger.Infof("IPv6 netmask = %d", c.IPv6Mask) | ||
} | ||
|
||
// unmarshalInternal unmarshals the subnet mask from the given text and checks if the value is valid | ||
// it is used by the UnmarshalText methods of ECSv4Mask and ECSv6Mask | ||
func unmarshalInternal(text []byte, maxvalue uint8, name string) (uint8, error) { | ||
strVal := string(text) | ||
|
||
uiVal, err := strconv.ParseUint(strVal, 10, 8) | ||
if err != nil { | ||
return 0, err | ||
} | ||
|
||
if uiVal > uint64(maxvalue) { | ||
return 0, fmt.Errorf("mask value (%s) is too large for %s(max: %d)", strVal, name, maxvalue) | ||
} | ||
|
||
return uint8(uiVal), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
package config | ||
|
||
import ( | ||
"github.com/0xERR0R/blocky/log" | ||
"github.com/creasty/defaults" | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
var _ = Describe("ECSConfig", func() { | ||
var ( | ||
c ECSConfig | ||
err error | ||
) | ||
|
||
BeforeEach(func() { | ||
err = defaults.Set(&c) | ||
Expect(err).Should(Succeed()) | ||
}) | ||
|
||
Describe("IsEnabled", func() { | ||
When("all fields are default", func() { | ||
It("should be disabled", func() { | ||
Expect(c.IsEnabled()).Should(BeFalse()) | ||
}) | ||
}) | ||
|
||
When("UseEcsAsClient is true", func() { | ||
BeforeEach(func() { | ||
c.UseAsClient = true | ||
}) | ||
|
||
It("should be enabled", func() { | ||
Expect(c.IsEnabled()).Should(BeTrue()) | ||
}) | ||
}) | ||
|
||
When("ForwardEcs is true", func() { | ||
BeforeEach(func() { | ||
c.Forward = true | ||
}) | ||
|
||
It("should be enabled", func() { | ||
Expect(c.IsEnabled()).Should(BeTrue()) | ||
}) | ||
}) | ||
|
||
When("IPv4Mask is set", func() { | ||
BeforeEach(func() { | ||
c.IPv4Mask = 24 | ||
}) | ||
|
||
It("should be enabled", func() { | ||
Expect(c.IsEnabled()).Should(BeTrue()) | ||
}) | ||
}) | ||
|
||
When("IPv6Mask is set", func() { | ||
BeforeEach(func() { | ||
c.IPv6Mask = 64 | ||
}) | ||
|
||
It("should be enabled", func() { | ||
Expect(c.IsEnabled()).Should(BeTrue()) | ||
}) | ||
}) | ||
}) | ||
|
||
Describe("LogConfig", func() { | ||
BeforeEach(func() { | ||
logger, hook = log.NewMockEntry() | ||
}) | ||
|
||
It("should log configuration", func() { | ||
c.LogConfig(logger) | ||
|
||
Expect(hook.Calls).Should(HaveLen(4)) | ||
Expect(hook.Messages).Should(SatisfyAll( | ||
ContainElement(ContainSubstring("Use as client")), | ||
ContainElement(ContainSubstring("Forward")), | ||
ContainElement(ContainSubstring("IPv4 netmask")), | ||
ContainElement(ContainSubstring("IPv6 netmask")), | ||
)) | ||
}) | ||
}) | ||
|
||
Describe("Parse", func() { | ||
var data []byte | ||
|
||
Context("IPv4Mask", func() { | ||
var ipmask ECSv4Mask | ||
|
||
When("Parse correct value", func() { | ||
BeforeEach(func() { | ||
data = []byte("24") | ||
err = yaml.Unmarshal(data, &ipmask) | ||
Expect(err).Should(Succeed()) | ||
}) | ||
|
||
It("should be value", func() { | ||
Expect(ipmask).Should(Equal(ECSv4Mask(24))) | ||
}) | ||
}) | ||
|
||
When("Parse NaN value", func() { | ||
BeforeEach(func() { | ||
data = []byte("FALSE") | ||
err = yaml.Unmarshal(data, &ipmask) | ||
}) | ||
|
||
It("should be error", func() { | ||
Expect(err).Should(HaveOccurred()) | ||
}) | ||
}) | ||
|
||
When("Parse incorrect value", func() { | ||
BeforeEach(func() { | ||
data = []byte("35") | ||
err = yaml.Unmarshal(data, &ipmask) | ||
}) | ||
|
||
It("should be error", func() { | ||
Expect(err).Should(HaveOccurred()) | ||
}) | ||
}) | ||
}) | ||
|
||
Context("IPv6Mask", func() { | ||
var ipmask ECSv6Mask | ||
|
||
When("Parse correct value", func() { | ||
BeforeEach(func() { | ||
data = []byte("64") | ||
err = yaml.Unmarshal(data, &ipmask) | ||
Expect(err).Should(Succeed()) | ||
}) | ||
|
||
It("should be value", func() { | ||
Expect(ipmask).Should(Equal(ECSv6Mask(64))) | ||
}) | ||
}) | ||
|
||
When("Parse NaN value", func() { | ||
BeforeEach(func() { | ||
data = []byte("FALSE") | ||
err = yaml.Unmarshal(data, &ipmask) | ||
}) | ||
|
||
It("should be error", func() { | ||
Expect(err).Should(HaveOccurred()) | ||
}) | ||
}) | ||
|
||
When("Parse incorrect value", func() { | ||
BeforeEach(func() { | ||
data = []byte("130") | ||
err = yaml.Unmarshal(data, &ipmask) | ||
}) | ||
|
||
It("should be error", func() { | ||
Expect(err).Should(HaveOccurred()) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.