buffers.c 35.5 KB
Newer Older
Roger Dingledine's avatar
Roger Dingledine committed
1
2
/* Copyright 2001 Matej Pfajfar.
 * Copyright 2001-2004 Roger Dingledine.
Nick Mathewson's avatar
Nick Mathewson committed
3
 * Copyright 2004-2005 Roger Dingledine, Nick Mathewson. */
4
5
/* See LICENSE for licensing information */
/* $Id$ */
6
const char buffers_c_id[] = "$Id$";
Roger Dingledine's avatar
Roger Dingledine committed
7

8
9
/**
 * \file buffers.c
10
11
12
 * \brief Implements a generic buffer interface.  Buffers are
 * fairly opaque string holders that can read to or flush from:
 * memory, file descriptors, or TLS connections.
13
 **/
Roger Dingledine's avatar
Roger Dingledine committed
14
15
16

#include "or.h"

17
#define SENTINELS
18
19
#undef CHECK_AFTER_RESIZE
#undef PARANOIA
20
#undef NOINLINE
21

22
23
#ifdef SENTINELS
/* If SENTINELS is defined, check for attempts to write beyond the
24
25
26
27
 * end/before the start of the buffer.
 */
#define START_MAGIC 0x70370370u
#define END_MAGIC 0xA0B0C0D0u
28
29
#define RAW_MEM(m) ((void*)(((char*)m)-4))
#define GUARDED_MEM(m) ((void*)(((char*)m)+4))
30
31
#define ALLOC_LEN(ln) ((ln)+8)
#define SET_GUARDS(m, ln) \
Nick Mathewson's avatar
Nick Mathewson committed
32
  do { set_uint32((m)-4,START_MAGIC); set_uint32((m)+ln,END_MAGIC); } while (0)
33
34
35
36
#else
#define RAW_MEM(m) (m)
#define GUARDED_MEM(m) (m)
#define ALLOC_LEN(ln) (ln)
Nick Mathewson's avatar
Nick Mathewson committed
37
#define SET_GUARDS(m,ln) do {} while (0)
38
39
#endif

40
41
42
43
44
45
#ifdef PARANOIA
#define check() do { assert_buf_ok(buf); } while (0)
#else
#define check() do { } while (0)
#endif

46
#ifdef NOINLINE
47
48
#undef INLINE
#define INLINE
49
#endif
50

51
#define BUFFER_MAGIC 0xB0FFF312u
52
struct buf_t {
53
54
  uint32_t magic; /**< Magic cookie for debugging: Must be set to BUFFER_MAGIC */
  char *mem;      /**< Storage for data in the buffer */
55
  char *cur;      /**< The first byte used for storing data in the buffer. */
56
  size_t highwater; /**< Largest observed datalen since last buf_shrink */
Roger Dingledine's avatar
Roger Dingledine committed
57
58
  size_t len;     /**< Maximum amount of data that <b>mem</b> can hold. */
  size_t datalen; /**< Number of bytes currently in <b>mem</b>. */
59
};
60

61
62
63
uint64_t buf_total_used = 0;
uint64_t buf_total_alloc = 0;

64
/** Size, in bytes, for newly allocated buffers.  Should be a power of 2. */
65
#define INITIAL_BUF_SIZE (4*1024)
66
/** Size, in bytes, for minimum 'shrink' size for buffers.  Buffers may start
67
68
 * out smaller than this, but they will never autoshrink to less
 * than this size. */
69
70
#define MIN_GREEDY_SHRINK_SIZE (16*1024)
#define MIN_LAZY_SHRINK_SIZE (4*1024)
71

72
static INLINE void peek_from_buf(char *string, size_t string_len, buf_t *buf);
73

74
75
76
77
78
/** If the contents of buf wrap around the end of the allocated space,
 * malloc a new buf and copy the contents in starting at the
 * beginning. This operation is relatively expensive, so it shouldn't
 * be used e.g. for every single read or write.
 */
79
80
static void
buf_normalize(buf_t *buf)
81
{
82
  check();
83
  if (buf->cur + buf->datalen <= buf->mem+buf->len) {
84
85
86
    return;
  } else {
    char *newmem;
87
    size_t sz = (buf->mem+buf->len)-buf->cur;
88
89
90
    log_fn(LOG_WARN, "Unexpected non-normalized buffer.");
    newmem = GUARDED_MEM(tor_malloc(ALLOC_LEN(buf->len)));
    SET_GUARDS(newmem, buf->len);
91
    memcpy(newmem, buf->cur, sz);
92
93
    memcpy(newmem+sz, buf->mem, buf->datalen-sz);
    free(RAW_MEM(buf->mem));
94
    buf->mem = buf->cur = newmem;
95
    check();
96
97
98
99
  }
}

/** Return the point in the buffer where the next byte will get stored. */
100
101
static INLINE char *
_buf_end(buf_t *buf)
102
{
103
  char *next = buf->cur + buf->datalen;
104
105
106
107
108
109
  char *end = buf->mem + buf->len;
  return (next < end) ? next : (next - buf->len);
}

/** If the pointer <b>cp</b> has passed beyond the end of the buffer, wrap it
 * around. */
110
111
static INLINE char *
_wrap_ptr(buf_t *buf, char *cp) {
112
113
114
115
116
117
118
119
  return (cp >= buf->mem + buf->len) ? (cp - buf->len) : cp;
}

