tangled
alpha
login
or
join now
altagos.dev
/
aether
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
read qname
altagos.dev
7 months ago
2d806558
b7753e96
verified
This commit was signed with the committer's
known signature
.
altagos.dev
SSH Key Fingerprint:
SHA256:UbTjEcCZlc6GzQWLCuDK3D//HESWD2xFPkzue9XMras=
+101
-3
1 changed file
expand all
collapse all
unified
split
src
root.zig
+101
-3
src/root.zig
···
45
45
}
46
46
47
47
/// Get a range of bytes
48
48
-
pub fn get_range(self: *const BytePacketBuffer, start: usize, len: usize) ReadError![]const u8 {
48
48
+
pub fn getRange(self: *const BytePacketBuffer, start: usize, len: usize) ReadError![]const u8 {
49
49
if (start + len >= comptime self.buf.len) return ReadError.EndOfBuffer;
50
50
return self.buf[start .. start + len];
51
51
}
···
55
55
/// The tricky part: Reading domain names, taking labels into consideration.
56
56
/// Will take something like [3]www[6]google[3]com and append
57
57
/// www.google.com to outstr.
58
58
-
pub fn read_qname(self: *BytePacketBuffer, outstr: []u8) ReadError!void {
58
58
+
pub fn readQname(self: *BytePacketBuffer, outstr: []u8) ReadError!void {
59
59
// We might encounter jumps, therefore we need to keep thrack of our position locally
60
60
var pos = self.pos;
61
61
var out_pos: usize = 0;
···
115
115
116
116
if (!jumped) self.seek(1);
117
117
}
118
118
+
119
119
+
/// Read a qname
120
120
+
///
121
121
+
/// The tricky part: Reading domain names, taking labels into consideration.
122
122
+
/// Will take something like [3]www[6]google[3]com and append
123
123
+
/// www.google.com to outstr.
124
124
+
pub fn readQnameAlloc(self: *BytePacketBuffer, alloc: std.mem.Allocator) ![]u8 {
125
125
+
var buffer: std.ArrayList(u8) = .init(alloc);
126
126
+
127
127
+
// We might encounter jumps, therefore we need to keep thrack of our position locally
128
128
+
var pos = self.pos;
129
129
+
130
130
+
// track whether or nor we've jumped
131
131
+
var jumped = false;
132
132
+
const max_jumps: usize = 5;
133
133
+
var jumps_performed: usize = 0;
134
134
+
135
135
+
var delim: ?[]const u8 = null;
136
136
+
while (true) {
137
137
+
if (jumps_performed > max_jumps) return ReadError.JumpLimitExceeded;
138
138
+
139
139
+
// Each label starts with a length byte
140
140
+
const len = try self.get(pos);
141
141
+
142
142
+
// If len has the two most signigicant bit set, it represents a jump to some other
143
143
+
// offset in the packet:
144
144
+
if ((len & 0xC0) == 0xC0) {
145
145
+
// Update the buffer position to a point past the current label
146
146
+
if (!jumped) self.seek(2);
147
147
+
148
148
+
// Read another byte, calculate offset and performe the jump by updating our
149
149
+
// local position variable
150
150
+
const b2 = @as(u16, try self.get(pos + 1));
151
151
+
const offset = ((@as(u16, len) ^ 0xC0) << 8) | b2;
152
152
+
pos = @as(usize, offset);
153
153
+
154
154
+
// Indicate that a jump was performed
155
155
+
jumped = true;
156
156
+
jumps_performed += 1;
157
157
+
158
158
+
continue;
159
159
+
} else {
160
160
+
// Move a single byte forward to move path the length
161
161
+
self.pos += 1;
162
162
+
pos += 1;
163
163
+
164
164
+
// Domain names are terminated by an empty label of length 0, so if the length
165
165
+
// is zero we're done
166
166
+
if (len == 0) break;
167
167
+
168
168
+
if (delim) |del| {
169
169
+
try buffer.appendSlice(del);
170
170
+
}
171
171
+
172
172
+
try buffer.appendSlice(try self.getRange(pos, len));
173
173
+
174
174
+
delim = ".";
175
175
+
176
176
+
pos += len;
177
177
+
}
178
178
+
}
179
179
+
180
180
+
if (!jumped) self.seek(1);
181
181
+
182
182
+
return buffer.toOwnedSlice();
183
183
+
}
118
184
};
119
185
120
186
test "BytePacketBuffer.read" {
···
182
248
const outstr = try allocator.alloc(u8, expected.len);
183
249
defer allocator.free(outstr);
184
250
185
185
-
try buf.read_qname(outstr);
251
251
+
try buf.readQname(outstr);
186
252
187
253
try testing.expectEqualStrings(expected, outstr);
188
254
}
255
255
+
256
256
+
test "BytePacketBuffer.read_qname_alloc google.com" {
257
257
+
const testing = std.testing;
258
258
+
const allocator = testing.allocator;
259
259
+
260
260
+
const input = [_]u8{
261
261
+
0x06, // [6]
262
262
+
0x67, // g
263
263
+
0x6f, // o
264
264
+
0x6f, // o
265
265
+
0x67, // g
266
266
+
0x6c, // l
267
267
+
0x65, // e
268
268
+
0x03, // [3]
269
269
+
0x63, // c
270
270
+
0x6f, // o
271
271
+
0x6d, // m
272
272
+
0x00, // [0]
273
273
+
};
274
274
+
const expected = "google.com";
275
275
+
276
276
+
var buf = BytePacketBuffer{};
277
277
+
for (input, 0..) |char, idx| {
278
278
+
buf.buf[idx] = char;
279
279
+
}
280
280
+
281
281
+
const outstr = try buf.readQnameAlloc(allocator);
282
282
+
defer allocator.free(outstr);
283
283
+
284
284
+
try testing.expectEqualStrings(expected, outstr);
285
285
+
}
286
286
+