mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-10-05 07:13:36 +00:00
feat(dns): add Lua scripting for DNS queries
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package geodata
|
||||
|
||||
import (
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
luar "layeh.com/gopher-luar"
|
||||
)
|
||||
|
||||
// RegisterLua makes xray.geodata available to require in an LState.
|
||||
// Matchers retain registry handles, so they remain usable after a reload.
|
||||
func RegisterLua(L *lua.LState) {
|
||||
L.PreloadModule("xray.geodata", func(L *lua.LState) int {
|
||||
module := L.NewTable()
|
||||
|
||||
module.RawSetString("domainMatcher", L.NewFunction(func(L *lua.LState) int {
|
||||
parsed, err := ParseDomainRules(luaRules(L, 1), Domain_Domain)
|
||||
if err != nil {
|
||||
L.RaiseError("%v", err)
|
||||
return 0
|
||||
}
|
||||
matcher, err := DomainReg.BuildDomainMatcher(parsed)
|
||||
if err != nil {
|
||||
L.RaiseError("%v", err)
|
||||
return 0
|
||||
}
|
||||
L.Push(luar.New(L, matcher))
|
||||
return 1
|
||||
}))
|
||||
|
||||
module.RawSetString("ipMatcher", L.NewFunction(func(L *lua.LState) int {
|
||||
parsed, err := ParseIPRules(luaRules(L, 1))
|
||||
if err != nil {
|
||||
L.RaiseError("%v", err)
|
||||
return 0
|
||||
}
|
||||
matcher, err := IPReg.BuildIPMatcher(parsed)
|
||||
if err != nil {
|
||||
L.RaiseError("%v", err)
|
||||
return 0
|
||||
}
|
||||
L.Push(luar.New(L, matcher))
|
||||
return 1
|
||||
}))
|
||||
L.Push(module)
|
||||
return 1
|
||||
})
|
||||
}
|
||||
|
||||
func luaRules(L *lua.LState, index int) []string {
|
||||
table := L.CheckTable(index)
|
||||
rules := make([]string, table.Len())
|
||||
for i := range rules {
|
||||
value, ok := table.RawGetInt(i + 1).(lua.LString)
|
||||
if !ok {
|
||||
L.RaiseError("geodata rules must be strings")
|
||||
return nil
|
||||
}
|
||||
rules[i] = string(value)
|
||||
}
|
||||
return rules
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package geodata
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
func TestLuaIPMatcherAcceptsNativeIP(t *testing.T) {
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
RegisterLua(L)
|
||||
ip := L.NewUserData()
|
||||
ip.Value = net.ParseIP("127.0.0.1")
|
||||
L.SetGlobal("ip", ip)
|
||||
if err := L.DoString(`
|
||||
local matcher = require("xray.geodata").ipMatcher({"127.0.0.0/8"})
|
||||
assert(matcher:Match(ip))
|
||||
assert(matcher:AnyMatch({ip}))
|
||||
assert(matcher:Matches({ip}))
|
||||
local matched, unmatched = matcher:FilterIPs({ip})
|
||||
assert(#matched == 1 and #unmatched == 0)
|
||||
assert(matcher:Match(matched[1]))
|
||||
`); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLuaDomainMatcherUsesNativeMatcher(t *testing.T) {
|
||||
L := lua.NewState()
|
||||
defer L.Close()
|
||||
RegisterLua(L)
|
||||
if err := L.DoString(`
|
||||
local matcher = require("xray.geodata").domainMatcher({"example.com"})
|
||||
assert(matcher:MatchAny("example.com"))
|
||||
assert(matcher:MatchAny("www.example.com"))
|
||||
assert(#(matcher:Match("www.example.com")) == 1)
|
||||
`); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user