/** If the range of *<b>len</b> bytes starting at <b>at</b> wraps around the
 * end of the buffer, then set *<b>len</b> to the number of bytes starting
 * at <b>at</b>, and set *<b>more_len</b> to the number of bytes starting
 * at <b>buf-&gt;mem</b>.  Otherwise, set *<b>more_len</b> to 0.
 */
120
121
static INLINE void
_split_range(buf_t *buf, char *at, size_t *len,
122
123
124
                                size_t *more_len)
{
  char *eos = at + *len;
125
  check();
126
127
128
129
130
131
132
133
134
  if (eos >= (buf->mem + buf->len)) {
    *more_len = eos - (buf->mem + buf->len);
    *len -= *more_len;
  } else {
    *more_len = 0;
  }
}

/** Change a buffer's capacity. <b>new_capacity</b> must be \>= buf->datalen. */
135
136
static void
buf_resize(buf_t *buf, size_t new_capacity)
137
{
138
139
140
141
  off_t offset;
#ifdef CHECK_AFTER_RESIZE
  char *tmp, *tmp2;
#endif
Roger Dingledine's avatar
Roger Dingledine committed
142
143
  tor_assert(buf->datalen <= new_capacity);
  tor_assert(new_capacity);
144
145
146
147
148
149
150
151

#ifdef CHECK_AFTER_RESIZE
  assert_buf_ok(buf);
  tmp = tor_malloc(buf->datalen);
  tmp2 = tor_malloc(buf->datalen);
  peek_from_buf(tmp, buf->datalen, buf);
#endif

152
153
154
  if (buf->len == new_capacity)
    return;

155
  offset = buf->cur - buf->mem;
156
  if (offset + buf->datalen > new_capacity) {
157
    /* We need to move stuff before we shrink. */
158
    if (offset + buf->datalen > buf->len) {
159
160
161
162
163
164
165
166
      /* We have:
       *
       * mem[0] ... mem[datalen-(len-offset)] (end of data)
       * mem[offset] ... mem[len-1]           (the start of the data)
       *
       * We're shrinking the buffer by (len-new_capacity) bytes, so we need
       * to move the start portion back by that many bytes.
       */
167
      memmove(buf->cur-(buf->len-new_capacity), buf->cur,
168
169
170
              buf->len-offset);
      offset -= (buf->len-new_capacity);
    } else {
171
      /* The data doesn't wrap around, but it does extend beyond the new
172
173
174
       * buffer length:
       *   mem[offset] ... mem[offset+datalen-1] (the data)
       */
175
      memmove(buf->mem, buf->cur, buf->datalen);
176
177
178
      offset = 0;
    }
  }
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

  /* XXX Some play code to throw away old buffers sometimes rather
   * than constantly reallocing them; just in case this is our memory
   * problem. It looks for now like it isn't, so disabled. -RD */
  if (0 && new_capacity == MIN_LAZY_SHRINK_SIZE &&
      !buf->datalen &&
      buf->len >= 1<<16) {
    /* don't realloc; free and malloc */
    char *newmem = GUARDED_MEM(tor_malloc(ALLOC_LEN(new_capacity)));
    SET_GUARDS(newmem, new_capacity);
    free(RAW_MEM(buf->mem));
    buf->mem = buf->cur = newmem;

  } else {
    buf->mem = GUARDED_MEM(tor_realloc(RAW_MEM(buf->mem),
                                       ALLOC_LEN(new_capacity)));
    SET_GUARDS(buf->mem, new_capacity);
    buf->cur = buf->mem+offset;
  }
198
199
  buf_total_alloc += new_capacity;
  buf_total_alloc -= buf->len;
200

201
  if (offset + buf->datalen > buf->len) {
202
203
204
205
206
207
208
209
210
211
    /* We need to move data now that we are done growing.  The buffer
     * now contains:
     *
     * mem[0] ... mem[datalen-(len-offset)] (end of data)
     * mem[offset] ... mem[len-1]           (the start of the data)
     * mem[len]...mem[new_capacity]         (empty space)
     *
     * We're growing by (new_capacity-len) bytes, so we need to move the
     * end portion forward by that many bytes.
     */
212
    memmove(buf->cur+(new_capacity-buf->len), buf->cur,
213
            buf->len-offset);
214
    buf->cur += new_capacity-buf->len;
215
  }
216
  buf->len = new_capacity;
217
218
219
220
221
222
223
224
225
226

#ifdef CHECK_AFTER_RESIZE
  assert_buf_ok(buf);
  peek_from_buf(tmp2, buf->datalen, buf);
  if (memcmp(tmp, tmp2, buf->datalen)) {
    tor_assert(0);
  }
  tor_free(tmp);
  tor_free(tmp2);
#endif
227
228
}

Roger Dingledine's avatar
Roger Dingledine committed
229
/** If the buffer is not large enough to hold <b>capacity</b> bytes, resize
230
231
232
 * it so that it can.  (The new size will be a power of 2 times the old
 * size.)
 */
233
234
static INLINE int
buf_ensure_capacity(buf_t *buf, size_t capacity)
235
236
{
  size_t new_len;
237
  if (buf->len >= capacity)  /* Don't grow if we're already big enough. */
238
    return 0;
239
  if (capacity > MAX_BUF_SIZE) /* Don't grow past the maximum. */
240
    return -1;
241
242
243
  /* Find the smallest new_len equal to (2**X)*len for some X; such that
   * new_len is at least capacity.
   */
244
245
246
  new_len = buf->len*2;
  while (new_len < capacity)
    new_len *= 2;
247
  /* Resize the buffer. */
248
249
  log_fn(LOG_DEBUG,"Growing buffer from %d to %d bytes.",
         (int)buf->len, (int)new_len);
250
251
252
253
  buf_resize(buf,new_len);
  return 0;
}

