1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
9 * \brief Read and write data on a buf_t object.
12 #define BUFFERS_PRIVATE
13 #include "lib/net/buffers_net.h"
14 #include "lib/buf/buffers.h"
15 #include "lib/log/log.h"
16 #include "lib/log/util_bug.h"
17 #include "lib/net/nettypes.h"
30 /** Helper: If PARANOIA is defined, assert that the buffer in local variable
31 * <b>buf</b> is well-formed. */
32 #define check() STMT_BEGIN buf_assert_ok(buf); STMT_END
34 #define check() STMT_NIL
35 #endif /* defined(PARANOIA) */
37 /** Read up to <b>at_most</b> bytes from the file descriptor <b>fd</b> into
38 * <b>chunk</b> (which must be on <b>buf</b>). If we get an EOF, set
39 * *<b>reached_eof</b> to 1. Uses <b>tor_socket_recv()</b> iff <b>is_socket</b>
40 * is true, otherwise it uses <b>read()</b>. Return -1 on error (and sets
41 * *<b>error</b> to errno), 0 on eof or blocking, and the number of bytes read
44 read_to_chunk(buf_t
*buf
, chunk_t
*chunk
, tor_socket_t fd
, size_t at_most
,
45 int *reached_eof
, int *error
, bool is_socket
)
48 if (at_most
> CHUNK_REMAINING_CAPACITY(chunk
))
49 at_most
= CHUNK_REMAINING_CAPACITY(chunk
);
52 read_result
= tor_socket_recv(fd
, CHUNK_WRITE_PTR(chunk
), at_most
, 0);
54 read_result
= read(fd
, CHUNK_WRITE_PTR(chunk
), at_most
);
56 if (read_result
< 0) {
57 int e
= is_socket
? tor_socket_errno(fd
) : errno
;
59 if (!ERRNO_IS_EAGAIN(e
)) { /* it's a real error */
62 log_warn(LD_NET
, "%s() failed: WSAENOBUFS. Not enough ram?",
63 is_socket
? "recv" : "read");
69 return 0; /* would block. */
70 } else if (read_result
== 0) {
71 log_debug(LD_NET
,"Encountered eof on fd %d", (int)fd
);
74 } else { /* actually got bytes. */
75 buf
->datalen
+= read_result
;
76 chunk
->datalen
+= read_result
;
77 log_debug(LD_NET
,"Read %ld bytes. %d on inbuf.", (long)read_result
,
79 tor_assert(read_result
<= BUF_MAX_LEN
);
80 return (int)read_result
;
84 /** Read from file descriptor <b>fd</b>, writing onto end of <b>buf</b>. Read
85 * at most <b>at_most</b> bytes, growing the buffer as necessary. If recv()
86 * returns 0 (because of EOF), set *<b>reached_eof</b> to 1 and return 0.
87 * Return -1 on error; else return the number of bytes read.
89 /* XXXX indicate "read blocked" somehow? */
91 buf_read_from_fd(buf_t
*buf
, int fd
, size_t at_most
,
96 /* XXXX It's stupid to overload the return values for these functions:
97 * "error status" and "number of bytes read" are not mutually exclusive.
100 size_t total_read
= 0;
103 tor_assert(reached_eof
);
104 tor_assert(SOCKET_OK(fd
));
106 if (BUG(buf
->datalen
> BUF_MAX_LEN
))
108 if (BUG(buf
->datalen
> BUF_MAX_LEN
- at_most
))
111 while (at_most
> total_read
) {
112 size_t readlen
= at_most
- total_read
;
114 if (!buf
->tail
|| CHUNK_REMAINING_CAPACITY(buf
->tail
) < MIN_READ_LEN
) {
115 chunk
= buf_add_chunk_with_capacity(buf
, at_most
, 1);
116 if (readlen
> chunk
->memlen
)
117 readlen
= chunk
->memlen
;
119 size_t cap
= CHUNK_REMAINING_CAPACITY(buf
->tail
);
125 r
= read_to_chunk(buf
, chunk
, fd
, readlen
,
126 reached_eof
, socket_error
, is_socket
);
129 return r
; /* Error */
130 tor_assert(total_read
+r
<= BUF_MAX_LEN
);
132 if ((size_t)r
< readlen
) { /* eof, block, or no more to read. */
136 return (int)total_read
;
139 /** Helper for buf_flush_to_socket(): try to write <b>sz</b> bytes from chunk
140 * <b>chunk</b> of buffer <b>buf</b> onto file descriptor <b>fd</b>. Return
141 * the number of bytes written on success, 0 on blocking, -1 on failure.
144 flush_chunk(tor_socket_t fd
, buf_t
*buf
, chunk_t
*chunk
, size_t sz
,
147 ssize_t write_result
;
149 if (sz
> chunk
->datalen
)
153 write_result
= tor_socket_send(fd
, chunk
->data
, sz
, 0);
155 write_result
= write(fd
, chunk
->data
, sz
);
157 if (write_result
< 0) {
158 int e
= is_socket
? tor_socket_errno(fd
) : errno
;
160 if (!ERRNO_IS_EAGAIN(e
)) { /* it's a real error */
163 log_warn(LD_NET
,"write() failed: WSAENOBUFS. Not enough ram?");
167 log_debug(LD_NET
,"write() would block, returning.");
170 buf_drain(buf
, write_result
);
171 tor_assert(write_result
<= BUF_MAX_LEN
);
172 return (int)write_result
;
176 /** Write data from <b>buf</b> to the file descriptor <b>fd</b>. Write at most
177 * <b>sz</b> bytes, and remove the written bytes
178 * from the buffer. Return the number of bytes written on success,
179 * -1 on failure. Return 0 if write() would block.
182 buf_flush_to_fd(buf_t
*buf
, int fd
, size_t sz
,
185 /* XXXX It's stupid to overload the return values for these functions:
186 * "error status" and "number of bytes flushed" are not mutually exclusive.
190 tor_assert(SOCKET_OK(fd
));
191 if (BUG(sz
> buf
->datalen
)) {
198 tor_assert(buf
->head
);
199 if (buf
->head
->datalen
>= sz
)
202 flushlen0
= buf
->head
->datalen
;
204 r
= flush_chunk(fd
, buf
, buf
->head
, flushlen0
, is_socket
);
210 if (r
== 0 || (size_t)r
< flushlen0
) /* can't flush any more now. */
213 tor_assert(flushed
<= BUF_MAX_LEN
);
217 /** Write data from <b>buf</b> to the socket <b>s</b>. Write at most
218 * <b>sz</b> bytes, decrement *<b>buf_flushlen</b> by
219 * the number of bytes actually written, and remove the written bytes
220 * from the buffer. Return the number of bytes written on success,
221 * -1 on failure. Return 0 if write() would block.
224 buf_flush_to_socket(buf_t
*buf
, tor_socket_t s
, size_t sz
)
226 return buf_flush_to_fd(buf
, s
, sz
, true);
229 /** Read from socket <b>s</b>, writing onto end of <b>buf</b>. Read at most
230 * <b>at_most</b> bytes, growing the buffer as necessary. If recv() returns 0
231 * (because of EOF), set *<b>reached_eof</b> to 1 and return 0. Return -1 on
232 * error; else return the number of bytes read.
235 buf_read_from_socket(buf_t
*buf
, tor_socket_t s
, size_t at_most
,
239 return buf_read_from_fd(buf
, s
, at_most
, reached_eof
, socket_error
, true);
242 /** Write data from <b>buf</b> to the pipe <b>fd</b>. Write at most
243 * <b>sz</b> bytes, decrement *<b>buf_flushlen</b> by
244 * the number of bytes actually written, and remove the written bytes
245 * from the buffer. Return the number of bytes written on success,
246 * -1 on failure. Return 0 if write() would block.
249 buf_flush_to_pipe(buf_t
*buf
, int fd
, size_t sz
)
251 return buf_flush_to_fd(buf
, fd
, sz
, false);
254 /** Read from pipe <b>fd</b>, writing onto end of <b>buf</b>. Read at most
255 * <b>at_most</b> bytes, growing the buffer as necessary. If read() returns 0
256 * (because of EOF), set *<b>reached_eof</b> to 1 and return 0. Return -1 on
257 * error; else return the number of bytes read.
260 buf_read_from_pipe(buf_t
*buf
, int fd
, size_t at_most
,
264 return buf_read_from_fd(buf
, fd
, at_most
, reached_eof
, socket_error
, false);