]> andersk Git - openssh.git/blobdiff - packet.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / packet.c
index 0e9993b5a278b4ef48fd5b15d441311807fdeca5..994e35b6df50f926455475e6121fa6a16c252a6c 100644 (file)
--- 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 @@ struct session_state {
        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)
@@ -1070,7 +1070,8 @@ packet_read_seqnr(u_int32_t *seqnr_p)
                        if ((ret = select(active_state->connection_in + 1, setp,
                            NULL, NULL, timeoutp)) >= 0)
                                break;
-                       if (errno != EAGAIN && errno != EINTR)
+                       if (errno != EAGAIN && errno != EINTR &&
+                           errno != EWOULDBLOCK)
                                break;
                        if (active_state->packet_timeout_ms == -1)
                                continue;
@@ -1643,7 +1644,8 @@ packet_write_poll(void)
                len = roaming_write(active_state->connection_out,
                    buffer_ptr(&active_state->output), len, &cont);
                if (len == -1) {
-                       if (errno == EINTR || errno == EAGAIN)
+                       if (errno == EINTR || errno == EAGAIN ||
+                           errno == EWOULDBLOCK)
                                return;
                        fatal("Write failed: %.100s", strerror(errno));
                }
@@ -1685,7 +1687,8 @@ packet_write_wait(void)
                        if ((ret = select(active_state->connection_out + 1,
                            NULL, setp, NULL, timeoutp)) >= 0)
                                break;
-                       if (errno != EAGAIN && errno != EINTR)
+                       if (errno != EAGAIN && errno != EINTR &&
+                           errno != EWOULDBLOCK)
                                break;
                        if (active_state->packet_timeout_ms == -1)
                                continue;
@@ -1887,3 +1890,50 @@ packet_get_newkeys(int mode)
 {
        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);
+       }
+}
This page took 0.096547 seconds and 4 git commands to generate.