254
#if 0
255
256
/** If the buffer is at least 2*MIN_GREEDY_SHRINK_SIZE bytes in capacity,
 * and if the buffer is less than 1/8 full, shrink the buffer until
257
258
259
 * one of the above no longer holds.  (We shrink the buffer by
 * dividing by powers of 2.)
 */
260
261
static INLINE void
buf_shrink_if_underfull(buf_t *buf) {
262
  size_t new_len;
263
264
265
  /* If the buffer is at least 1/8 full, or if shrinking the buffer would
   * put it under MIN_GREEDY_SHRINK_SIZE, don't do it. */
  if (buf->datalen >= (buf->len>>3) || buf->len < MIN_GREEDY_SHRINK_SIZE*2)
266
    return;
267
268
  /* Shrink new_len by powers of 2 until: datalen is at least 1/4 of
   * new_len, OR shrinking new_len more would put it under
269
   * MIN_GREEDY_SHRINK_SIZE.
270
   */
271
272
273
  new_len = (buf->len>>1);
  while (buf->datalen < (new_len>>3) && new_len > MIN_GREEDY_SHRINK_SIZE*2)
    new_len >>= 1;
274
275
276
  log_fn(LOG_DEBUG,"Shrinking buffer from %d to %d bytes.",
         (int)buf->len, (int)new_len);
  buf_resize(buf, new_len);
277
}
278
279
280
#else
#define buf_shrink_if_underfull(buf) do {} while (0)
#endif
281

282
283
284
285
286
/** Resize buf so it won't hold extra memory that we haven't been
 * using lately (that is, since the last time we called buf_shrink).
 * Try to shrink the buf until it is the largest factor of two that
 * can contain <b>buf</b>-&gt;highwater, but never smaller than
 * MIN_LAZY_SHRINK_SIZE.
Roger Dingledine's avatar
Roger Dingledine committed
287
 */
288
289
290
291
292
void
buf_shrink(buf_t *buf)
{
  size_t new_len;

293
  new_len = buf->len;
294
295
296
  while (buf->highwater < (new_len>>2) && new_len > MIN_LAZY_SHRINK_SIZE*2)
    new_len >>= 1;

297
  buf->highwater = buf->datalen;
298
299
300
  if (new_len == buf->len)
    return;

301
302
303
304
305
  log_fn(LOG_DEBUG,"Shrinking buffer from %d to %d bytes.",
         (int)buf->len, (int)new_len);
  buf_resize(buf, new_len);
}

Roger Dingledine's avatar
Roger Dingledine committed
306
/** Remove the first <b>n</b> bytes from buf.
307
 */
308
309
static INLINE void
buf_remove_from_front(buf_t *buf, size_t n) {
Roger Dingledine's avatar
Roger Dingledine committed
310
  tor_assert(buf->datalen >= n);
311
  buf->datalen -= n;
312
  buf_total_used -= n;
313
314
315
316
317
  if (buf->datalen) {
    buf->cur = _wrap_ptr(buf, buf->cur+n);
  } else {
    buf->cur = buf->mem;
  }
318
  buf_shrink_if_underfull(buf);
319
  check();
320
321
}

Nick Mathewson's avatar
Nick Mathewson committed
322
/** Make sure that the memory in buf ends with a zero byte. */
323
324
static INLINE int
buf_nul_terminate(buf_t *buf)
325
{
Nick Mathewson's avatar
Nick Mathewson committed
326
  if (buf_ensure_capacity(buf,buf->datalen+1)<0)
327
    return -1;
328
  *_buf_end(buf) = '\0';
Nick Mathewson's avatar
Nick Mathewson committed
329
  return 0;
330
331
}

Roger Dingledine's avatar
Roger Dingledine committed
332
/** Create and return a new buf with capacity <b>size</b>.
333
 */
334
335
buf_t *
buf_new_with_capacity(size_t size) {
336
  buf_t *buf;
337
  buf = tor_malloc_zero(sizeof(buf_t));
338
  buf->magic = BUFFER_MAGIC;
339
  buf->cur = buf->mem = GUARDED_MEM(tor_malloc(ALLOC_LEN(size)));
340
  SET_GUARDS(buf->mem, size);
341
342
  buf->len = size;

343
  buf_total_alloc += size;
Roger Dingledine's avatar
Roger Dingledine committed
344
  assert_buf_ok(buf);
345
346
  return buf;
}
Roger Dingledine's avatar
Roger Dingledine committed
347

348
/** Allocate and return a new buffer with default capacity. */
349
350
buf_t *
buf_new(void)
351
{
352
  return buf_new_with_capacity(INITIAL_BUF_SIZE);
353
}
Roger Dingledine's avatar
Roger Dingledine committed
354

Roger Dingledine's avatar
Roger Dingledine committed
355
/** Remove all data from <b>buf</b> */
356
357
void
buf_clear(buf_t *buf)
358
{
359
  buf_total_used -= buf->datalen;
360
  buf->datalen = 0;
361
  buf->cur = buf->mem;
362
}
Roger Dingledine's avatar
Roger Dingledine committed
363

