╭ changed ─────────────────╮ │src/serve_ssh_protocol.zig│ ╰──────────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────╮ │393 try close.append(self.allocator, SSH_MSG_CHANNEL_CLOSE); │ │394 try writeU32(&close, self.allocator, self.channel.remote_id); │ │405 - try self.sc_cipher.writePacket(self.io, self.allocator, self.writer, close.items);│ │395 + try self.sc_cipher.writePacket(self.io, self.writer, close.items); │ │396 │ │397 // read and discard until the peer closes (TCP FIN) before letting the │ │398 // caller close the socket. a git client, after our CHANNEL_CLOSE, still │ ╰───────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │492 const self: *SessionReader = @fieldParentPtr("interface", r); │ │493 │ │494 // wait for data to arrive (or EOF) │ │505 - while (self.sess.incoming_buffer.items.len == 0) { │ │495 + while (self.sess.incomingBytes().len == 0) { │ │496 if (self.sess.incoming_eof) return error.EndOfStream; │ │497 self.sess.processOneBackgroundPacket() catch return error.ReadFailed;│ │498 } │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │499 │ │510 - // drain as much of incoming_buffer as the limit allows, in one go │ │511 - const chunk = limit.sliceConst(self.sess.incoming_buffer.items); │ │500 + // drain as much buffered input as the limit allows, in one go │ │501 + const chunk = limit.sliceConst(self.sess.incomingBytes()); │ │502 const written = try w.write(chunk); │ │503 │ │514 - std.mem.copyForwards(u8, self.sess.incoming_buffer.items, self.sess.incoming_buffer.items[written..]);│ │515 - self.sess.incoming_buffer.shrinkRetainingCapacity(self.sess.incoming_buffer.items.len - written); │ │504 + self.sess.consumeIncoming(written); │ │505 self.sess.maybeRefillRecvWindowForBufferedInput() catch return error.ReadFailed; │ │506 │ │507 return written; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │510 fn readVec(r: *std.Io.Reader, data: [][]u8) std.Io.Reader.Error!usize { │ │511 const self: *SessionReader = @fieldParentPtr("interface", r); │ │512 │ │524 - // wait until something is in incoming_buffer (or EOF) │ │525 - while (self.sess.incoming_buffer.items.len == 0) { │ │513 + // wait until some input is buffered (or EOF) │ │514 + while (self.sess.incomingBytes().len == 0) { │ │515 if (self.sess.incoming_eof) return error.EndOfStream; │ │516 self.sess.processOneBackgroundPacket() catch return error.ReadFailed;│ │517 } │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │518 │ │530 - const src = self.sess.incoming_buffer.items; │ │519 + const src = self.sess.incomingBytes(); │ │520 │ │521 // vtable.readVec contract: if data[0] is empty, write into r.buffer│ │522 // instead and return 0. without this branch the caller spins, │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────╮ │527 const copy = @min(dest.len, src.len); │ │528 @memcpy(dest[0..copy], src[0..copy]); │ │529 r.end += copy; │ │541 - std.mem.copyForwards(u8, self.sess.incoming_buffer.items, src[copy..]); │ │542 - self.sess.incoming_buffer.shrinkRetainingCapacity(src.len - copy); │ │530 + self.sess.consumeIncoming(copy); │ │531 self.sess.maybeRefillRecvWindowForBufferedInput() catch return error.ReadFailed;│ │532 return 0; │ │533 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────╮ │535 const dest = data[0]; │ │536 const copy = @min(dest.len, src.len); │ │537 @memcpy(dest[0..copy], src[0..copy]); │ │550 - std.mem.copyForwards(u8, self.sess.incoming_buffer.items, src[copy..]); │ │551 - self.sess.incoming_buffer.shrinkRetainingCapacity(src.len - copy); │ │538 + self.sess.consumeIncoming(copy); │ │539 self.sess.maybeRefillRecvWindowForBufferedInput() catch return error.ReadFailed;│ │540 return copy; │ │541 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │674 } │ │675 } │ │676 │ │690 - fn writePacket(self: KexTransport, io: std.Io, allocator: std.mem.Allocator, writer: *std.Io.Writer, payload: []const u8) !void {│ │677 + fn writePacket(self: KexTransport, io: std.Io, writer: *std.Io.Writer, payload: []const u8) !void { │ │678 switch (self) { │ │679 .plain => try writePlainPacket(io, writer, payload), │ │693 - .encrypted => |ciphers| try ciphers.sc.writePacket(io, allocator, writer, payload), │ │680 + .encrypted => |ciphers| try ciphers.sc.writePacket(io, writer, payload), │ │681 } │ │682 } │ │683 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────╮ │966 ) !void { │ │967 const server_kex_init = try buildServerKexInit(io, allocator); │ │968 defer allocator.free(server_kex_init); │ │982 - try sc_cipher.writePacket(io, allocator, writer, server_kex_init);│ │969 + try sc_cipher.writePacket(io, writer, server_kex_init); │ │970 │ │971 const negotiated = try exchangeKeys( │ │972 io, │ ╰───────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────╮ │1108 try writeStringField(&reply, allocator, host_key_blob.items); │ │1109 try writeStringField(&reply, allocator, server_blob); │ │1110 try writeStringField(&reply, allocator, signature_blob.items); │ │1124 - try transport.writePacket(io, allocator, writer, reply.items); │ │1111 + try transport.writePacket(io, writer, reply.items); │ │1112 │ │1113 // NEWKEYS — both sides switch to the new keys after this is sent and│ │1114 // the peer's NEWKEYS is received. │ ╰───────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