tor  0.4.2.0-alpha-dev
Data Structures | Macros | Typedefs | Functions | Variables
buffers.c File Reference
#include "orconfig.h"
#include <stddef.h>
#include "lib/buf/buffers.h"
#include "lib/cc/torint.h"
#include "lib/log/log.h"
#include "lib/log/util_bug.h"
#include "lib/ctime/di_ops.h"
#include "lib/malloc/malloc.h"
#include "lib/string/printf.h"
#include "lib/time/compat_time.h"
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

Go to the source code of this file.

Data Structures

struct  buf_pos_t
 

Macros

#define BUFFERS_PRIVATE
 
#define check()   STMT_NIL
 
#define CHUNK_HEADER_LEN   offsetof(chunk_t, mem[0])
 
#define SENTINEL_LEN   4
 
#define CHUNK_OVERHEAD   (CHUNK_HEADER_LEN + SENTINEL_LEN)
 
#define CHUNK_ALLOC_SIZE(memlen)   (CHUNK_OVERHEAD + (memlen))
 
#define CHUNK_SIZE_WITH_ALLOC(memlen)   ((memlen) - CHUNK_OVERHEAD)
 
#define DEBUG_SENTINEL
 
#define DBG_S(s)   s
 
#define CHUNK_SET_SENTINEL(chunk, alloclen)
 
#define MIN_CHUNK_ALLOC   256
 
#define MAX_CHUNK_ALLOC   65536
 

Typedefs

typedef struct buf_pos_t buf_pos_t
 

Functions

static void chunk_repack (chunk_t *chunk)
 
static void buf_chunk_free_unchecked (chunk_t *chunk)
 
static chunk_t * chunk_new_with_alloc_size (size_t alloc)
 
static chunk_t * chunk_grow (chunk_t *chunk, size_t sz)
 
size_t buf_preferred_chunk_size (size_t target)
 
void buf_pullup (buf_t *buf, size_t bytes, const char **head_out, size_t *len_out)
 
void buf_drain (buf_t *buf, size_t n)
 
buf_t * buf_new_with_capacity (size_t size)
 
buf_t * buf_new (void)
 
size_t buf_get_default_chunk_size (const buf_t *buf)
 
void buf_clear (buf_t *buf)
 
 MOCK_IMPL (size_t, buf_datalen,(const buf_t *buf))
 
size_t buf_allocation (const buf_t *buf)
 
size_t buf_slack (const buf_t *buf)
 
void buf_free_ (buf_t *buf)
 
static chunk_t * chunk_copy (const chunk_t *in_chunk)
 
buf_t * buf_copy (const buf_t *buf)
 
chunk_t * buf_add_chunk_with_capacity (buf_t *buf, size_t capacity, int capped)
 
uint32_t buf_get_oldest_chunk_timestamp (const buf_t *buf, uint32_t now)
 
size_t buf_get_total_allocation (void)
 
int buf_add (buf_t *buf, const char *string, size_t string_len)
 
void buf_add_string (buf_t *buf, const char *string)
 
void buf_add_printf (buf_t *buf, const char *format,...)
 
void buf_add_vprintf (buf_t *buf, const char *format, va_list args)
 
char * buf_extract (buf_t *buf, size_t *sz_out)
 
void buf_peek (const buf_t *buf, char *string, size_t string_len)
 
int buf_get_bytes (buf_t *buf, char *string, size_t string_len)
 
int buf_move_to_buf (buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen)
 
void buf_move_all (buf_t *buf_out, buf_t *buf_in)
 
static void buf_pos_init (const buf_t *buf, buf_pos_t *out)
 
static off_t buf_find_pos_of_char (char ch, buf_pos_t *out)
 
static int buf_pos_inc (buf_pos_t *pos)
 
static int buf_matches_at_pos (const buf_pos_t *pos, const char *s, size_t n)
 
int buf_find_string_offset (const buf_t *buf, const char *s, size_t n)
 
int buf_peek_startswith (const buf_t *buf, const char *cmd)
 
static off_t buf_find_offset_of_char (buf_t *buf, char ch)
 
int buf_get_line (buf_t *buf, char *data_out, size_t *data_len)
 
int buf_set_to_copy (buf_t **output, const buf_t *input)
 
void buf_assert_ok (buf_t *buf)
 

Variables

static size_t total_bytes_allocated_in_chunks = 0
 

Detailed Description

Implements a generic buffer interface.

