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 $ */
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.
21 #include <sys/types.h>
22 #include <sys/socket.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;
53 int fd
= packet_get_connection_out();
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();
70 optvallen
= sizeof(optval
);
71 if (getsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &optval
, &optvallen
) != 0)
72 optval
= DEFAULT_ROAMBUF
;
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
) {
85 out_buf
= xmalloc(size
);
98 add_recv_bytes(u_int64_t num
)
110 roam_set_bytes(u_int64_t sent
, u_int64_t recvd
)
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
)
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;
139 roaming_write(int fd
, const void *buf
, size_t count
, int *cont
)
143 ret
= write(fd
, buf
, count
);
144 if (ret
> 0 && !resume_in_progress
) {
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
);
155 roaming_read(int fd
, void *buf
, size_t count
, int *cont
)
157 ssize_t ret
= read(fd
, buf
, count
);
159 if (!resume_in_progress
) {
167 roaming_atomicio(ssize_t(*f
)(int, void*, size_t), int fd
, void *buf
,
170 size_t ret
= atomicio(f
, fd
, buf
, count
);
172 if (f
== vwrite
&& ret
> 0 && !resume_in_progress
) {
174 } else if (f
== read
&& ret
> 0 && !resume_in_progress
) {
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
;
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
,
198 atomicio(vwrite
, fd
, out_buf
, out_last
);
200 atomicio(vwrite
, fd
, out_buf
+ (out_last
- needed
), needed
);