+ if (c->ssh->throttled_all ||
+ (c->ssh->version == 2 && c->v.v2.remwindow == 0))
+ return;
+
+ if (c->closes & CLOSES_SENT_EOF) {
+ /*
+ * If we've already sent outgoing EOF, there's nothing we can
+ * do with incoming data except consume it and throw it away.
+ */
+ bufchain_clear(&c->u.a.inbuffer);
+ return;
+ }
+
+ while (1) {
+ /*
+ * Try to extract a complete message from the input buffer.
+ */
+ datalen = bufchain_size(&c->u.a.inbuffer);
+ if (datalen < 4)
+ break; /* not even a length field available yet */
+
+ bufchain_fetch(&c->u.a.inbuffer, msglen, 4);
+ lengthfield = GET_32BIT(msglen);
+
+ if (lengthfield > AGENT_MAX_MSGLEN) {
+ /*
+ * If the remote has sent a message that's just _too_
+ * long, we should reject it in advance of seeing the rest
+ * of the incoming message, and also close the connection
+ * for good measure (which avoids us having to faff about
+ * with carefully ignoring just the right number of bytes
+ * from the overlong message).
+ */
+ ssh_agentf_got_response(c, NULL, 0);
+ sshfwd_write_eof(c);
+ return;
+ }
+
+ if (lengthfield > datalen - 4)
+ break; /* a whole message is not yet available */
+
+ messagelen = lengthfield + 4;
+
+ message = snewn(messagelen, unsigned char);
+ bufchain_fetch(&c->u.a.inbuffer, message, messagelen);
+ bufchain_consume(&c->u.a.inbuffer, messagelen);
+ c->u.a.pending = agent_query(
+ message, messagelen, &reply, &replylen, ssh_agentf_callback, c);
+ sfree(message);
+
+ if (c->u.a.pending)
+ return; /* agent_query promised to reply in due course */
+
+ /*
+ * If the agent gave us an answer immediately, pass it
+ * straight on and go round this loop again.
+ */
+ ssh_agentf_got_response(c, reply, replylen);
+ sfree(reply);
+ }
+
+ /*
+ * If we get here (i.e. we left the above while loop via 'break'
+ * rather than 'return'), that means we've determined that the
+ * input buffer for the agent forwarding connection doesn't
+ * contain a complete request.
+ *
+ * So if there's potentially more data to come, we can return now,
+ * and wait for the remote client to send it. But if the remote
+ * has sent EOF, it would be a mistake to do that, because we'd be
+ * waiting a long time. So this is the moment to check for EOF,
+ * and respond appropriately.
+ */
+ if (c->closes & CLOSES_RCVD_EOF)