- andreas@cvs.openbsd.org 2009/06/27 09:29:06
     [packet.h packet.c]
     packet_bacup_state() and packet_restore_state() will be used to
     temporarily save the current state ren resuming a suspended connection.
     ok markus@
diff --git a/ChangeLog b/ChangeLog
index 0f39fa2..93f6b8a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+ - (dtucker) OpenBSD CVS Sync
+   - andreas@cvs.openbsd.org 2009/06/27 09:29:06
+     [packet.h packet.c]
+     packet_bacup_state() and packet_restore_state() will be used to
+     temporarily save the current state ren resuming a suspended connection.
+     ok markus@
+
 20090622
  - (dtucker) OpenBSD CVS Sync
    - dtucker@cvs.openbsd.org 2009/06/22 05:39:28
diff --git a/packet.c b/packet.c
index 0e9993b..600e015 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.165 2009/06/12 20:58:32 andreas Exp $ */
+/* $OpenBSD: packet.c,v 1.166 2009/06/27 09:29:06 andreas Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -194,7 +194,7 @@
 	TAILQ_HEAD(, packet) outgoing;
 };
 
-static struct session_state *active_state;
+static struct session_state *active_state, *backup_state;
 
 static struct session_state *
 alloc_session_state(void)
@@ -1887,3 +1887,50 @@
 {
 	return (void *)active_state->newkeys[mode];
 }
+
+/*
+ * Save the state for the real connection, and use a separate state when
+ * resuming a suspended connection.
+ */
+void
+packet_backup_state(void)
+{
+	struct session_state *tmp;
+
+	close(active_state->connection_in);
+	active_state->connection_in = -1;
+	close(active_state->connection_out);
+	active_state->connection_out = -1;
+	if (backup_state)
+		tmp = backup_state;
+	else
+		tmp = alloc_session_state();
+	backup_state = active_state;
+	active_state = tmp;
+}
+
+/*
+ * Swap in the old state when resuming a connecion.
+ */
+void
+packet_restore_state(void)
+{
+	struct session_state *tmp;
+	void *buf;
+	u_int len;
+
+	tmp = backup_state;
+	backup_state = active_state;
+	active_state = tmp;
+	active_state->connection_in = backup_state->connection_in;
+	backup_state->connection_in = -1;
+	active_state->connection_out = backup_state->connection_out;
+	backup_state->connection_out = -1;
+	len = buffer_len(&backup_state->input);
+	if (len > 0) {
+		buf = buffer_ptr(&backup_state->input);
+		buffer_append(&active_state->input, buf, len);
+		buffer_clear(&backup_state->input);
+		add_recv_bytes(len);
+	}
+}
diff --git a/packet.h b/packet.h
index 265fcf2..33523d7 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.51 2009/05/27 06:36:07 andreas Exp $ */
+/* $OpenBSD: packet.h,v 1.52 2009/06/27 09:29:06 andreas Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -109,6 +109,9 @@
 int	 packet_need_rekeying(void);
 void	 packet_set_rekey_limit(u_int32_t);
 
+void	 packet_backup_state(void);
+void	 packet_restore_state(void);
+
 void	*packet_get_input(void);
 void	*packet_get_output(void);