Roger Dingledine's avatar
Roger Dingledine committed
364
/** Return the number of bytes stored in <b>buf</b> */
365
366
size_t
buf_datalen(const buf_t *buf)
367
368
{
  return buf->datalen;
Roger Dingledine's avatar
Roger Dingledine committed
369
370
}

Roger Dingledine's avatar
Roger Dingledine committed
371
/** Return the maximum bytes that can be stored in <b>buf</b> before buf
372
 * needs to resize. */
373
374
size_t
buf_capacity(const buf_t *buf)
375
376
377
378
{
  return buf->len;
}

Roger Dingledine's avatar
Roger Dingledine committed
379
/** For testing only: Return a pointer to the raw memory stored in <b>buf</b>.
380
 */
381
382
const char *
_buf_peek_raw_buffer(const buf_t *buf)
383
{
384
  return buf->cur;
385
386
}

Roger Dingledine's avatar
Roger Dingledine committed
387
/** Release storage held by <b>buf</b>.
388
 */
389
390
391
void
buf_free(buf_t *buf)
{
392
393
  assert_buf_ok(buf);
  buf->magic = 0xDEADBEEF;
394
  free(RAW_MEM(buf->mem));
395
396
  buf_total_alloc -= buf->len;
  buf_total_used -= buf->datalen;
397
  tor_free(buf);
Roger Dingledine's avatar
Roger Dingledine committed
398
399
}

400
401
402
403
404
405
406
407
408
/** Helper for read_to_buf: read no more than at_most bytes from
 * socket s into buffer buf, starting at the position pos.  (Does not
 * check for overflow.)  Set *reached_eof to true on EOF.  Return
 * number of bytes read on success, 0 if the read would block, -1 on
 * failure.
 */
static INLINE int
read_to_buf_impl(int s, size_t at_most, buf_t *buf,
                 char *pos, int *reached_eof)
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
{
  int read_result;

//  log_fn(LOG_DEBUG,"reading at most %d bytes.",at_most);
  read_result = recv(s, pos, at_most, 0);
  if (read_result < 0) {
    int e = tor_socket_errno(s);
    if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */
      return -1;
    }
    return 0; /* would block. */
  } else if (read_result == 0) {
    log_fn(LOG_DEBUG,"Encountered eof");
    *reached_eof = 1;
    return 0;
  } else { /* we read some bytes */
    buf->datalen += read_result;
426
    buf_total_used += read_result;
427
428
    if (buf->datalen > buf->highwater)
      buf->highwater = buf->datalen;
429
430
431
432
433
434
    log_fn(LOG_DEBUG,"Read %d bytes. %d on inbuf.",read_result,
           (int)buf->datalen);
    return read_result;
  }
}

Nick Mathewson's avatar
Nick Mathewson committed
435
/** Read from socket <b>s</b>, writing onto end of <b>buf</b>.  Read at most
Roger Dingledine's avatar
Roger Dingledine committed
436
 * <b>at_most</b> bytes, resizing the buffer as necessary.  If recv()
Roger Dingledine's avatar
Roger Dingledine committed
437
 * returns 0, set <b>*reached_eof</b> to 1 and return 0. Return -1 on error;
Roger Dingledine's avatar
Roger Dingledine committed
438
 * else return the number of bytes read.  Return 0 if recv() would
439
 * block.
440
 */
441
442
int
read_to_buf(int s, size_t at_most, buf_t *buf, int *reached_eof)
443
444
445
446
{
  int r;
  char *next;
  size_t at_start;
Roger Dingledine's avatar
Roger Dingledine committed
447

Roger Dingledine's avatar
Roger Dingledine committed
448
  assert_buf_ok(buf);
449
450
  tor_assert(reached_eof);
  tor_assert(s>=0);
Roger Dingledine's avatar
Roger Dingledine committed
451

452
453
  if (buf_ensure_capacity(buf,buf->datalen+at_most))
    return -1;
Roger Dingledine's avatar
Roger Dingledine committed
454

455
  if (at_most + buf->datalen > buf->len)
456
    at_most = buf->len - buf->datalen; /* take the min of the two */
457

458
  if (at_most == 0)
459
460
    return 0; /* we shouldn't read anything */

461
462
463
464
  next = _buf_end(buf);
  _split_range(buf, next, &at_most, &at_start);

  r = read_to_buf_impl(s, at_most, buf, next, reached_eof);
465
  check();
466
467
468
469
470
471
472
  if (r < 0 || (size_t)r < at_most) {
    return r; /* Either error, eof, block, or no more to read. */
  }

  if (at_start) {
    int r2;
    tor_assert(_buf_end(buf) == buf->mem);
473
    r2 = read_to_buf_impl(s, at_start, buf, buf->mem, reached_eof);
474
    check();
475
476
477
478
    if (r2 < 0) {
      return r2;
    } else {
      r += r2;
Roger Dingledine's avatar
Roger Dingledine committed
479
480
    }
  }
481
482
483
  return r;
}

484
485
486
487
488
/** Helper for read_to_buf_tls: read no more than at_most bytes from
 * the TLS connection tlsinto buffer buf, starting at the position
 * next.  (Does not check for overflow.)  Return number of bytes read
 * on success, 0 if the read would block, -1 on failure.
 */