A buf_t is a (fairly) opaque byte-oriented FIFO that can read to or flush from memory, sockets, file descriptors, TLS connections, or another buf_t. Buffers are implemented as linked lists of memory chunks.

All socket-backed and TLS-based connection_t objects have a pair of buffers: one for incoming data, and one for outcoming data. These are fed and drained from functions in connection.c, trigged by events that are monitored in main.c.

This module only handles the buffer implementation itself. To use a buffer with the network, a compressor, or a TLS connection, see the other buffer_* modules.

Definition in file buffers.c.

Macro Definition Documentation

◆ CHUNK_ALLOC_SIZE

#define CHUNK_ALLOC_SIZE (   memlen)    (CHUNK_OVERHEAD + (memlen))

Return the number of bytes needed to allocate a chunk to hold memlen bytes.

Definition at line 89 of file buffers.c.

◆ CHUNK_SET_SENTINEL

#define CHUNK_SET_SENTINEL (   chunk,
  alloclen 
)
Value:
do { \
uint8_t *a = (uint8_t*) &(chunk)->mem[(chunk)->memlen]; \
DBG_S(uint8_t *b = &((uint8_t*)(chunk))[(alloclen)-SENTINEL_LEN]); \
DBG_S(tor_assert(a == b)); \
memset(a,0,SENTINEL_LEN); \
} while (0)
tor_assert(buffer)
#define SENTINEL_LEN
Definition: memarea.c:58

Definition at line 105 of file buffers.c.

◆ CHUNK_SIZE_WITH_ALLOC

#define CHUNK_SIZE_WITH_ALLOC (   memlen)    ((memlen) - CHUNK_OVERHEAD)

Return the number of usable bytes in a chunk allocated with malloc(memlen).

Definition at line 92 of file buffers.c.

◆ MAX_CHUNK_ALLOC

#define MAX_CHUNK_ALLOC   65536

No chunk should take up more than this many bytes.

Definition at line 182 of file buffers.c.

◆ MIN_CHUNK_ALLOC

#define MIN_CHUNK_ALLOC   256

Every chunk should take up at least this many bytes.

Definition at line 180 of file buffers.c.

Typedef Documentation

◆ buf_pos_t

typedef struct buf_pos_t buf_pos_t

Internal structure: represents a position in a buffer.

Function Documentation

◆ buf_add()

int buf_add ( buf_t *  buf,
const char *  string,
size_t  string_len 
)

Append string_len bytes from string to the end of buf.

Return the new length of the buffer on success, -1 on failure.

Definition at line 525 of file buffers.c.

Referenced by buf_add_string(), buf_add_vprintf(), MOCK_IMPL(), and process_write().

◆ buf_add_chunk_with_capacity()

chunk_t* buf_add_chunk_with_capacity ( buf_t *  buf,
size_t  capacity,
int  capped 
)

Append a new chunk with enough capacity to hold capacity bytes to the tail of buf. If capped, don't allocate a chunk bigger than MAX_CHUNK_ALLOC.

Definition at line 473 of file buffers.c.

References CHUNK_ALLOC_SIZE.

Referenced by buf_add_compress().

◆ buf_add_printf()

void buf_add_printf ( buf_t *  buf,
const char *  format,
  ... 
)

As tor_snprintf, but write the results into a buf_t

Definition at line 566 of file buffers.c.

References buf_add_vprintf().

◆ buf_add_string()

void buf_add_string ( buf_t *  buf,
const char *  string 
)

Add a nul-terminated string to buf, not including the terminating NUL.

Definition at line 559 of file buffers.c.

References buf_add().

◆ buf_add_vprintf()

void buf_add_vprintf ( buf_t *  buf,
const char *  format,
va_list  args 
)

As tor_vsnprintf, but write the results into a buf_t.

Definition at line 576 of file buffers.c.

References buf_add(), tor_free, and tor_vasprintf().

Referenced by buf_add_printf().

◆ buf_allocation()

size_t buf_allocation ( const buf_t *  buf)

Return the total length of all chunks used in buf.

Definition at line 399 of file buffers.c.

References CHUNK_ALLOC_SIZE.

◆ buf_assert_ok()

void buf_assert_ok ( buf_t *  buf)

Log an error and exit if buf is corrupted.

Definition at line 899 of file buffers.c.

References tor_assert().

◆ buf_clear()

void buf_clear ( buf_t *  buf)

Remove all data from buf.

