buffers_net.c (8183B)
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 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 ssize_t read_result; 48 if (at_most > CHUNK_REMAINING_CAPACITY(chunk)) 49 at_most = CHUNK_REMAINING_CAPACITY(chunk); 50 51 if (is_socket) 52 read_result = tor_socket_recv(fd, CHUNK_WRITE_PTR(chunk), at_most, 0); 53 else 54 read_result = read(fd, CHUNK_WRITE_PTR(chunk), at_most); 55 56 if (read_result < 0) { 57 int e = is_socket ? tor_socket_errno(fd) : errno; 58 59 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 if (error) 66 *error = e; 67 return -1; 68 } 69 return 0; /* would block. */ 70 } else if (read_result == 0) { 71 log_debug(LD_NET,"Encountered eof on fd %d", (int)fd); 72 *reached_eof = 1; 73 return 0; 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, 78 (int)buf->datalen); 79 tor_assert(read_result <= BUF_MAX_LEN); 80 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 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 int r = 0; 100 size_t total_read = 0; 101 102 check(); 103 tor_assert(reached_eof); 104 tor_assert(SOCKET_OK(fd)); 105 106 if (BUG(buf->datalen > BUF_MAX_LEN)) 107 return -1; 108 if (BUG(buf->datalen > BUF_MAX_LEN - at_most)) 109 return -1; 110 111 while (at_most > total_read) { 112 size_t readlen = at_most - total_read; 113 chunk_t *chunk; 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; 118 } else { 119 size_t cap = CHUNK_REMAINING_CAPACITY(buf->tail); 120 chunk = buf->tail; 121 if (cap < readlen) 122 readlen = cap; 123 } 124 125 r = read_to_chunk(buf, chunk, fd, readlen, 126 reached_eof, socket_error, is_socket); 127 check(); 128 if (r < 0) 129 return r; /* Error */ 130 tor_assert(total_read+r <= BUF_MAX_LEN); 131 total_read += r; 132 if ((size_t)r < readlen) { /* eof, block, or no more to read. */ 133 break; 134 } 135 } 136 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 flush_chunk(tor_socket_t fd, buf_t *buf, chunk_t *chunk, size_t sz, 145 bool is_socket) 146 { 147 ssize_t write_result; 148 149 if (sz > chunk->datalen) 150 sz = chunk->datalen; 151 152 if (is_socket) 153 write_result = tor_socket_send(fd, chunk->data, sz, 0); 154 else 155 write_result = write(fd, chunk->data, sz); 156 157 if (write_result < 0) { 158 int e = is_socket ? tor_socket_errno(fd) : errno; 159 160 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 log_debug(LD_NET,"write() would block, returning."); 168 return 0; 169 } else { 170 buf_drain(buf, write_result); 171 tor_assert(write_result <= BUF_MAX_LEN); 172 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 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 int r; 189 size_t flushed = 0; 190 tor_assert(SOCKET_OK(fd)); 191 if (BUG(sz > buf->datalen)) { 192 sz = buf->datalen; 193 } 194 195 check(); 196 while (sz) { 197 size_t flushlen0; 198 tor_assert(buf->head); 199 if (buf->head->datalen >= sz) 200 flushlen0 = sz; 201 else 202 flushlen0 = buf->head->datalen; 203 204 r = flush_chunk(fd, buf, buf->head, flushlen0, is_socket); 205 check(); 206 if (r < 0) 207 return r; 208 flushed += r; 209 sz -= r; 210 if (r == 0 || (size_t)r < flushlen0) /* can't flush any more now. */ 211 break; 212 } 213 tor_assert(flushed <= BUF_MAX_LEN); 214 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 buf_flush_to_socket(buf_t *buf, tor_socket_t s, size_t sz) 225 { 226 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 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 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 buf_flush_to_pipe(buf_t *buf, int fd, size_t sz) 250 { 251 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 buf_read_from_pipe(buf_t *buf, int fd, size_t at_most, 261 int *reached_eof, 262 int *socket_error) 263 { 264 return buf_read_from_fd(buf, fd, at_most, reached_eof, socket_error, false); 265 }