489
490
491
492
493
494
495
496
497
498
499
500
static INLINE int
read_to_buf_tls_impl(tor_tls *tls, size_t at_most, buf_t *buf, char *next)
{
  int r;

  log_fn(LOG_DEBUG,"before: %d on buf, %d pending, at_most %d.",
         (int)buf_datalen(buf), (int)tor_tls_get_pending_bytes(tls),
         (int)at_most);
  r = tor_tls_read(tls, next, at_most);
  if (r<0)
    return r;
  buf->datalen += r;
501
  buf_total_used += r;
502
503
  if (buf->datalen > buf->highwater)
    buf->highwater = buf->datalen;
504
505
506
  log_fn(LOG_DEBUG,"Read %d bytes. %d on inbuf; %d pending",r,
         (int)buf->datalen,(int)tor_tls_get_pending_bytes(tls));
  return r;
Roger Dingledine's avatar
Roger Dingledine committed
507
508
}

509
/** As read_to_buf, but reads from a TLS connection.
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
 *
 * Using TLS on OR connections complicates matters in two ways.
 *
 * First, a TLS stream has its own read buffer independent of the
 * connection's read buffer.  (TLS needs to read an entire frame from
 * the network before it can decrypt any data.  Thus, trying to read 1
 * byte from TLS can require that several KB be read from the network
 * and decrypted.  The extra data is stored in TLS's decrypt buffer.)
 * Because the data hasn't been read by Tor (it's still inside the TLS),
 * this means that sometimes a connection "has stuff to read" even when
 * poll() didn't return POLLIN. The tor_tls_get_pending_bytes function is
 * used in connection.c to detect TLS objects with non-empty internal
 * buffers and read from them again.
 *
 * Second, the TLS stream's events do not correspond directly to network
 * events: sometimes, before a TLS stream can read, the network must be
 * ready to write -- or vice versa.
527
 */
528
529
530
int
read_to_buf_tls(tor_tls *tls, size_t at_most, buf_t *buf)
{
531
  int r;
532
533
534
  char *next;
  size_t at_start;

Roger Dingledine's avatar
Roger Dingledine committed
535
536
  tor_assert(tls);
  assert_buf_ok(buf);
537

538
539
540
  log_fn(LOG_DEBUG,"start: %d on buf, %d pending, at_most %d.",
         (int)buf_datalen(buf), (int)tor_tls_get_pending_bytes(tls),
         (int)at_most);
Roger Dingledine's avatar
Roger Dingledine committed
541

542
  if (buf_ensure_capacity(buf, at_most+buf->datalen))
543
    return TOR_TLS_ERROR;
544

545
  if (at_most + buf->datalen > buf->len)
546
    at_most = buf->len - buf->datalen;
547
548
549

  if (at_most == 0)
    return 0;
550

551
552
553
554
  next = _buf_end(buf);
  _split_range(buf, next, &at_most, &at_start);

  r = read_to_buf_tls_impl(tls, at_most, buf, next);
555
  check();
556
557
558
559
560
561
  if (r < 0 || (size_t)r < at_most)
    return r; /* Either error, eof, block, or no more to read. */

  if (at_start) {
    int r2;
    tor_assert(_buf_end(buf) == buf->mem);
562
    r2 = read_to_buf_tls_impl(tls, at_start, buf, buf->mem);
563
    check();
564
565
566
567
568
    if (r2 < 0)
      return r2;
    else
      r += r2;
  }
569
  return r;
Roger Dingledine's avatar
Roger Dingledine committed
570
}
571

572
573
574
575
/** Helper for flush_buf: try to write sz bytes from buffer buf onto
 * socket s.  On success, deduct the bytes written from *buf_flushlen.
 * Return the number of bytes written on success, -1 on failure.
 */
576
577
578
579
580
static INLINE int
flush_buf_impl(int s, buf_t *buf, size_t sz, size_t *buf_flushlen)
{
  int write_result;

581
  write_result = send(s, buf->cur, sz, 0);
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  if (write_result < 0) {
    int e = tor_socket_errno(s);
    if (!ERRNO_IS_EAGAIN(e)) { /* it's a real error */
      return -1;
    }
    log_fn(LOG_DEBUG,"write() would block, returning.");
    return 0;
  } else {
    *buf_flushlen -= write_result;

    buf_remove_from_front(buf, write_result);

    return write_result;
  }
}

Roger Dingledine's avatar
Roger Dingledine committed
598
599
600
601
602
/** Write data from <b>buf</b> to the socket <b>s</b>.  Write at most
 * <b>*buf_flushlen</b> bytes, decrement <b>*buf_flushlen</b> by
 * the number of bytes actually written, and remove the written bytes
 * from the buffer.  Return the number of bytes written on success,
 * -1 on failure.  Return 0 if write() would block.
603
 */