Definition at line 379 of file buffers.c.

Referenced by buf_free_().

◆ buf_copy()

buf_t* buf_copy ( const buf_t *  buf)

Return a new copy of buf

Definition at line 451 of file buffers.c.

References buf_new(), and chunk_copy().

◆ buf_drain()

void buf_drain ( buf_t *  buf,
size_t  n 
)

Remove the first n bytes from buf.

Definition at line 328 of file buffers.c.

References tor_assert().

Referenced by flush_chunk_tls().

◆ buf_extract()

char* buf_extract ( buf_t *  buf,
size_t *  sz_out 
)

Return a heap-allocated string containing the contents of buf, plus a NUL byte. If sz_out is provided, set *sz_out to the length of the returned string, not including the terminating NUL.

Definition at line 589 of file buffers.c.

References tor_assert().

◆ buf_find_offset_of_char()

static off_t buf_find_offset_of_char ( buf_t *  buf,
char  ch 
)
static

Return the index within buf at which ch first appears, or -1 if ch does not appear on buf.

Definition at line 840 of file buffers.c.

References tor_assert().

Referenced by buf_get_line().

◆ buf_find_pos_of_char()

static off_t buf_find_pos_of_char ( char  ch,
buf_pos_t out 
)
static

Advance out to the first appearance of ch at the current position of out, or later. Return -1 if no instances are found; otherwise returns the absolute position of the character.

Definition at line 730 of file buffers.c.

References buf_pos_t::chunk, buf_pos_t::chunk_pos, buf_pos_t::pos, and tor_assert().

Referenced by buf_find_string_offset().

◆ buf_find_string_offset()

int buf_find_string_offset ( const buf_t *  buf,
const char *  s,
size_t  n 
)

Return the first position in buf at which the n-character string s occurs, or -1 if it does not occur.

Definition at line 804 of file buffers.c.

References buf_find_pos_of_char(), buf_matches_at_pos(), buf_pos_inc(), buf_pos_init(), buf_pos_t::chunk_pos, buf_pos_t::pos, and tor_assert().

◆ buf_free_()

void buf_free_ ( buf_t *  buf)

Release storage held by buf.

Definition at line 422 of file buffers.c.

References buf_clear(), and tor_free.

◆ buf_get_bytes()

int buf_get_bytes ( buf_t *  buf,
char *  string,
size_t  string_len 
)

Remove string_len bytes from the front of buf, and store them into string. Return the new buffer size. string_len must be <= the number of bytes on the buffer.

Definition at line 634 of file buffers.c.

Referenced by buf_get_line(), and connection_buf_get_bytes().

◆ buf_get_line()

int buf_get_line ( buf_t *  buf,
char *  data_out,
size_t *  data_len 
)

Try to read a single LF-terminated line from buf, and write it (including the LF), NUL-terminated, into the *data_len byte buffer at data_out. Set *data_len to the number of bytes in the line, not counting the terminating NUL. Return 1 if we read a whole line, return 0 if we don't have a whole line yet, and return -1 if the line length exceeds *data_len.

Definition at line 863 of file buffers.c.

References buf_find_offset_of_char(), and buf_get_bytes().

Referenced by connection_buf_get_line().

◆ buf_get_oldest_chunk_timestamp()

uint32_t buf_get_oldest_chunk_timestamp ( const buf_t *  buf,
uint32_t  now 
)

Return the age of the oldest chunk in the buffer buf, in timestamp units. Requires the current monotonic timestamp as its input now.

Definition at line 504 of file buffers.c.

Referenced by conn_get_buffer_age().

◆ buf_matches_at_pos()

static int buf_matches_at_pos ( const buf_pos_t pos,
const char *  s,
size_t  n 
)
static

Return true iff the n-character string in s appears (verbatim) at pos.

Definition at line 778 of file buffers.c.

References buf_pos_inc(), buf_pos_t::chunk, and buf_pos_t::pos.

Referenced by buf_find_string_offset().

◆ buf_move_all()

void buf_move_all ( buf_t *  buf_out,
buf_t *  buf_in 
)

Moves all data from buf_in to buf_out, without copying.

Definition at line 687 of file buffers.c.

References tor_assert().

Referenced by connection_buf_add_buf().

◆ buf_move_to_buf()

int buf_move_to_buf ( buf_t *  buf_out,
buf_t *  buf_in,
size_t *  buf_flushlen 
)

