+ if (c->u.a.pending)
+ return;
+
+ /*
+ * If the outgoing side of the channel connection is currently
+ * throttled (for any reason, either that channel's window size or
+ * the entire SSH connection being throttled), don't submit any
+ * new forwarded requests to the real agent. This causes the input
+ * side of the agent forwarding not to be emptied, exerting the
+ * required back-pressure on the remote client, and encouraging it
+ * to read our responses before sending too many more requests.
+ */
+ if (c->ssh->throttled_all ||
+ (c->ssh->version == 2 && c->v.v2.remwindow == 0))
+ 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 > 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);
+ }
+
+ /*
+ * 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)