@@ -4,13 +4,17 @@ import (
4
4
"io"
5
5
"log"
6
6
"net"
7
+ "time"
7
8
8
9
"github.com/miekg/dns"
10
+ "github.com/patrickmn/go-cache"
9
11
"github.com/thinkgos/go-socks5/ccsocks5"
10
12
)
11
13
14
+ var c = cache .New (30 * time .Minute , 10 * time .Minute )
15
+
12
16
//StartServer acts start a dns proxy server
13
- func StartServer (localAddr * string , socksAddr * string , dnsAddr * string ) {
17
+ func StartServer (localAddr * string , socksAddr * string , dnsAddr * string , cached * bool ) {
14
18
addr , err := net .ResolveUDPAddr ("udp" , * localAddr )
15
19
if nil != err {
16
20
log .Fatalln ("Unable to get UDP socket:" , err )
@@ -21,6 +25,7 @@ func StartServer(localAddr *string, socksAddr *string, dnsAddr *string) {
21
25
}
22
26
defer conn .Close ()
23
27
log .Printf ("dns2socks started on %v" , * localAddr )
28
+
24
29
client := ccsocks5 .NewClient (* socksAddr )
25
30
defer client .Close ()
26
31
buf := make ([]byte , 4096 )
@@ -30,7 +35,17 @@ func StartServer(localAddr *string, socksAddr *string, dnsAddr *string) {
30
35
continue
31
36
}
32
37
b := buf [:n ]
33
- printQuestion (b )
38
+ if * cached {
39
+ answer := getAnswerFromCache (b )
40
+ if answer != nil {
41
+ respMsg := new (dns.Msg )
42
+ respMsg .Unpack (b )
43
+ respMsg .Answer = append (respMsg .Answer , * answer )
44
+ respData , _ := respMsg .Pack ()
45
+ conn .WriteToUDP (respData , fromAddr )
46
+ continue
47
+ }
48
+ }
34
49
proxyConn , err := client .Dial ("udp" , * dnsAddr )
35
50
if err != nil {
36
51
log .Println (err )
@@ -45,21 +60,35 @@ func StartServer(localAddr *string, socksAddr *string, dnsAddr *string) {
45
60
break
46
61
}
47
62
b := buf [:n ]
48
- printAnswer (b )
63
+ if * cached {
64
+ setAnswerCache (b )
65
+ }
49
66
conn .WriteToUDP (b , fromAddr )
50
67
}
51
68
}()
52
69
}
53
70
}
54
71
55
- func printQuestion (data []byte ) {
72
+ func getAnswerFromCache (data []byte ) * dns. RR {
56
73
msg := new (dns.Msg )
57
74
msg .Unpack (data )
58
- log .Printf ("dns question:%v" , msg .Question )
75
+ q := msg .Question [0 ]
76
+ if q .Qtype == dns .TypeA {
77
+ if v , found := c .Get (q .Name ); found {
78
+ log .Printf ("query dns from cache:%v" , msg .Question )
79
+ ret := v .(* dns.RR )
80
+ return ret
81
+ }
82
+ }
83
+ return nil
59
84
}
60
85
61
- func printAnswer (data []byte ) {
86
+ func setAnswerCache (data []byte ) {
62
87
msg := new (dns.Msg )
63
88
msg .Unpack (data )
64
- log .Printf ("dns answer:%v" , msg .Answer )
89
+ q := msg .Question [0 ]
90
+ if q .Qtype == dns .TypeA && len (msg .Answer ) > 0 {
91
+ c .Set (q .Name , & msg .Answer [len (msg .Answer )- 1 ], cache .DefaultExpiration )
92
+ log .Printf ("set dns cache:%v" , q .Name )
93
+ }
65
94
}
0 commit comments