1 /* $OpenBSD: roaming_common.c,v 1.5 2009/06/27 09:32:43 andreas Exp $ */
3 * Copyright (c) 2004-2009 AppGate Network Security AB
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/types.h>
21 #include <sys/socket.h>
25 #ifdef HAVE_INTTYPES_H
40 static size_t out_buf_size
= 0;
41 static char *out_buf
= NULL
;
42 static size_t out_start
;
43 static size_t out_last
;
45 static u_int64_t write_bytes
= 0;
46 static u_int64_t read_bytes
= 0;
48 int roaming_enabled
= 0;
49 int resume_in_progress
= 0;
54 int fd
= packet_get_connection_out();
55 int optval
, optvallen
;
57 optvallen
= sizeof(optval
);
58 if (getsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &optval
, &optvallen
) != 0)
59 optval
= DEFAULT_ROAMBUF
;
66 int fd
= packet_get_connection_in();
67 int optval
, optvallen
;
69 optvallen
= sizeof(optval
);
70 if (getsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &optval
, &optvallen
) != 0)
71 optval
= DEFAULT_ROAMBUF
;
76 set_out_buffer_size(size_t size
)
79 * The buffer size can only be set once and the buffer will live
80 * as long as the session lives.
82 if (out_buf
== NULL
) {
84 out_buf
= xmalloc(size
);
97 add_recv_bytes(u_int64_t num
)
109 roam_set_bytes(u_int64_t sent
, u_int64_t recvd
)
116 buf_append(const char *buf
, size_t count
)
118 if (count
> out_buf_size
) {
119 buf
+= count
- out_buf_size
;
120 count
= out_buf_size
;
122 if (count
< out_buf_size
- out_last
) {
123 memcpy(out_buf
+ out_last
, buf
, count
);
124 if (out_start
> out_last
)
129 size_t chunk
= out_buf_size
- out_last
;
130 memcpy(out_buf
+ out_last
, buf
, chunk
);
131 memcpy(out_buf
, buf
+ chunk
, count
- chunk
);
132 out_last
= count
- chunk
;
133 out_start
= out_last
+ 1;
138 roaming_write(int fd
, const void *buf
, size_t count
, int *cont
)
142 ret
= write(fd
, buf
, count
);
143 if (ret
> 0 && !resume_in_progress
) {
145 if (out_buf_size
> 0)
146 buf_append(buf
, ret
);
148 debug3("Wrote %ld bytes for a total of %llu", (long)ret
,
149 (unsigned long long)write_bytes
);
154 roaming_read(int fd
, void *buf
, size_t count
, int *cont
)
156 ssize_t ret
= read(fd
, buf
, count
);
158 if (!resume_in_progress
) {
166 roaming_atomicio(ssize_t(*f
)(int, void*, size_t), int fd
, void *buf
,
169 size_t ret
= atomicio(f
, fd
, buf
, count
);
171 if (f
== vwrite
&& ret
> 0 && !resume_in_progress
) {
173 } else if (f
== read
&& ret
> 0 && !resume_in_progress
) {
180 resend_bytes(int fd
, u_int64_t
*offset
)
182 size_t available
, needed
;
184 if (out_start
< out_last
)
185 available
= out_last
- out_start
;
187 available
= out_buf_size
;
188 needed
= write_bytes
- *offset
;
189 debug3("resend_bytes: resend %lu bytes from %llu",
190 (unsigned long)needed
, (unsigned long long)*offset
);
191 if (needed
> available
)
192 fatal("Needed to resend more data than in the cache");
193 if (out_last
< needed
) {
194 int chunkend
= needed
- out_last
;
195 atomicio(vwrite
, fd
, out_buf
+ out_buf_size
- chunkend
,
197 atomicio(vwrite
, fd
, out_buf
, out_last
);
199 atomicio(vwrite
, fd
, out_buf
+ (out_last
- needed
), needed
);