604
605
int
flush_buf(int s, buf_t *buf, size_t *buf_flushlen)
606
{
607
608
609
  int r;
  size_t flushed = 0;
  size_t flushlen0, flushlen1;
Roger Dingledine's avatar
Roger Dingledine committed
610

Roger Dingledine's avatar
Roger Dingledine committed
611
  assert_buf_ok(buf);
612
613
614
  tor_assert(buf_flushlen);
  tor_assert(s>=0);
  tor_assert(*buf_flushlen <= buf->datalen);
Roger Dingledine's avatar
Roger Dingledine committed
615

616
  if (*buf_flushlen == 0) /* nothing to flush */
Roger Dingledine's avatar
Roger Dingledine committed
617
618
    return 0;

619
  flushlen0 = *buf_flushlen;
620
  _split_range(buf, buf->cur, &flushlen0, &flushlen1);
621
622

  r = flush_buf_impl(s, buf, flushlen0, buf_flushlen);
623
  check();
624
625
626
627
628
629
630
631

  log_fn(LOG_DEBUG,"%d: flushed %d bytes, %d ready to flush, %d remain.",
           s,r,(int)*buf_flushlen,(int)buf->datalen);
  if (r < 0 || (size_t)r < flushlen0)
    return r; /* Error, or can't flush any more now. */
  flushed = r;

  if (flushlen1) {
632
    tor_assert(buf->cur == buf->mem);
633
    r = flush_buf_impl(s, buf, flushlen1, buf_flushlen);
634
    check();
635
    log_fn(LOG_DEBUG,"%d: flushed %d bytes, %d ready to flush, %d remain.",
636
637
638
639
640
641
642
           s,r,(int)*buf_flushlen,(int)buf->datalen);
    if (r<0)
      return r;
    flushed += r;
  }
  return flushed;
}
643

644
645
646
647
/** Helper for flush_buf_tls: try to write sz bytes from buffer buf onto
 * TLS object tls.  On success, deduct the bytes written from *buf_flushlen.
 * Return the number of bytes written on success, -1 on failure.
 */
648
649
650
651
652
static INLINE int
flush_buf_tls_impl(tor_tls *tls, buf_t *buf, size_t sz, size_t *buf_flushlen)
{
  int r;

653
  r = tor_tls_write(tls, buf->cur, sz);
654
655
  if (r < 0) {
    return r;
Roger Dingledine's avatar
Roger Dingledine committed
656
  }
657
658
659
660
661
  *buf_flushlen -= r;
  buf_remove_from_front(buf, r);
  log_fn(LOG_DEBUG,"flushed %d bytes, %d ready to flush, %d remain.",
         r,(int)*buf_flushlen,(int)buf->datalen);
  return r;
Roger Dingledine's avatar
Roger Dingledine committed
662
663
}

664
/** As flush_buf, but writes data to a TLS connection.
665
 */
666
int flush_buf_tls(tor_tls *tls, buf_t *buf, size_t *buf_flushlen)
667
668
{
  int r;
669
670
  size_t flushed=0;
  size_t flushlen0, flushlen1;
Roger Dingledine's avatar
Roger Dingledine committed
671
  assert_buf_ok(buf);
672
673
  tor_assert(tls);
  tor_assert(buf_flushlen);
Roger Dingledine's avatar
Roger Dingledine committed
674
675
676

  /* we want to let tls write even if flushlen is zero, because it might
   * have a partial record pending */
677
  check_no_tls_errors();
678
679

  flushlen0 = *buf_flushlen;
680
  _split_range(buf, buf->cur, &flushlen0, &flushlen1);
681
682

  r = flush_buf_tls_impl(tls, buf, flushlen0, buf_flushlen);
683
  check();
684
685
686
687
688
  if (r < 0 || (size_t)r < flushlen0)
    return r; /* Error, or can't flush any more now. */
  flushed = r;

  if (flushlen1) {
689
    tor_assert(buf->cur == buf->mem);
690
    r = flush_buf_tls_impl(tls, buf, flushlen1, buf_flushlen);
691
    check();
692
693
694
    if (r<0)
      return r;
    flushed += r;
695
  }
696
  return flushed;
697
698
}

Roger Dingledine's avatar
Roger Dingledine committed
699
700
701
/** Append <b>string_len</b> bytes from <b>string</b> to the end of
 * <b>buf</b>.
 *
702
703
 * Return the new length of the buffer on success, -1 on failure.
 */
704
705
706
707
708
int
write_to_buf(const char *string, size_t string_len, buf_t *buf)
{
  char *next;
  size_t len2;
Roger Dingledine's avatar
Roger Dingledine committed
709
710
711
712
713

  /* append string to buf (growing as needed, return -1 if "too big")
   * return total number of bytes on the buf
   */

Roger Dingledine's avatar
Roger Dingledine committed
714
715
  tor_assert(string);
  assert_buf_ok(buf);
Roger Dingledine's avatar
Roger Dingledine committed
716

717
  if (buf_ensure_capacity(buf, buf->datalen+string_len)) {
718
    log_fn(LOG_WARN, "buflen too small, can't hold %d bytes.", (int)(buf->datalen+string_len));
719
    return -1;
720
  }
721

722
723
724
725
  next = _buf_end(buf);
  _split_range(buf, next, &string_len, &len2);

  memcpy(next, string, string_len);
726
  buf->datalen += string_len;
727
  buf_total_used += string_len;
728
729
730
731
732

  if (len2) {
    tor_assert(_buf_end(buf) == buf->mem);
    memcpy(buf->mem, string+string_len, len2);
    buf->datalen += len2;
733
    buf_total_used += len2;
734
  }
735
736
  if (buf->datalen > buf->highwater)
    buf->highwater = buf->datalen;
737
738
  log_fn(LOG_DEBUG,"added %d bytes to buf (now %d total).",
         (int)string_len, (int)buf->datalen);
739
  check();
740
  return buf->datalen;
741
742
}

743
744
745
746
/** Helper: copy the first string_len bytes from buf onto string.
 */
