+static void ssh_process_incoming_data(Ssh ssh,
+ unsigned char **data, int *datalen)
+{
+ struct Packet *pktin = ssh->s_rdpkt(ssh, data, datalen);
+ if (pktin) {
+ ssh->protocol(ssh, NULL, 0, pktin);
+ ssh_free_packet(pktin);
+ }
+}
+
+static void ssh_queue_incoming_data(Ssh ssh,
+ unsigned char **data, int *datalen)
+{
+ bufchain_add(&ssh->queued_incoming_data, *data, *datalen);
+ *data += *datalen;
+ *datalen = 0;
+}
+
+static void ssh_process_queued_incoming_data(Ssh ssh)
+{
+ void *vdata;
+ unsigned char *data;
+ int len, origlen;
+
+ while (!ssh->frozen && bufchain_size(&ssh->queued_incoming_data)) {
+ bufchain_prefix(&ssh->queued_incoming_data, &vdata, &len);
+ data = vdata;
+ origlen = len;
+
+ while (!ssh->frozen && len > 0)
+ ssh_process_incoming_data(ssh, &data, &len);
+
+ if (origlen > len)
+ bufchain_consume(&ssh->queued_incoming_data, origlen - len);
+ }
+}
+
+static void ssh_set_frozen(Ssh ssh, int frozen)
+{
+ sk_set_frozen(ssh->s, frozen);
+ ssh->frozen = frozen;
+}
+