1
1
/*
2
- Copyright 2024 LinuxSuRen.
2
+ Copyright 2024-2025 LinuxSuRen.
3
3
4
4
Licensed under the Apache License, Version 2.0 (the "License");
5
5
you may not use this file except in compliance with the License.
@@ -18,16 +18,9 @@ package cmd
18
18
19
19
import (
20
20
"fmt"
21
- "github.com/google/gopacket"
22
- "github.com/google/gopacket/layers"
23
21
adns "github.com/linuxsuren/atest-ext-collector/pkg/dns"
24
- "github.com/miekg/dns"
25
22
"github.com/spf13/cobra"
26
23
"github.com/spf13/pflag"
27
- "gopkg.in/yaml.v3"
28
- "net"
29
- "os"
30
- "strings"
31
24
)
32
25
33
26
func createDNSCmd () (cmd * cobra.Command ) {
@@ -51,6 +44,8 @@ type dnsOptions struct {
51
44
52
45
// inner fields
53
46
cacheHandler adns.DNSCache
47
+ server adns.Server
48
+ config * adns.DNSConfig
54
49
}
55
50
56
51
func (o * dnsOptions ) setFlags (flags * pflag.FlagSet ) {
@@ -68,107 +63,34 @@ func (o *dnsOptions) preRunE(_ *cobra.Command, _ []string) (err error) {
68
63
}
69
64
70
65
if o .simpleConfig != "" {
71
- var data []byte
72
- if data , err = os .ReadFile (o .simpleConfig ); err == nil {
73
- records := make (map [string ]string )
74
- if err = yaml .Unmarshal (data , & records ); err == nil {
75
- o .cacheHandler .Init (records )
76
- }
66
+ if o .config , err = adns .ParseFromFile (o .simpleConfig ); err != nil {
67
+ return
77
68
}
78
- }
79
- return
80
- }
81
69
82
- func (o * dnsOptions ) runE (cmd * cobra.Command , args []string ) (err error ) {
83
- addr := net.UDPAddr {
84
- Port : o .port ,
85
- IP : net .ParseIP ("0.0.0.0" ),
70
+ o .cacheHandler .Init (o .config .Simple )
71
+ o .cacheHandler .GetWildcardCache ().Init (o .config .Wildcard )
86
72
}
87
- var u * net.UDPConn
88
- if u , err = net .ListenUDP ("udp" , & addr ); err != nil {
89
- return
73
+ if o .config == nil {
74
+ o .config = & adns.DNSConfig {}
90
75
}
91
76
92
- cmd .Println ("DNS server is ready!" )
93
- go func () {
94
- if err := adns .NewHTTPServer (o .httpPort , o .cacheHandler ).Start (); err != nil {
95
- panic (err )
96
- }
97
- }()
98
- // Wait to get request on that port
99
- for {
100
- tmp := make ([]byte , 1024 )
101
- _ , addr , _ := u .ReadFrom (tmp )
102
- clientAddr := addr
103
- packet := gopacket .NewPacket (tmp , layers .LayerTypeDNS , gopacket .Default )
104
- dnsPacket := packet .Layer (layers .LayerTypeDNS )
105
- tcp , _ := dnsPacket .(* layers.DNS )
106
- if ! o .serveDNS (u , clientAddr , tcp ) {
107
- o .cacheDNS (string (tcp .Questions [0 ].Name ))
108
- }
77
+ if o .upstream != "" {
78
+ o .config .Upstream = o .upstream
79
+ }
80
+ if o .port > 0 {
81
+ o .config .Port = o .port
109
82
}
83
+ o .server = adns .NewDNSServer (o .config , o .cacheHandler )
110
84
return
111
85
}
112
86
113
- func (o * dnsOptions ) cacheDNS (name string ) {
114
- client := dns.Client {}
115
- var m dns.Msg
116
- m .SetQuestion (name + "." , dns .TypeA )
117
- reply , _ , err := client .Exchange (& m , o .upstream )
118
- if err != nil {
119
- fmt .Println ("failed query domain" , name , err )
120
- return
121
- }
122
- if reply .Rcode == dns .RcodeSuccess && len (reply .Answer ) > 0 {
123
- if a , ok := reply .Answer [0 ].(* dns.A ); ok {
124
- o .cacheHandler .Put (strings .TrimSuffix (reply .Question [0 ].Name , "." ), a .A .String ())
125
- fmt .Println ("cache new record" , reply .Question [0 ].Name , "==" , a .A .String ())
126
- fmt .Println ("total cache item count" , o .cacheHandler .Size ())
127
- return
128
- } else if cname , ok := reply .Answer [0 ].(* dns.CNAME ); ok {
129
- fmt .Println (name , "==" , strings .TrimSuffix (cname .Hdr .Name , "." ), "==" , strings .TrimSuffix (cname .Target , "." ))
130
- if ip := o .cacheHandler .LookupIP (strings .TrimSuffix (cname .Target , "." )); ip != "" {
131
- o .cacheHandler .Put (strings .TrimSuffix (cname .Hdr .Name , "." ), ip )
132
- } else {
133
- o .cacheDNS (strings .TrimSuffix (cname .Target , "." ))
134
- }
87
+ func (o * dnsOptions ) runE (cmd * cobra.Command , args []string ) (err error ) {
88
+ go func () {
89
+ if err := adns .NewHTTPServer (o .httpPort , o .upstream , o .cacheHandler ).Start (); err != nil {
90
+ panic (err )
135
91
}
136
- fmt .Println ("unknown record" , reply .Question [0 ].Name , "," , reply .Answer [0 ].String ())
137
- }
138
- }
92
+ }()
139
93
140
- func (o * dnsOptions ) serveDNS (u * net.UDPConn , clientAddr net.Addr , request * layers.DNS ) (resolved bool ) {
141
- replyMess := request
142
- var dnsAnswer layers.DNSResourceRecord
143
- dnsAnswer .Type = layers .DNSTypeA
144
- var ip string
145
- var err error
146
- resolved = true
147
- ip = o .cacheHandler .LookupIP (string (request .Questions [0 ].Name ))
148
- if ip == "" {
149
- //fmt.Printf("cannot found: %s\n", request.Questions[0].Name)
150
- resolved = false
151
- return
152
- //Todo: Log no data present for the IP and handle:todo
153
- }
154
- a , _ , _ := net .ParseCIDR (ip + "/24" )
155
- dnsAnswer .Type = layers .DNSTypeA
156
- dnsAnswer .IP = a
157
- dnsAnswer .Name = []byte (request .Questions [0 ].Name )
158
- fmt .Println (string (request .Questions [0 ].Name ), "===" , ip )
159
- dnsAnswer .Class = layers .DNSClassIN
160
- replyMess .QR = true
161
- replyMess .ANCount = 1
162
- replyMess .OpCode = layers .DNSOpCodeNotify
163
- replyMess .AA = true
164
- replyMess .Answers = append (replyMess .Answers , dnsAnswer )
165
- replyMess .ResponseCode = layers .DNSResponseCodeNoErr
166
- buf := gopacket .NewSerializeBuffer ()
167
- opts := gopacket.SerializeOptions {} // See SerializeOptions for more details.
168
- err = replyMess .SerializeTo (buf , opts )
169
- if err != nil {
170
- panic (err )
171
- }
172
- u .WriteTo (buf .Bytes (), clientAddr )
94
+ err = o .server .Start ()
173
95
return
174
96
}
0 commit comments