@@ -4,7 +4,10 @@ import (
44 "crypto/sha512"
55 "encoding/binary"
66 "errors"
7+ "fmt"
78 "net"
9+ "os"
10+ "strings"
811 "sync"
912 "time"
1013
@@ -47,6 +50,9 @@ type PluginsState struct {
4750
4851func InitPluginsGlobals (pluginsGlobals * PluginsGlobals , proxy * Proxy ) error {
4952 queryPlugins := & []Plugin {}
53+ if len (proxy .queryLogFile ) != 0 {
54+ * queryPlugins = append (* queryPlugins , Plugin (new (PluginQueryLog )))
55+ }
5056 if proxy .pluginBlockIPv6 {
5157 * queryPlugins = append (* queryPlugins , Plugin (new (PluginBlockIPv6 )))
5258 }
@@ -184,7 +190,7 @@ func (plugin *PluginBlockIPv6) Name() string {
184190}
185191
186192func (plugin * PluginBlockIPv6 ) Description () string {
187- return "Immediately return a synthetic response to AAAA queries"
193+ return "Immediately return a synthetic response to AAAA queries. "
188194}
189195
190196func (plugin * PluginBlockIPv6 ) Init (proxy * Proxy ) error {
@@ -219,17 +225,28 @@ func (plugin *PluginBlockIPv6) Eval(pluginsState *PluginsState, msg *dns.Msg) er
219225
220226// -------- querylog plugin --------
221227
222- type PluginQueryLog struct {}
228+ type PluginQueryLog struct {
229+ sync.Mutex
230+ outFd * os.File
231+ }
223232
224233func (plugin * PluginQueryLog ) Name () string {
225234 return "querylog"
226235}
227236
228237func (plugin * PluginQueryLog ) Description () string {
229- return "Log DNS queries"
238+ return "Log DNS queries. "
230239}
231240
232241func (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+
233250 return nil
234251}
235252
@@ -242,6 +259,36 @@ func (plugin *PluginQueryLog) Reload() error {
242259}
243260
244261func (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 ()
245292 return nil
246293}
247294
0 commit comments