mirror of
https://github.com/tim-beatham/smegmesh.git
synced 2025-03-16 06:58:18 +01:00
Merge pull request #33 from tim-beatham/32-incorporate-dns
32-incorporate-dns
This commit is contained in:
commit
73db65660b
18
cmd/dns/main.go
Normal file
18
cmd/dns/main.go
Normal file
@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
smegdns "github.com/tim-beatham/wgmesh/pkg/dns"
|
||||
)
|
||||
|
||||
func main() {
|
||||
server, err := smegdns.NewDns(53)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
defer server.Close()
|
||||
server.Listen()
|
||||
}
|
@ -31,7 +31,7 @@ func NewCtrlServer(params *NewCtrlServerParams) (*MeshCtrlServer, error) {
|
||||
nodeFactory := crdt.MeshNodeFactory{
|
||||
Config: *params.Conf,
|
||||
}
|
||||
idGenerator := &lib.UUIDGenerator{}
|
||||
idGenerator := &lib.IDNameGenerator{}
|
||||
ipAllocator := &ip.ULABuilder{}
|
||||
interfaceManipulator := wg.NewWgInterfaceManipulator(params.Client)
|
||||
|
||||
|
114
pkg/dns/dns.go
Normal file
114
pkg/dns/dns.go
Normal file
@ -0,0 +1,114 @@
|
||||
package smegdns
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/rpc"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/tim-beatham/wgmesh/pkg/ipc"
|
||||
"github.com/tim-beatham/wgmesh/pkg/lib"
|
||||
logging "github.com/tim-beatham/wgmesh/pkg/log"
|
||||
"github.com/tim-beatham/wgmesh/pkg/query"
|
||||
)
|
||||
|
||||
const SockAddr = "/tmp/wgmesh_ipc.sock"
|
||||
|
||||
const MeshRegularExpression = `(?P<meshId>.+)\.(?P<alias>.+)\.smeg\.`
|
||||
|
||||
type DNSHandler struct {
|
||||
client *rpc.Client
|
||||
server *dns.Server
|
||||
}
|
||||
|
||||
// queryMesh: queries the mesh network for the given meshId and node
|
||||
// with alias
|
||||
func (d *DNSHandler) queryMesh(meshId, alias string) net.IP {
|
||||
var reply string
|
||||
|
||||
err := d.client.Call("IpcHandler.Query", &ipc.QueryMesh{
|
||||
MeshId: meshId,
|
||||
Query: "[?alias == 'tim'] | [0]",
|
||||
}, &reply)
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var node *query.QueryNode
|
||||
|
||||
err = json.Unmarshal([]byte(reply), &node)
|
||||
|
||||
if err != nil || node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ip, _, _ := net.ParseCIDR(node.WgHost)
|
||||
return ip
|
||||
}
|
||||
|
||||
func (d *DNSHandler) handleQuery(m *dns.Msg) {
|
||||
for _, q := range m.Question {
|
||||
switch q.Qtype {
|
||||
case dns.TypeAAAA:
|
||||
logging.Log.WriteInfof("Query for %s", q.Name)
|
||||
|
||||
groups := lib.MatchCaptureGroup(MeshRegularExpression, q.Name)
|
||||
|
||||
if len(groups) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
ip := d.queryMesh(groups["meshId"], groups["alias"])
|
||||
|
||||
rr, err := dns.NewRR(fmt.Sprintf("%s AAAA %s", q.Name, ip))
|
||||
|
||||
if err != nil {
|
||||
logging.Log.WriteErrorf(err.Error())
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
m.Answer = append(m.Answer, rr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *DNSHandler) handleDnsRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
msg := new(dns.Msg)
|
||||
msg.SetReply(r)
|
||||
msg.Authoritative = true
|
||||
|
||||
switch r.Opcode {
|
||||
case dns.OpcodeQuery:
|
||||
h.handleQuery(msg)
|
||||
}
|
||||
|
||||
w.WriteMsg(msg)
|
||||
}
|
||||
|
||||
func (h *DNSHandler) Listen() error {
|
||||
return h.server.ListenAndServe()
|
||||
}
|
||||
|
||||
func (h *DNSHandler) Close() error {
|
||||
return h.server.Shutdown()
|
||||
}
|
||||
|
||||
func NewDns(udpPort int) (*DNSHandler, error) {
|
||||
client, err := rpc.DialHTTP("unix", SockAddr)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dnsHander := DNSHandler{
|
||||
client: client,
|
||||
}
|
||||
|
||||
dns.HandleFunc("smeg.", dnsHander.handleDnsRequest)
|
||||
|
||||
dnsHander.server = &dns.Server{Addr: fmt.Sprintf(":%d", udpPort), Net: "udp"}
|
||||
return &dnsHander, nil
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
package lib
|
||||
|
||||
import "github.com/google/uuid"
|
||||
import (
|
||||
"github.com/anandvarma/namegen"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// IdGenerator generates unique ids
|
||||
type IdGenerator interface {
|
||||
@ -15,3 +18,11 @@ func (g *UUIDGenerator) GetId() (string, error) {
|
||||
id := uuid.New()
|
||||
return id.String(), nil
|
||||
}
|
||||
|
||||
type IDNameGenerator struct {
|
||||
}
|
||||
|
||||
func (i *IDNameGenerator) GetId() (string, error) {
|
||||
name_schema := namegen.New()
|
||||
return name_schema.Get(), nil
|
||||
}
|
||||
|
19
pkg/lib/regex.go
Normal file
19
pkg/lib/regex.go
Normal file
@ -0,0 +1,19 @@
|
||||
package lib
|
||||
|
||||
import "regexp"
|
||||
|
||||
func MatchCaptureGroup(pattern, payload string) map[string]string {
|
||||
patterns := make(map[string]string)
|
||||
|
||||
expr := regexp.MustCompile(pattern)
|
||||
|
||||
match := expr.FindStringSubmatch(payload)
|
||||
|
||||
for i, name := range expr.SubexpNames() {
|
||||
if i != 0 && name != "" {
|
||||
patterns[name] = match[i]
|
||||
}
|
||||
}
|
||||
|
||||
return patterns
|
||||
}
|
Loading…
Reference in New Issue
Block a user