+
+ 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);
+ }
+