aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Ashby <martin@ashbysoft.com>2023-11-12 09:07:50 +0000
committerMartin Ashby <martin@ashbysoft.com>2023-11-12 09:07:50 +0000
commit536837b44823aedf3dab0b8ef844d57cbae7af74 (patch)
tree3c19f7757af9f7112ec02f320ae4cd40bfab5b89
parente3c5be0a33e66b124ff261479cffa9f95ce53dc0 (diff)
downloadzbt-536837b44823aedf3dab0b8ef844d57cbae7af74.tar.gz
zbt-536837b44823aedf3dab0b8ef844d57cbae7af74.tar.bz2
zbt-536837b44823aedf3dab0b8ef844d57cbae7af74.tar.xz
zbt-536837b44823aedf3dab0b8ef844d57cbae7af74.zip
Handshake a peer
-rw-r--r--src/main.zig31
-rw-r--r--src/peer_protocol.zig26
2 files changed, 54 insertions, 3 deletions
diff --git a/src/main.zig b/src/main.zig
index 9966a55..d50cc90 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,8 +1,15 @@
const std = @import("std");
const MetaInfo = @import("metainfo.zig");
const bencode = @import("bencode.zig");
+const AnyWriter = @import("anywriter.zig");
+const peerproto = @import("peer_protocol.zig");
+
+const prr = "00112233445566778899";
pub fn main() !void {
+ var peer_id: [20]u8 = undefined;
+ @memcpy(&peer_id, prr);
+
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const a = gpa.allocator();
@@ -27,7 +34,7 @@ pub fn main() !void {
var info_hash = try mi.info.hash(a);
var buf_left = [_]u8{0} ** 1024;
try q.put("info_hash", &info_hash);
- try q.put("peer_id", "00112233445566778899");
+ try q.put("peer_id", &peer_id);
try q.put("port", "6881");
try q.put("uploaded", "0");
try q.put("downloaded", "0");
@@ -44,10 +51,27 @@ pub fn main() !void {
defer trb.deinit(a);
var tr = try TrackerResp.parse(a, trb);
defer tr.deinit(a);
- var w = std.io.getStdOut().writer();
+
for (tr.peers) |peer| {
- try std.fmt.format(w, "peer: {}\n", .{peer});
+ std.log.info("peer: {}", .{peer});
}
+
+ // Handle peers...
+
+
+ const p = tr.peers[0];
+ var ps = try std.net.tcpConnectToAddress(p);
+ defer ps.close();
+ var pw = ps.writer();
+ var pr = ps.reader();
+ var hs: peerproto.Handshake = .{
+ .info_hash = info_hash,
+ .peer_id = peer_id,
+ };
+
+ try hs.write(pw);
+ var phs = try peerproto.Handshake.read(pr);
+ std.log.info("peer at {} peer_id {s}", .{ p, std.fmt.fmtSliceHexLower(&phs.peer_id) });
}
}
@@ -95,6 +119,7 @@ const TrackerResp = struct {
}
};
+
test {
_ = bencode;
_ = MetaInfo;
diff --git a/src/peer_protocol.zig b/src/peer_protocol.zig
new file mode 100644
index 0000000..cd70ad2
--- /dev/null
+++ b/src/peer_protocol.zig
@@ -0,0 +1,26 @@
+const std = @import("std");
+
+pub const Handshake = struct {
+ info_hash: [20]u8,
+ peer_id: [20]u8,
+
+ pub fn read(reader: anytype) !Handshake {
+ var msg = [_]u8{0} ** 68;
+ try reader.readNoEof(&msg);
+ if (msg[0] != 19) return error.ProtocolError;
+ if (!std.mem.eql(u8, msg[1..20], "BitTorrent protocol")) return error.ProtocolError;
+ //if (!std.mem.allEqual(u8, msg[20..28], 0)) return error.ProtocolError;
+ var res: Handshake = undefined;
+ @memcpy(&res.info_hash, msg[28..48]);
+ @memcpy(&res.peer_id, msg[48..68]);
+ return res;
+ }
+
+ pub fn write(self: Handshake, writer: anytype) !void {
+ try writer.writeByte(19);
+ try writer.writeAll("BitTorrent protocol");
+ try writer.writeByteNTimes(0, 8);
+ try writer.writeAll(&self.info_hash);
+ try writer.writeAll(&self.peer_id);
+ }
+};