Line data Source code
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 */
6 :
7 : /**
8 : * \file buffers_net.c
9 : * \brief Read and write data on a buf_t object.
10 : **/
11 :
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"
18 :
19 : #ifdef _WIN32
20 : #include <winsock2.h>
21 : #endif
22 :
23 : #include <stdlib.h>
24 :
25 : #ifdef HAVE_UNISTD_H
26 : #include <unistd.h>
27 : #endif
28 :
29 : #ifdef PARANOIA
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
33 : #else
34 : #define check() STMT_NIL
35 : #endif /* defined(PARANOIA) */
36 :
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
42 : * otherwise. */
43 : static inline int
44 10 : 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)
46 : {
47 10 : ssize_t read_result;
48 10 : if (at_most > CHUNK_REMAINING_CAPACITY(chunk))
49 : at_most = CHUNK_REMAINING_CAPACITY(chunk);
50 :
51 10 : if (is_socket)
52 0 : read_result = tor_socket_recv(fd, CHUNK_WRITE_PTR(chunk), at_most, 0);
53 : else
54 10 : read_result = read(fd, CHUNK_WRITE_PTR(chunk), at_most);
55 :
56 10 : if (read_result < 0) {
57 0 : int e = is_socket ? tor_socket_errno(fd) : errno;
58 :
59 0 : if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */
60 : #ifdef _WIN32
61 : if (e == WSAENOBUFS)
62 : log_warn(LD_NET, "%s() failed: WSAENOBUFS. Not enough ram?",
63 : is_socket ? "recv" : "read");
64 : #endif
65 0 : if (error)
66 0 : *error = e;
67 0 : return -1;
68 : }
69 : return 0; /* would block. */
70 10 : } else if (read_result == 0) {
71 4 : log_debug(LD_NET,"Encountered eof on fd %d", (int)fd);
72 4 : *reached_eof = 1;
73 4 : return 0;
74 : } else { /* actually got bytes. */
75 6 : buf->datalen += read_result;
76 6 : chunk->datalen += read_result;
77 6 : log_debug(LD_NET,"Read %ld bytes. %d on inbuf.", (long)read_result,
78 : (int)buf->datalen);
79 6 : tor_assert(read_result <= BUF_MAX_LEN);
80 6 : return (int)read_result;
81 : }
82 : }
83 :
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.
88 : */
89 : /* XXXX indicate "read blocked" somehow? */
90 : static int
91 10 : buf_read_from_fd(buf_t *buf, int fd, size_t at_most,
92 : int *reached_eof,
93 : int *socket_error,
94 : bool is_socket)
95 : {
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.
98 : */
99 10 : int r = 0;
100 10 : size_t total_read = 0;
101 :
102 10 : check();
103 10 : tor_assert(reached_eof);
104 10 : tor_assert(SOCKET_OK(fd));
105 :
106 10 : if (BUG(buf->datalen > BUF_MAX_LEN))
107 0 : return -1;
108 10 : if (BUG(buf->datalen > BUF_MAX_LEN - at_most))
109 0 : return -1;
110 :
111 10 : while (at_most > total_read) {
112 10 : size_t readlen = at_most - total_read;
113 10 : chunk_t *chunk;
114 10 : if (!buf->tail || CHUNK_REMAINING_CAPACITY(buf->tail) < MIN_READ_LEN) {
115 7 : chunk = buf_add_chunk_with_capacity(buf, at_most, 1);
116 7 : if (readlen > chunk->memlen)
117 : readlen = chunk->memlen;
118 : } else {
119 3 : size_t cap = CHUNK_REMAINING_CAPACITY(buf->tail);
120 3 : chunk = buf->tail;
121 3 : if (cap < readlen)
122 : readlen = cap;
123 : }
124 :
125 10 : r = read_to_chunk(buf, chunk, fd, readlen,
126 : reached_eof, socket_error, is_socket);
127 10 : check();
128 10 : if (r < 0)
129 0 : return r; /* Error */
130 10 : tor_assert(total_read+r <= BUF_MAX_LEN);
131 10 : total_read += r;
132 10 : if ((size_t)r < readlen) { /* eof, block, or no more to read. */
133 : break;
134 : }
135 : }
136 10 : return (int)total_read;
137 : }
138 :
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.
142 : */
143 : static inline int
144 3 : flush_chunk(tor_socket_t fd, buf_t *buf, chunk_t *chunk, size_t sz,
145 : bool is_socket)
146 : {
147 3 : ssize_t write_result;
148 :
149 3 : if (sz > chunk->datalen)
150 : sz = chunk->datalen;
151 :
152 3 : if (is_socket)
153 0 : write_result = tor_socket_send(fd, chunk->data, sz, 0);
154 : else
155 3 : write_result = write(fd, chunk->data, sz);
156 :
157 3 : if (write_result < 0) {
158 0 : int e = is_socket ? tor_socket_errno(fd) : errno;
159 :
160 0 : if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */
161 : #ifdef _WIN32
162 : if (e == WSAENOBUFS)
163 : log_warn(LD_NET,"write() failed: WSAENOBUFS. Not enough ram?");
164 : #endif
165 : return -1;
166 : }
167 0 : log_debug(LD_NET,"write() would block, returning.");
168 0 : return 0;
169 : } else {
170 3 : buf_drain(buf, write_result);
171 3 : tor_assert(write_result <= BUF_MAX_LEN);
172 3 : return (int)write_result;
173 : }
174 : }
175 :
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.
180 : */
181 : static int
182 3 : buf_flush_to_fd(buf_t *buf, int fd, size_t sz,
183 : bool is_socket)
184 : {
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.
187 : */
188 3 : int r;
189 3 : size_t flushed = 0;
190 3 : tor_assert(SOCKET_OK(fd));
191 3 : if (BUG(sz > buf->datalen)) {
192 0 : sz = buf->datalen;
193 : }
194 :
195 : check();
196 6 : while (sz) {
197 3 : size_t flushlen0;
198 3 : tor_assert(buf->head);
199 3 : if (buf->head->datalen >= sz)
200 : flushlen0 = sz;
201 : else
202 : flushlen0 = buf->head->datalen;
203 :
204 3 : r = flush_chunk(fd, buf, buf->head, flushlen0, is_socket);
205 3 : check();
206 3 : if (r < 0)
207 0 : return r;
208 3 : flushed += r;
209 3 : sz -= r;
210 3 : if (r == 0 || (size_t)r < flushlen0) /* can't flush any more now. */
211 : break;
212 : }
213 3 : tor_assert(flushed <= BUF_MAX_LEN);
214 3 : return (int)flushed;
215 : }
216 :
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.
222 : */
223 : int
224 0 : buf_flush_to_socket(buf_t *buf, tor_socket_t s, size_t sz)
225 : {
226 0 : return buf_flush_to_fd(buf, s, sz, true);
227 : }
228 :
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.
233 : */
234 : int
235 0 : buf_read_from_socket(buf_t *buf, tor_socket_t s, size_t at_most,
236 : int *reached_eof,
237 : int *socket_error)
238 : {
239 0 : return buf_read_from_fd(buf, s, at_most, reached_eof, socket_error, true);
240 : }
241 :
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.
247 : */
248 : int
249 3 : buf_flush_to_pipe(buf_t *buf, int fd, size_t sz)
250 : {
251 3 : return buf_flush_to_fd(buf, fd, sz, false);
252 : }
253 :
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.
258 : */
259 : int
260 10 : buf_read_from_pipe(buf_t *buf, int fd, size_t at_most,
261 : int *reached_eof,
262 : int *socket_error)
263 : {
264 10 : return buf_read_from_fd(buf, fd, at_most, reached_eof, socket_error, false);
265 : }
|