static INLINE void
peek_from_buf(char *string, size_t string_len, buf_t *buf)
747
748
{
  size_t len2;
Roger Dingledine's avatar
Roger Dingledine committed
749

750
  /* There must be string_len bytes in buf; write them onto string,
751
752
753
   * then memmove buf back (that is, remove them from buf).
   *
   * Return the number of bytes still on the buffer. */
Roger Dingledine's avatar
Roger Dingledine committed
754

Roger Dingledine's avatar
Roger Dingledine committed
755
756
757
  tor_assert(string);
  tor_assert(string_len <= buf->datalen); /* make sure we don't ask for too much */
  assert_buf_ok(buf);
Roger Dingledine's avatar
Roger Dingledine committed
758

759
  _split_range(buf, buf->cur, &string_len, &len2);
760

761
  memcpy(string, buf->cur, string_len);
762
763
764
765
766
767
768
769
770
  if (len2) {
    memcpy(string+string_len,buf->mem,len2);
  }
}

/** Remove <b>string_len</b> bytes from the front of <b>buf</b>, and store them
 * into <b>string</b>.  Return the new buffer size.  <b>string_len</b> must be \<=
 * the number of bytes on the buffer.
 */
771
772
int
fetch_from_buf(char *string, size_t string_len, buf_t *buf)
773
774
775
776
777
778
{
  /* There must be string_len bytes in buf; write them onto string,
   * then memmove buf back (that is, remove them from buf).
   *
   * Return the number of bytes still on the buffer. */

779
  check();
780
  peek_from_buf(string, string_len, buf);
781
  buf_remove_from_front(buf, string_len);
782
  check();
783
  return buf->datalen;
Roger Dingledine's avatar
Roger Dingledine committed
784
785
}

Roger Dingledine's avatar
Roger Dingledine committed
786
/** There is a (possibly incomplete) http statement on <b>buf</b>, of the
787
 * form "\%s\\r\\n\\r\\n\%s", headers, body. (body may contain nuls.)
788
789
790
 * If a) the headers include a Content-Length field and all bytes in
 * the body are present, or b) there's no Content-Length field and
 * all headers are present, then:
791
 *
Roger Dingledine's avatar
Roger Dingledine committed
792
793
794
 *  - strdup headers into <b>*headers_out</b>, and nul-terminate it.
 *  - memdup body into <b>*body_out</b>, and nul-terminate it.
 *  - Then remove them from <b>buf</b>, and return 1.
795
796
797
 *
 *  - If headers or body is NULL, discard that part of the buf.
 *  - If a headers or body doesn't fit in the arg, return -1.
798
799
 *  (We ensure that the headers or body don't exceed max len,
 *   _even if_ we're planning to discard them.)
Roger Dingledine's avatar
Roger Dingledine committed
800
 *
801
802
 * Else, change nothing and return 0.
 */
803
804
805
806
807
int
fetch_from_buf_http(buf_t *buf,
                    char **headers_out, size_t max_headerlen,
                    char **body_out, size_t *body_used, size_t max_bodylen)
{
Nick Mathewson's avatar
Nick Mathewson committed
808
  char *headers, *body, *p;
809
  size_t headerlen, bodylen, contentlen;
810

Roger Dingledine's avatar
Roger Dingledine committed
811
  assert_buf_ok(buf);
812
  buf_normalize(buf);
813

Nick Mathewson's avatar
Nick Mathewson committed
814
815
816
817
  if (buf_nul_terminate(buf)<0) {
    log_fn(LOG_WARN,"Couldn't nul-terminate buffer");
    return -1;
  }
818
  headers = buf->cur;
Nick Mathewson's avatar
Nick Mathewson committed
819
820
  body = strstr(headers,"\r\n\r\n");
  if (!body) {
821
822
823
    log_fn(LOG_DEBUG,"headers not all here yet.");
    return 0;
  }
Nick Mathewson's avatar
Nick Mathewson committed
824
  body += 4; /* Skip the the CRLFCRLF */
825
  headerlen = body-headers; /* includes the CRLFCRLF */
826
  bodylen = buf->datalen - headerlen;
827
  log_fn(LOG_DEBUG,"headerlen %d, bodylen %d.", (int)headerlen, (int)bodylen);
828

829
  if (max_headerlen <= headerlen) {
830
831
    log_fn(LOG_WARN,"headerlen %d larger than %d. Failing.", (int)headerlen,
           (int)max_headerlen-1);
832
833
    return -1;
  }
834
  if (max_bodylen <= bodylen) {
835
    log_fn(LOG_WARN,"bodylen %d larger than %d. Failing.", (int)bodylen, (int)max_bodylen-1);
836
837
838
    return -1;
  }

839
#define CONTENT_LENGTH "\r\nContent-Length: "
Nick Mathewson's avatar
Nick Mathewson committed
840
841
  p = strstr(headers, CONTENT_LENGTH);
  if (p) {
842
843
844
    int i;
    i = atoi(p+strlen(CONTENT_LENGTH));
    if (i < 0) {
Nick Mathewson's avatar
Nick Mathewson committed
845
846
847
      log_fn(LOG_WARN, "Content-Length is less than zero; it looks like someone is trying to crash us.");
      return -1;
    }
848
    contentlen = i;
849
    /* if content-length is malformed, then our body length is 0. fine. */
850
    log_fn(LOG_DEBUG,"Got a contentlen of %d.",(int)contentlen);
851
    if (bodylen < contentlen) {
852
853
854
      log_fn(LOG_DEBUG,"body not all here yet.");
      return 0; /* not all there yet */
    }
855
    if (bodylen > contentlen) {
856
      bodylen = contentlen;
857
      log_fn(LOG_DEBUG,"bodylen reduced to %d.",(int)bodylen);
858
    }
859
860
  }
  /* all happy. copy into the appropriate places, and return 1 */
861
  if (headers_out) {
862
    *headers_out = tor_malloc(headerlen+1);
863
    memcpy(*headers_out,buf->cur,headerlen);
864
    (*headers_out)[headerlen] = 0; /* null terminate it */
865
  }
866
  if (body_out) {
Roger Dingledine's avatar
Roger Dingledine committed
867
    tor_assert(body_used);
868
    *body_used = bodylen;
869
    *body_out = tor_malloc(bodylen+1);
870
    memcpy(*body_out,buf->cur+headerlen,bodylen);
871
    (*body_out)[bodylen] = 0; /* null terminate it */
872
  }
873
  buf_remove_from_front(buf, headerlen+bodylen);
874
875
876
  return 1;
}

