@@ -4,7 +4,10 @@ import (
4
4
"crypto/sha512"
5
5
"encoding/binary"
6
6
"errors"
7
+ "fmt"
7
8
"net"
9
+ "os"
10
+ "strings"
8
11
"sync"
9
12
"time"
10
13
@@ -47,6 +50,9 @@ type PluginsState struct {
47
50
48
51
func InitPluginsGlobals (pluginsGlobals * PluginsGlobals , proxy * Proxy ) error {
49
52
queryPlugins := & []Plugin {}
53
+ if len (proxy .queryLogFile ) != 0 {
54
+ * queryPlugins = append (* queryPlugins , Plugin (new (PluginQueryLog )))
55
+ }
50
56
if proxy .pluginBlockIPv6 {
51
57
* queryPlugins = append (* queryPlugins , Plugin (new (PluginBlockIPv6 )))
52
58
}
@@ -184,7 +190,7 @@ func (plugin *PluginBlockIPv6) Name() string {
184
190
}
185
191
186
192
func (plugin * PluginBlockIPv6 ) Description () string {
187
- return "Immediately return a synthetic response to AAAA queries"
193
+ return "Immediately return a synthetic response to AAAA queries. "
188
194
}
189
195
190
196
func (plugin * PluginBlockIPv6 ) Init (proxy * Proxy ) error {
@@ -219,17 +225,28 @@ func (plugin *PluginBlockIPv6) Eval(pluginsState *PluginsState, msg *dns.Msg) er
219
225
220
226
// -------- querylog plugin --------
221
227
222
- type PluginQueryLog struct {}
228
+ type PluginQueryLog struct {
229
+ sync.Mutex
230
+ outFd * os.File
231
+ }
223
232
224
233
func (plugin * PluginQueryLog ) Name () string {
225
234
return "querylog"
226
235
}
227
236
228
237
func (plugin * PluginQueryLog ) Description () string {
229
- return "Log DNS queries"
238
+ return "Log DNS queries. "
230
239
}
231
240
232
241
func (plugin * PluginQueryLog ) Init (proxy * Proxy ) error {
242
+ plugin .Lock ()
243
+ defer plugin .Unlock ()
244
+ outFd , err := os .OpenFile (proxy .queryLogFile , os .O_WRONLY | os .O_APPEND | os .O_CREATE , 0644 )
245
+ if err != nil {
246
+ return err
247
+ }
248
+ plugin .outFd = outFd
249
+
233
250
return nil
234
251
}
235
252
@@ -242,6 +259,36 @@ func (plugin *PluginQueryLog) Reload() error {
242
259
}
243
260
244
261
func (plugin * PluginQueryLog ) Eval (pluginsState * PluginsState , msg * dns.Msg ) error {
262
+ questions := msg .Question
263
+ if len (questions ) == 0 {
264
+ return nil
265
+ }
266
+ question := questions [0 ]
267
+ now := time .Now ()
268
+ year , month , day := now .Date ()
269
+ hour , minute , second := now .Clock ()
270
+ tsStr := fmt .Sprintf ("[%d-%02d-%02d %02d:%02d:%02d]" , year , int (month ), day , hour , minute , second )
271
+ var clientIPStr string
272
+ if pluginsState .clientProto == "udp" {
273
+ clientIPStr = (* pluginsState .clientAddr ).(* net.UDPAddr ).IP .String ()
274
+ } else {
275
+ clientIPStr = (* pluginsState .clientAddr ).(* net.TCPAddr ).IP .String ()
276
+ }
277
+ qName := question .Name
278
+ if len (qName ) > 1 && strings .HasSuffix (qName , "." ) {
279
+ qName = qName [0 : len (qName )- 1 ]
280
+ }
281
+ qType , ok := dns .TypeToString [question .Qtype ]
282
+ if ! ok {
283
+ qType = string (qType )
284
+ }
285
+ line := fmt .Sprintf ("%s\t %s\t %s\t %s\n " , tsStr , clientIPStr , qName , qType )
286
+ plugin .Lock ()
287
+ if plugin .outFd == nil {
288
+ return errors .New ("Log file not initialized" )
289
+ }
290
+ plugin .outFd .WriteString (line )
291
+ defer plugin .Unlock ()
245
292
return nil
246
293
}
247
294
0 commit comments