@@ -3,6 +3,7 @@ package main
3
3
import (
4
4
"bytes"
5
5
"chashell/lib/crypto"
6
+ "chashell/lib/logging"
6
7
"chashell/lib/protocol"
7
8
"encoding/hex"
8
9
"fmt"
@@ -35,6 +36,10 @@ var packetQueue = map[string][]string{}
35
36
// Store the sessions information.
36
37
var sessionsMap = map [string ]* clientInfo {}
37
38
39
+ // Temporary store the polled query. Some DNS Servers will perform multiples DNS requests for one query.
40
+ // We need to send the same query to every requests or the Chashell client will not receive the data.
41
+ var pollCache = map [string ]* pollTemporaryData {}
42
+
38
43
type clientInfo struct {
39
44
hostname string
40
45
heartbeat int64
@@ -48,6 +53,11 @@ type connData struct {
48
53
packets map [int32 ]string
49
54
}
50
55
56
+ type pollTemporaryData struct {
57
+ lastseen int64
58
+ data string
59
+ }
60
+
51
61
func (ci * clientInfo ) getChunk (chunkID int32 ) connData {
52
62
// Return the chunk identifier.
53
63
return ci .conn [chunkID ]
@@ -116,22 +126,51 @@ func parseQuery(m *dns.Msg) {
116
126
// Identify the message type.
117
127
switch u := message .Packet .(type ) {
118
128
case * protocol.Message_Pollquery :
129
+ // Check if this DNS poll-request was already performed.
130
+ temp , valid := pollCache [string (dataPacketRaw )]
131
+ if valid {
132
+ log .Println ("Duplicated poll query received." )
133
+ // Send already in cache data.
134
+ answer = temp .data
135
+ break
136
+ }
137
+
119
138
// Check if we have data to send.
120
139
queue , valid := packetQueue [clientGUID ]
121
140
122
141
if valid && len (queue ) > 0 {
123
142
answer = queue [0 ]
143
+ // Store answer in cache for DNS servers which are sending multiple queries.
144
+ pollCache [string (dataPacketRaw )] = & pollTemporaryData {lastseen : now .Unix (), data : answer }
145
+ // Dequeue.
124
146
packetQueue [clientGUID ] = queue [1 :]
125
147
}
148
+ case * protocol.Message_Infopacket :
149
+ session .hostname = string (u .Infopacket .Hostname )
126
150
127
151
case * protocol.Message_Chunkstart :
152
+ // Some DNS Servers will send multiple DNS queries, ignore duplicates.
153
+ _ , valid := session .conn [u .Chunkstart .Chunkid ]
154
+ if valid {
155
+ log .Printf ("Ignoring duplicated Chunkstart : %d\n " , u .Chunkstart .Chunkid )
156
+ break
157
+ }
158
+
128
159
// We need to allocate a new session in order to store incoming data.
129
160
session .conn [u .Chunkstart .Chunkid ] = connData {chunkSize : u .Chunkstart .Chunksize , packets : make (map [int32 ]string )}
130
161
162
+
131
163
case * protocol.Message_Chunkdata :
132
164
// Get the storage associated to the chunkId.
133
165
connection := session .getChunk (u .Chunkdata .Chunkid )
134
166
167
+ // Some DNS Servers will send multiple DNS queries, ignore duplicates.
168
+ _ , valid := connection .packets [u .Chunkdata .Chunknum ]
169
+ if valid {
170
+ log .Printf ("Ignoring duplicated Chunkdata : %v\n " , u .Chunkdata )
171
+ break
172
+ }
173
+
135
174
// Store the data packet.
136
175
connection .packets [u .Chunkdata .Chunknum ] = string (u .Chunkdata .Packet )
137
176
@@ -151,6 +190,7 @@ func parseQuery(m *dns.Msg) {
151
190
}
152
191
}
153
192
193
+
154
194
default :
155
195
fmt .Printf ("Unknown message type received : %v\n " , u )
156
196
}
@@ -198,6 +238,7 @@ func main() {
198
238
}
199
239
}()
200
240
241
+ // Timeout checking loop
201
242
go func () {
202
243
for {
203
244
time .Sleep (1 * time .Second )
@@ -214,6 +255,21 @@ func main() {
214
255
}
215
256
}()
216
257
258
+ // Poll-cache cleaner
259
+ go func () {
260
+ for {
261
+ time .Sleep (1 * time .Second )
262
+ now := time .Now ()
263
+ for pollData , cache := range pollCache {
264
+ if cache .lastseen + 10 < now .Unix () {
265
+ logging .Printf ("Dropping cached poll query : %v\n " , pollData )
266
+ // Delete from poll cache list.
267
+ delete (pollCache , pollData )
268
+ }
269
+ }
270
+ }
271
+ }()
272
+
217
273
p := prompt .New (executor , Completer , prompt .OptionPrefix ("chashell >>> " ))
218
274
p .Run ()
219
275
}
0 commit comments