Roger Dingledine's avatar
Roger Dingledine committed
877
/** There is a (possibly incomplete) socks handshake on <b>buf</b>, of one
Roger Dingledine's avatar
Roger Dingledine committed
878
 * of the forms
879
880
881
882
 *  - socks4: "socksheader username\\0"
 *  - socks4a: "socksheader username\\0 destaddr\\0"
 *  - socks5 phase one: "version #methods methods"
 *  - socks5 phase two: "version command 0 addresstype..."
883
884
 * If it's a complete and valid handshake, and destaddr fits in
 *   MAX_SOCKS_ADDR_LEN bytes, then pull the handshake off the buf,
Roger Dingledine's avatar
Roger Dingledine committed
885
 *   assign to <b>req</b>, and return 1.
886
 *
887
 * If it's invalid or too big, return -1.
888
 *
Roger Dingledine's avatar
Roger Dingledine committed
889
 * Else it's not all there yet, leave buf alone and return 0.
890
 *
Roger Dingledine's avatar
Roger Dingledine committed
891
892
 * If you want to specify the socks reply, write it into <b>req->reply</b>
 *   and set <b>req->replylen</b>, else leave <b>req->replylen</b> alone.
893
 *
Roger Dingledine's avatar
Roger Dingledine committed
894
 * If returning 0 or -1, <b>req->address</b> and <b>req->port</b> are undefined.
895
 */
896
897
898
int
fetch_from_buf_socks(buf_t *buf, socks_request_t *req)
{
Roger Dingledine's avatar
Roger Dingledine committed
899
  unsigned char len;
900
  char tmpbuf[INET_NTOA_BUF_LEN];
Roger Dingledine's avatar
Roger Dingledine committed
901
902
  uint32_t destip;
  enum {socks4, socks4a} socks4_prot = socks4a;
903
  char *next, *startaddr;
Roger Dingledine's avatar
Roger Dingledine committed
904
  struct in_addr in;
905

906
907
908
909
  /* If the user connects with socks4 or the wrong variant of socks5,
   * then log a warning to let him know that it might be unwise. */
  static int have_warned_about_unsafe_socks = 0;

910
  if (buf->datalen < 2) /* version and another byte */
911
    return 0;
912
913
  buf_normalize(buf);

914
  switch (*(buf->cur)) { /* which version of socks? */
Roger Dingledine's avatar
Roger Dingledine committed
915
916
917

    case 5: /* socks5 */

918
      if (req->socks_version != 5) { /* we need to negotiate a method */
919
        unsigned char nummethods = (unsigned char)*(buf->cur+1);
Roger Dingledine's avatar
Roger Dingledine committed
920
        tor_assert(!req->socks_version);
921
        if (buf->datalen < 2u+nummethods)
Roger Dingledine's avatar
Roger Dingledine committed
922
          return 0;
923
        if (!nummethods || !memchr(buf->cur+2, 0, nummethods)) {
Roger Dingledine's avatar
Roger Dingledine committed
924
          log_fn(LOG_WARN,"socks5: offered methods don't include 'no auth'. Rejecting.");
925
          req->replylen = 2; /* 2 bytes of response */
926
          req->reply[0] = 5;
927
          req->reply[1] = '\xFF'; /* reject all methods */
Roger Dingledine's avatar
Roger Dingledine committed
928
          return -1;
Roger Dingledine's avatar
Roger Dingledine committed
929
        }
930
        buf_remove_from_front(buf,2+nummethods);/* remove packet from buf */
Roger Dingledine's avatar
Roger Dingledine committed
931

932
933
        req->replylen = 2; /* 2 bytes of response */
        req->reply[0] = 5; /* socks5 reply */
934
        req->reply[1] = SOCKS5_SUCCEEDED;
935
        req->socks_version = 5; /* remember that we've already negotiated auth */
Roger Dingledine's avatar
Roger Dingledine committed
936
937
938
939
940
        log_fn(LOG_DEBUG,"socks5: accepted method 0");
        return 0;
      }
      /* we know the method; read in the request */
      log_fn(LOG_DEBUG,"socks5: checking request");
941
      if (buf->datalen < 8) /* basic info plus >=2 for addr plus 2 for port */
Roger Dingledine's avatar
Roger Dingledine committed
942
        return 0; /* not yet */
943
      req->command = (unsigned char) *(buf->cur+1);
944
      if (req->command != SOCKS_COMMAND_CONNECT &&