11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: roaming_common.c,v 1.8 2010/01/12 00:59:29 djm Exp $ */
21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2004-2009 AppGate Network Security AB
41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Permission to use, copy, modify, and distribute this software for any
61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * purpose with or without fee is hereby granted, provided that the above
71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * copyright notice and this permission notice appear in all copies.
81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h"
191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h>
211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h>
221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/uio.h>
231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h>
251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_INTTYPES_H
261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <inttypes.h>
271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h>
291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h>
301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h>
311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "atomicio.h"
331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h"
341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h"
351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h"
361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h"
371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h"
381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "roaming.h"
391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic size_t out_buf_size = 0;
411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *out_buf = NULL;
421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic size_t out_start;
431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic size_t out_last;
441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic u_int64_t write_bytes = 0;
461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic u_int64_t read_bytes = 0;
471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint roaming_enabled = 0;
491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint resume_in_progress = 0;
501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodget_snd_buf_size()
531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int fd = packet_get_connection_out();
551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int optval;
561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	socklen_t optvallen = sizeof(optval);
571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optvallen) != 0)
591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		optval = DEFAULT_ROAMBUF;
601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return optval;
611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodget_recv_buf_size()
651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int fd = packet_get_connection_in();
671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int optval;
681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	socklen_t optvallen = sizeof(optval);
691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, &optvallen) != 0)
711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		optval = DEFAULT_ROAMBUF;
721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return optval;
731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodset_out_buffer_size(size_t size)
771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * The buffer size can only be set once and the buffer will live
801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * as long as the session lives.
811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (out_buf == NULL) {
831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		out_buf_size = size;
841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		out_buf = xmalloc(size);
851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		out_start = 0;
861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		out_last = 0;
871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int64_t
911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodget_recv_bytes(void)
921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return read_bytes;
941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodadd_recv_bytes(u_int64_t num)
981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	read_bytes += num;
1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int64_t
1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodget_sent_bytes(void)
1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return write_bytes;
1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodroam_set_bytes(u_int64_t sent, u_int64_t recvd)
1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	read_bytes = recvd;
1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	write_bytes = sent;
1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodbuf_append(const char *buf, size_t count)
1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (count > out_buf_size) {
1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buf += count - out_buf_size;
1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		count = out_buf_size;
1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (count < out_buf_size - out_last) {
1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		memcpy(out_buf + out_last, buf, count);
1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (out_start > out_last)
1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			out_start += count;
1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		out_last += count;
1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* data will wrap */
1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		size_t chunk = out_buf_size - out_last;
1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		memcpy(out_buf + out_last, buf, chunk);
1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		memcpy(out_buf, buf + chunk, count - chunk);
1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		out_last = count - chunk;
1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		out_start = out_last + 1;
1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssize_t
1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodroaming_write(int fd, const void *buf, size_t count, int *cont)
1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ssize_t ret;
1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ret = write(fd, buf, count);
1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (ret > 0 && !resume_in_progress) {
1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		write_bytes += ret;
1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (out_buf_size > 0)
1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			buf_append(buf, ret);
1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (out_buf_size > 0 &&
1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (ret == 0 || (ret == -1 && errno == EPIPE))) {
1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (wait_for_roaming_reconnect() != 0) {
1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			ret = 0;
1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*cont = 1;
1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else {
1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			ret = -1;
1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			errno = EAGAIN;
1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return ret;
1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssize_t
1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodroaming_read(int fd, void *buf, size_t count, int *cont)
1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ssize_t ret = read(fd, buf, count);
1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (ret > 0) {
1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!resume_in_progress) {
1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			read_bytes += ret;
1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else if (out_buf_size > 0 &&
1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (ret == 0 || (ret == -1 && (errno == ECONNRESET
1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    || errno == ECONNABORTED || errno == ETIMEDOUT
1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    || errno == EHOSTUNREACH)))) {
1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("roaming_read failed for %d  ret=%ld  errno=%d",
1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    fd, (long)ret, errno);
1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ret = 0;
1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (wait_for_roaming_reconnect() == 0)
1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*cont = 1;
1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return ret;
1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsize_t
1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodroaming_atomicio(ssize_t(*f)(int, void*, size_t), int fd, void *buf,
1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    size_t count)
1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	size_t ret = atomicio(f, fd, buf, count);
1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (f == vwrite && ret > 0 && !resume_in_progress) {
1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		write_bytes += ret;
1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else if (f == read && ret > 0 && !resume_in_progress) {
1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		read_bytes += ret;
1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return ret;
1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodresend_bytes(int fd, u_int64_t *offset)
1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	size_t available, needed;
2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (out_start < out_last)
2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		available = out_last - out_start;
2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		available = out_buf_size;
2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	needed = write_bytes - *offset;
2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug3("resend_bytes: resend %lu bytes from %llu",
2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (unsigned long)needed, (unsigned long long)*offset);
2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (needed > available)
2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("Needed to resend more data than in the cache");
2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (out_last < needed) {
2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		int chunkend = needed - out_last;
2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		atomicio(vwrite, fd, out_buf + out_buf_size - chunkend,
2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    chunkend);
2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		atomicio(vwrite, fd, out_buf, out_last);
2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		atomicio(vwrite, fd, out_buf + (out_last - needed), needed);
2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Caclulate a new key after a reconnect
2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcalculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const EVP_MD *md = EVP_sha1();
2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	EVP_MD_CTX ctx;
2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char hash[EVP_MAX_MD_SIZE];
2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Buffer b;
2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_init(&b);
2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_int64(&b, *key);
2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_int64(&b, cookie);
2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_int64(&b, challenge);
2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	EVP_DigestInit(&ctx, md);
2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	EVP_DigestUpdate(&ctx, buffer_ptr(&b), buffer_len(&b));
2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	EVP_DigestFinal(&ctx, hash, NULL);
2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_clear(&b);
2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_append(&b, hash, EVP_MD_size(md));
2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	*key = buffer_get_int64(&b);
2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_free(&b);
2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
245