Move up to *buf_flushlen bytes from buf_in to buf_out, and modify *buf_flushlen appropriately. Return the number of bytes actually copied.

Definition at line 654 of file buffers.c.

◆ buf_new()

buf_t* buf_new ( void  )

Allocate and return a new buffer with default capacity.

Definition at line 363 of file buffers.c.

Referenced by buf_copy(), and buf_new_with_capacity().

◆ buf_new_with_capacity()

buf_t* buf_new_with_capacity ( size_t  size)

Create and return a new buf with default chunk capacity size.

Definition at line 354 of file buffers.c.

References buf_new(), and buf_preferred_chunk_size().

◆ buf_peek()

void buf_peek ( const buf_t *  buf,
char *  string,
size_t  string_len 
)

Helper: copy the first string_len bytes from buf onto string.

Definition at line 607 of file buffers.c.

References tor_assert().

◆ buf_peek_startswith()

int buf_peek_startswith ( const buf_t *  buf,
const char *  cmd 
)

Return 1 iff buf starts with cmd. cmd must be a null terminated string, of no more than PEEK_BUF_STARTSWITH_MAX bytes.

Definition at line 823 of file buffers.c.

◆ buf_pos_inc()

static int buf_pos_inc ( buf_pos_t pos)
inlinestatic

Advance pos by a single character, if there are any more characters in the buffer. Returns 0 on success, -1 on failure.

Definition at line 761 of file buffers.c.

References buf_pos_t::chunk, buf_pos_t::chunk_pos, buf_pos_t::pos, and tor_assert().

Referenced by buf_find_string_offset(), and buf_matches_at_pos().

◆ buf_pos_init()

static void buf_pos_init ( const buf_t *  buf,
buf_pos_t out 
)
static

Initialize out to point to the first character of buf.

Definition at line 719 of file buffers.c.

References buf_pos_t::chunk, buf_pos_t::chunk_pos, and buf_pos_t::pos.

Referenced by buf_find_string_offset().

◆ buf_preferred_chunk_size()

size_t buf_preferred_chunk_size ( size_t  target)

Return the allocation size we'd like to use to hold target bytes.

Definition at line 187 of file buffers.c.

References SIZE_T_CEILING, and tor_assert().

Referenced by buf_new_with_capacity().

◆ buf_pullup()

void buf_pullup ( buf_t *  buf,
size_t  bytes,
const char **  head_out,
size_t *  len_out 
)

Collapse data from the first N chunks from buf into buf->head, growing it as necessary, until buf->head has the first bytes bytes of data from the buffer, or until buf->head has all the data in buf.

Set *head_out to point to the first byte of available data, and *len_out to the number of bytes of data available at *head_out. Note that *len_out may be more or less than bytes, depending on the number of bytes available.

Definition at line 209 of file buffers.c.

◆ buf_set_to_copy()

int buf_set_to_copy ( buf_t **  output,
const buf_t *  input 
)

Set *output to contain a copy of the data in *input

Definition at line 887 of file buffers.c.

◆ buf_slack()

size_t buf_slack ( const buf_t *  buf)

Return the number of bytes that can be added to buf without performing any additional allocation.

Definition at line 412 of file buffers.c.

Referenced by connection_buf_read_from_socket().

◆ chunk_copy()

static chunk_t* chunk_copy ( const chunk_t *  in_chunk)
static

Return a new copy of in_chunk

Definition at line 434 of file buffers.c.

Referenced by buf_copy().

◆ chunk_grow()

static chunk_t* chunk_grow ( chunk_t *  chunk,
size_t  sz 
)
inlinestatic

Expand chunk until it can hold sz bytes, and return a new pointer to chunk. Old pointers are no longer valid.

Definition at line 159 of file buffers.c.

References CHUNK_ALLOC_SIZE, and tor_assert().

◆ chunk_repack()

static void chunk_repack ( chunk_t *  chunk)
inlinestatic

Move all bytes stored in chunk to the front of chunk->mem, to free up space at the end.

Definition at line 116 of file buffers.c.

◆ MOCK_IMPL()

MOCK_IMPL ( size_t  ,
buf_datalen  ,
(const buf_t *buf)   
)

Return the number of bytes stored in buf

Definition at line 391 of file buffers.c.

Variable Documentation

◆ total_bytes_allocated_in_chunks

size_t total_bytes_allocated_in_chunks = 0
static

Keep track of total size of allocated chunks for consistency asserts

Definition at line 125 of file buffers.c.