No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / external / bsd / openssh / dist / roaming_common.c
blob0a1eebaf951f633e5a130cae0cd173989d208246
1 /* $NetBSD: roaming_common.c,v 1.1.1.1 2009/12/27 01:07:02 christos Exp $ */
2 /* $OpenBSD: roaming_common.c,v 1.5 2009/06/27 09:32:43 andreas Exp $ */
3 /*
4 * Copyright (c) 2004-2009 AppGate Network Security AB
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include "includes.h"
19 __RCSID("$NetBSD$");
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/uio.h>
25 #include <errno.h>
26 #include <inttypes.h>
27 #include <stdarg.h>
28 #include <string.h>
29 #include <unistd.h>
31 #include "atomicio.h"
32 #include "log.h"
33 #include "packet.h"
34 #include "xmalloc.h"
35 #include "cipher.h"
36 #include "buffer.h"
37 #include "roaming.h"
39 static size_t out_buf_size = 0;
40 static char *out_buf = NULL;
41 static size_t out_start;
42 static size_t out_last;
44 static u_int64_t write_bytes = 0;
45 static u_int64_t read_bytes = 0;
47 int roaming_enabled = 0;
48 int resume_in_progress = 0;
50 int
51 get_snd_buf_size()
53 int fd = packet_get_connection_out();
54 int optval;
55 socklen_t optvallen;
57 optvallen = sizeof(optval);
58 if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optvallen) != 0)
59 optval = DEFAULT_ROAMBUF;
60 return optval;
63 int
64 get_recv_buf_size()
66 int fd = packet_get_connection_in();
67 int optval;
68 socklen_t optvallen;
70 optvallen = sizeof(optval);
71 if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, &optvallen) != 0)
72 optval = DEFAULT_ROAMBUF;
73 return optval;
76 void
77 set_out_buffer_size(size_t size)
80 * The buffer size can only be set once and the buffer will live
81 * as long as the session lives.
83 if (out_buf == NULL) {
84 out_buf_size = size;
85 out_buf = xmalloc(size);
86 out_start = 0;
87 out_last = 0;
91 u_int64_t
92 get_recv_bytes(void)
94 return read_bytes;
97 void
98 add_recv_bytes(u_int64_t num)
100 read_bytes += num;
103 u_int64_t
104 get_sent_bytes(void)
106 return write_bytes;
109 void
110 roam_set_bytes(u_int64_t sent, u_int64_t recvd)
112 read_bytes = recvd;
113 write_bytes = sent;
116 static void
117 buf_append(const char *buf, size_t count)
119 if (count > out_buf_size) {
120 buf += count - out_buf_size;
121 count = out_buf_size;
123 if (count < out_buf_size - out_last) {
124 memcpy(out_buf + out_last, buf, count);
125 if (out_start > out_last)
126 out_start += count;
127 out_last += count;
128 } else {
129 /* data will wrap */
130 size_t chunk = out_buf_size - out_last;
131 memcpy(out_buf + out_last, buf, chunk);
132 memcpy(out_buf, buf + chunk, count - chunk);
133 out_last = count - chunk;
134 out_start = out_last + 1;
138 ssize_t
139 roaming_write(int fd, const void *buf, size_t count, int *cont)
141 ssize_t ret;
143 ret = write(fd, buf, count);
144 if (ret > 0 && !resume_in_progress) {
145 write_bytes += ret;
146 if (out_buf_size > 0)
147 buf_append(buf, ret);
149 debug3("Wrote %ld bytes for a total of %llu", (long)ret,
150 (unsigned long long)write_bytes);
151 return ret;
154 ssize_t
155 roaming_read(int fd, void *buf, size_t count, int *cont)
157 ssize_t ret = read(fd, buf, count);
158 if (ret > 0) {
159 if (!resume_in_progress) {
160 read_bytes += ret;
163 return ret;
166 size_t
167 roaming_atomicio(ssize_t(*f)(int, void*, size_t), int fd, void *buf,
168 size_t count)
170 size_t ret = atomicio(f, fd, buf, count);
172 if (f == vwrite && ret > 0 && !resume_in_progress) {
173 write_bytes += ret;
174 } else if (f == read && ret > 0 && !resume_in_progress) {
175 read_bytes += ret;
177 return ret;
180 void
181 resend_bytes(int fd, u_int64_t *offset)
183 size_t available, needed;
185 if (out_start < out_last)
186 available = out_last - out_start;
187 else
188 available = out_buf_size;
189 needed = write_bytes - *offset;
190 debug3("resend_bytes: resend %lu bytes from %llu",
191 (unsigned long)needed, (unsigned long long)*offset);
192 if (needed > available)
193 fatal("Needed to resend more data than in the cache");
194 if (out_last < needed) {
195 int chunkend = needed - out_last;
196 atomicio(vwrite, fd, out_buf + out_buf_size - chunkend,
197 chunkend);
198 atomicio(vwrite, fd, out_buf, out_last);
199 } else {
200 atomicio(vwrite, fd, out_buf + (out_last - needed), needed);