- andreas@cvs.openbsd.org 2009/10/24 11:22:37
     [roaming_common.c]
     Do the actual suspend/resume in the client. This won't be useful until
     the server side supports roaming.
     Most code from Martin Forssen, maf at appgate dot com. Some changes by
     me and markus@
     ok markus@
diff --git a/roaming_common.c b/roaming_common.c
index 73db09d..272dead 100644
--- a/roaming_common.c
+++ b/roaming_common.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roaming_common.c,v 1.5 2009/06/27 09:32:43 andreas Exp $ */
+/* $OpenBSD: roaming_common.c,v 1.6 2009/10/24 11:22:37 andreas Exp $ */
 /*
  * Copyright (c) 2004-2009 AppGate Network Security AB
  *
@@ -147,6 +147,16 @@
 	}
 	debug3("Wrote %ld bytes for a total of %llu", (long)ret,
 	    (unsigned long long)write_bytes);
+	if (out_buf_size > 0 &&
+	    (ret == 0 || (ret == -1 && errno == EPIPE))) {
+		if (wait_for_roaming_reconnect() != 0) {
+			ret = 0;
+			*cont = 1;
+		} else {
+			ret = -1;
+			errno = EAGAIN;
+		}
+	}
 	return ret;
 }
 
@@ -158,6 +168,15 @@
 		if (!resume_in_progress) {
 			read_bytes += ret;
 		}
+	} else if (out_buf_size > 0 &&
+	    (ret == 0 || (ret == -1 && (errno == ECONNRESET
+	    || errno == ECONNABORTED || errno == ETIMEDOUT
+	    || errno == EHOSTUNREACH)))) {
+		debug("roaming_read failed for %d  ret=%ld  errno=%d",
+		    fd, (long)ret, errno);
+		ret = 0;
+		if (wait_for_roaming_reconnect() == 0)
+			*cont = 1;
 	}
 	return ret;
 }
@@ -199,3 +218,29 @@
 		atomicio(vwrite, fd, out_buf + (out_last - needed), needed);
 	}
 }
+
+/*
+ * Caclulate a new key after a reconnect
+ */
+void
+calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
+{
+	const EVP_MD *md = EVP_sha1();
+	EVP_MD_CTX ctx;
+	char hash[EVP_MAX_MD_SIZE];
+	Buffer b;
+
+	buffer_init(&b);
+	buffer_put_int64(&b, *key);
+	buffer_put_int64(&b, cookie);
+	buffer_put_int64(&b, challenge);
+
+	EVP_DigestInit(&ctx, md);
+	EVP_DigestUpdate(&ctx, buffer_ptr(&b), buffer_len(&b));
+	EVP_DigestFinal(&ctx, hash, NULL);
+
+	buffer_clear(&b);
+	buffer_append(&b, hash, EVP_MD_size(md));
+	*key = buffer_get_int64(&b);
+	buffer_free(&b);
+}