diff options
author | Martin Ashby <martin@ashbysoft.com> | 2023-11-12 09:07:50 +0000 |
---|---|---|
committer | Martin Ashby <martin@ashbysoft.com> | 2023-11-12 09:07:50 +0000 |
commit | 536837b44823aedf3dab0b8ef844d57cbae7af74 (patch) | |
tree | 3c19f7757af9f7112ec02f320ae4cd40bfab5b89 | |
parent | e3c5be0a33e66b124ff261479cffa9f95ce53dc0 (diff) | |
download | zbt-536837b44823aedf3dab0b8ef844d57cbae7af74.tar.gz zbt-536837b44823aedf3dab0b8ef844d57cbae7af74.tar.bz2 zbt-536837b44823aedf3dab0b8ef844d57cbae7af74.tar.xz zbt-536837b44823aedf3dab0b8ef844d57cbae7af74.zip |
Handshake a peer
-rw-r--r-- | src/main.zig | 31 | ||||
-rw-r--r-- | src/peer_protocol.zig | 26 |
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); + } +}; |