Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
David Goulet
Tor
Commits
c6d4a00c
Commit
c6d4a00c
authored
May 09, 2004
by
Roger Dingledine
Browse files
more doxygen markup
plenty more remains svn:r1824
parent
b384c5a1
Changes
14
Hide whitespace changes
Inline
Side-by-side
src/or/buffers.c
View file @
c6d4a00c
/* Copyright 2001
,
200
2,
200
3
Roger Dingledine
, Matej Pfajfar
. */
/* Copyright 2001
Matej Pfajfar,
200
1-
200
4
Roger Dingledine. */
/* See LICENSE for licensing information */
/* $Id$ */
...
...
@@ -13,8 +13,8 @@
struct
buf_t
{
uint32_t
magic
;
/**< Magic cookie for debugging: Must be set to BUFFER_MAGIC */
char
*
mem
;
/**< Storage for data in the buffer */
size_t
len
;
/**< Maximum amount of data that
'mem'
can hold. */
size_t
datalen
;
/**< Number of bytes currently in
'mem'
. */
size_t
len
;
/**< Maximum amount of data that
<b>mem</b>
can hold. */
size_t
datalen
;
/**< Number of bytes currently in
<b>mem</b>
. */
};
/** Size, in bytes, for newly allocated buffers. Should be a power of 2. */
...
...
@@ -26,7 +26,7 @@ struct buf_t {
* than this size. */
#define MIN_BUF_SHRINK_SIZE (16*1024)
/** Change a buffer's capacity.
new_capacity must be \<= buf->datalen. */
/** Change a buffer's capacity.
<b>
new_capacity
</b>
must be \<= buf->datalen. */
static
INLINE
void
buf_resize
(
buf_t
*
buf
,
size_t
new_capacity
)
{
tor_assert
(
buf
->
datalen
<=
new_capacity
);
...
...
@@ -35,7 +35,7 @@ static INLINE void buf_resize(buf_t *buf, size_t new_capacity)
buf
->
len
=
new_capacity
;
}
/** If the buffer is not large enough to hold
"
capacity
"
bytes, resize
/** If the buffer is not large enough to hold
<b>
capacity
</b>
bytes, resize
* it so that it can. (The new size will be a power of 2 times the old
* size.)
*/
...
...
@@ -82,7 +82,7 @@ static INLINE void buf_shrink_if_underfull(buf_t *buf) {
buf_resize
(
buf
,
new_len
);
}
/** Remove the first
'n'
bytes from buf.
/** Remove the first
<b>n</b>
bytes from buf.
*/
static
INLINE
void
buf_remove_from_front
(
buf_t
*
buf
,
size_t
n
)
{
tor_assert
(
buf
->
datalen
>=
n
);
...
...
@@ -91,8 +91,8 @@ static INLINE void buf_remove_from_front(buf_t *buf, size_t n) {
buf_shrink_if_underfull
(
buf
);
}
/** Find the first instance of the str_len byte string
'sr'
on the
* buf_len byte string
'
bufstr
'
. Strings are not necessary
/** Find the first instance of the str_len byte string
<b>str</b>
on the
* buf_len byte string
<b>
bufstr
</b>
. Strings are not necessary
* NUL-terminated. If none exists, return -1. Otherwise, return index
* of the first character in bufstr _after_ the first instance of str.
*/
...
...
@@ -116,7 +116,7 @@ static int find_mem_in_mem(const char *str, int str_len,
return
-
1
;
}
/** Create and return a new buf with capacity
'
size
'
.
/** Create and return a new buf with capacity
<b>
size
</b>
.
*/
buf_t
*
buf_new_with_capacity
(
size_t
size
)
{
buf_t
*
buf
;
...
...
@@ -137,33 +137,33 @@ buf_t *buf_new()
return
buf_new_with_capacity
(
INITIAL_BUF_SIZE
);
}
/** Remove all data from
'buf'
*/
/** Remove all data from
<b>buf</b>
*/
void
buf_clear
(
buf_t
*
buf
)
{
buf
->
datalen
=
0
;
}
/** Return the number of bytes stored in
'buf'
*/
/** Return the number of bytes stored in
<b>buf</b>
*/
size_t
buf_datalen
(
const
buf_t
*
buf
)
{
return
buf
->
datalen
;
}
/** Return the maximum bytes that can be stored in
'buf'
before buf
/** Return the maximum bytes that can be stored in
<b>buf</b>
before buf
* needs to resize. */
size_t
buf_capacity
(
const
buf_t
*
buf
)
{
return
buf
->
len
;
}
/** For testing only: Return a pointer to the raw memory stored in
'buf'
.
/** For testing only: Return a pointer to the raw memory stored in
<b>buf</b>
.
*/
const
char
*
_buf_peek_raw_buffer
(
const
buf_t
*
buf
)
{
return
buf
->
mem
;
}
/** Release storage held by
'buf'
.
/** Release storage held by
<b>buf</b>
.
*/
void
buf_free
(
buf_t
*
buf
)
{
assert_buf_ok
(
buf
);
...
...
@@ -172,9 +172,9 @@ void buf_free(buf_t *buf) {
tor_free
(
buf
);
}
/** Read from socket
s
, writing onto end of
buf
. Read at most
*
'
at_most
'
bytes, resizing the buffer as necessary. If read()
* returns 0, set *reached_eof to 1 and return 0. Return -1 on error;
/** Read from socket
<b>s</s>
, writing onto end of
<b>buf</b>
. Read at most
*
<b>
at_most
</b>
bytes, resizing the buffer as necessary. If read()
* returns 0, set
<b>
*reached_eof
</b>
to 1 and return 0. Return -1 on error;
* else return the number of bytes read. Return 0 if read() would
* block.
*/
...
...
@@ -247,17 +247,14 @@ int read_to_buf_tls(tor_tls *tls, size_t at_most, buf_t *buf) {
return
r
;
}
/** Write data from 'buf' to the socket 's'. Write at most
* *buf_flushlen bytes, and decrement *buf_flushlen by the number of
* bytes actually written. Return the number of bytes written on
* success, -1 on failure. Return 0 if write() would block.
/** 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.
*/
int
flush_buf
(
int
s
,
buf_t
*
buf
,
int
*
buf_flushlen
)
{
/* push from buf onto s
* then memmove to front of buf
* return -1 or how many bytes you just flushed */
int
write_result
;
assert_buf_ok
(
buf
);
...
...
@@ -306,7 +303,9 @@ int flush_buf_tls(tor_tls *tls, buf_t *buf, int *buf_flushlen)
return
r
;
}
/** Append string_len bytes from 'string' to the end of 'buf'.
/** Append <b>string_len</b> bytes from <b>string</b> to the end of
* <b>buf</b>.
*
* Return the new length of the buffer on success, -1 on failure.
*/
int
write_to_buf
(
const
char
*
string
,
int
string_len
,
buf_t
*
buf
)
{
...
...
@@ -329,9 +328,8 @@ int write_to_buf(const char *string, int string_len, buf_t *buf) {
return
buf
->
datalen
;
}
/* Remove string_len bytes from the front of 'buf', and store them
* into 'string'. Return the new buffer size. string_len must be <=
/** 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.
*/
int
fetch_from_buf
(
char
*
string
,
size_t
string_len
,
buf_t
*
buf
)
{
...
...
@@ -350,15 +348,15 @@ int fetch_from_buf(char *string, size_t string_len, buf_t *buf) {
return
buf
->
datalen
;
}
/** There is a (possibly incomplete) http statement on
*buf
, of the
/** There is a (possibly incomplete) http statement on
<b>buf</b>
, of the
* form "\%s\\r\\n\\r\\n\%s", headers, body. (body may contain nuls.)
* 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:
*
* - strdup headers into *headers_out, and nul-terminate it.
* - memdup body into *body_out, and nul-terminate it.
* - Then remove them from
buf
, and return 1.
* - 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.
*
* - 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.
...
...
@@ -427,7 +425,7 @@ int fetch_from_buf_http(buf_t *buf,
return
1
;
}
/** There is a (possibly incomplete) socks handshake on
buf
, of one
/** There is a (possibly incomplete) socks handshake on
<b>buf</b>
, of one
* of the forms
* - socks4: "socksheader username\\0"
* - socks4a: "socksheader username\\0 destaddr\\0"
...
...
@@ -435,16 +433,16 @@ int fetch_from_buf_http(buf_t *buf,
* - socks5 phase two: "version command 0 addresstype..."
* If it's a complete and valid handshake, and destaddr fits in
* MAX_SOCKS_ADDR_LEN bytes, then pull the handshake off the buf,
* assign to
req
, and return 1.
* assign to
<b>req</b>
, and return 1.
*
* If it's invalid or too big, return -1.
*
* Else it's not all there yet, leave buf alone and return 0.
*
* If you want to specify the socks reply, write it into req->reply
* and set req->replylen, else leave req->replylen alone.
* 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.
*
* If returning 0 or -1, req->address and req->port are undefined.
* If returning 0 or -1,
<b>
req->address
</b>
and
<b>
req->port
</b>
are undefined.
*/
int
fetch_from_buf_socks
(
buf_t
*
buf
,
socks_request_t
*
req
)
{
unsigned
char
len
;
...
...
@@ -618,7 +616,7 @@ int fetch_from_buf_socks(buf_t *buf, socks_request_t *req) {
}
}
/** Log an error and exit if
'buf'
is corrupted.
/** Log an error and exit if
<b>buf</b>
is corrupted.
*/
void
assert_buf_ok
(
buf_t
*
buf
)
{
...
...
@@ -628,7 +626,6 @@ void assert_buf_ok(buf_t *buf)
tor_assert
(
buf
->
datalen
<=
buf
->
len
);
}
/*
Local Variables:
mode:c
...
...
src/or/command.c
View file @
c6d4a00c
...
...
@@ -2,26 +2,31 @@
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file command.c
* \brief Functions for processing incoming cells
**/
#include
"or.h"
extern
or_options_t
options
;
/* command-line and config-file options */
extern
or_options_t
options
;
/*
*<
command-line and config-file options */
/* keep statistics about how many of each type of cell we've received */
/*
*
keep statistics about how many of each type of cell we've received */
unsigned
long
stats_n_padding_cells_processed
=
0
;
unsigned
long
stats_n_create_cells_processed
=
0
;
unsigned
long
stats_n_created_cells_processed
=
0
;
unsigned
long
stats_n_relay_cells_processed
=
0
;
unsigned
long
stats_n_destroy_cells_processed
=
0
;
/* These are the main four functions for processing cells */
/*
*
These are the main four functions for processing cells */
static
void
command_process_create_cell
(
cell_t
*
cell
,
connection_t
*
conn
);
static
void
command_process_created_cell
(
cell_t
*
cell
,
connection_t
*
conn
);
static
void
command_process_relay_cell
(
cell_t
*
cell
,
connection_t
*
conn
);
static
void
command_process_destroy_cell
(
cell_t
*
cell
,
connection_t
*
conn
);
/* This is a wrapper function around the actual function that processes
*
'
cell
'
that just arrived on
'
conn
'
. Increment *time
by the number of
* microseconds used by the call to *func(cell, conn).
/*
*
This is a wrapper function around the actual function that processes
the
*
<b>
cell
</b>
that just arrived on
<b>
conn
</b>
. Increment
<b>
*time
</b>
*
by the number of
microseconds used by the call to
<b>
*func(cell, conn)
</b>
.
*/
static
void
command_time_process_cell
(
cell_t
*
cell
,
connection_t
*
conn
,
int
*
time
,
void
(
*
func
)(
cell_t
*
,
connection_t
*
))
{
...
...
@@ -41,7 +46,7 @@ static void command_time_process_cell(cell_t *cell, connection_t *conn, int *tim
*
time
+=
time_passed
;
}
/* Process a cell that was just received on conn. Keep internal
/*
*
Process a
<b>
cell
</b>
that was just received on
<b>
conn
</b>
. Keep internal
* statistics about how many of each cell we've processed so far
* this second, and the total number of microseconds it took to
* process each type of cell.
...
...
@@ -107,7 +112,7 @@ void command_process_cell(cell_t *cell, connection_t *conn) {
}
}
/* Process a 'create' cell that just arrived from conn. Make a new circuit
/*
*
Process a 'create'
<b>
cell
</b>
that just arrived from
<b>
conn
</b>
. Make a new circuit
* with the p_circ_id specified in cell. Put the circuit in state
* onionskin_pending, and pass the onionskin to the cpuworker. Circ will
* get picked up again when the cpuworker finishes decrypting it.
...
...
@@ -137,9 +142,9 @@ static void command_process_create_cell(cell_t *cell, connection_t *conn) {
log_fn
(
LOG_DEBUG
,
"success: handed off onionskin."
);
}
/* Process a 'created' cell that just arrived from conn. Find the circuit
* that it's intended for. If
you
're not the origin of the circuit, package
* the 'created' cell in an 'extended' relay cell and pass it back. If
you
/*
*
Process a 'created'
<b>
cell
</b>
that just arrived from
<b>
conn
</b>
. Find the circuit
* that it's intended for. If
we
're not the origin of the circuit, package
* the 'created' cell in an 'extended' relay cell and pass it back. If
we
* are the origin of the circuit, send it to circuit_finish_handshake() to
* finish processing keys, and then call circuit_send_next_onion_skin() to
* extend to the next hop in the circuit if necessary.
...
...
@@ -180,7 +185,7 @@ static void command_process_created_cell(cell_t *cell, connection_t *conn) {
}
}
/* Process a 'relay' cell that just arrived from conn. Make sure
/*
*
Process a 'relay'
<b>
cell
</b>
that just arrived from
<b>
conn
</b>
. Make sure
* it came in with a recognized circ_id. Pass it on to
* circuit_receive_relay_cell() for actual processing.
*/
...
...
@@ -216,8 +221,8 @@ static void command_process_relay_cell(cell_t *cell, connection_t *conn) {
}
}
/* Process a 'destroy' cell that just arrived from
conn. Find the
* circ that it refers to (if any).
/*
*
Process a 'destroy'
<b>
cell
</b>
that just arrived from
*
<b>conn</b>. Find the
circ that it refers to (if any).
*
* If the circ is in state
* onionskin_pending, then call onion_pending_remove() to remove it
...
...
src/or/connection_or.c
View file @
c6d4a00c
...
...
@@ -2,17 +2,23 @@
/* See LICENSE for licensing information */
/* $Id$ */
/**
* \file connection_or.c
* \brief Functions to handle OR connections, TLS handshaking, and
* cells on the network.
**/
#include
"or.h"
extern
or_options_t
options
;
/* command-line and config-file options */
extern
or_options_t
options
;
/*
*<
command-line and config-file options */
static
int
connection_tls_finish_handshake
(
connection_t
*
conn
);
static
int
connection_or_process_cells_from_inbuf
(
connection_t
*
conn
);
/**************************************************************/
/* Pack the cell_t host-order structure
'src'
into network-order
* in the buffer
'
dest
'
. See tor-spec.txt for details about the
/*
*
Pack the cell_t host-order structure
<b>src</b>
into network-order
* in the buffer
<b>
dest
</b>
. See tor-spec.txt for details about the
* wire format.
*/
static
void
cell_pack
(
char
*
dest
,
const
cell_t
*
src
)
{
...
...
@@ -21,8 +27,8 @@ static void cell_pack(char *dest, const cell_t *src) {
memcpy
(
dest
+
3
,
src
->
payload
,
CELL_PAYLOAD_SIZE
);
}
/* Unpack the network-order buffer
'src'
into a host-order
* cell_t structure
'
dest
'
.
/*
*
Unpack the network-order buffer
<b>src</b>
into a host-order
* cell_t structure
<b>
dest
</b>
.
*/
static
void
cell_unpack
(
cell_t
*
dest
,
const
char
*
src
)
{
dest
->
circ_id
=
ntohs
(
*
(
uint16_t
*
)(
src
));
...
...
@@ -30,9 +36,7 @@ static void cell_unpack(cell_t *dest, const char *src) {
memcpy
(
dest
->
payload
,
src
+
3
,
CELL_PAYLOAD_SIZE
);
}
/**************************************************************/
/* Handle any new bytes that have come in on connection 'conn'.
/** Handle any new bytes that have come in on connection <b>conn</b>.
* If conn is in 'open' state, hand it to
* connection_or_process_cells_from_inbuf()
* (else do nothing).
...
...
@@ -52,7 +56,7 @@ int connection_or_process_inbuf(connection_t *conn) {
return
connection_or_process_cells_from_inbuf
(
conn
);
}
/* Connection
'
conn
'
has finished writing and has no bytes left on
/*
*
Connection
<b>
conn
</b>
has finished writing and has no bytes left on
* its outbuf.
*
* If it's in state 'connecting', then take a look at the socket, and
...
...
@@ -68,7 +72,8 @@ int connection_or_finished_flushing(connection_t *conn) {
switch
(
conn
->
state
)
{
case
OR_CONN_STATE_CONNECTING
:
if
(
getsockopt
(
conn
->
s
,
SOL_SOCKET
,
SO_ERROR
,
(
void
*
)
&
e
,
&
len
)
<
0
)
{
/* not yet */
if
(
getsockopt
(
conn
->
s
,
SOL_SOCKET
,
SO_ERROR
,
(
void
*
)
&
e
,
&
len
)
<
0
)
{
/* not yet */
if
(
!
ERRNO_IS_CONN_EINPROGRESS
(
tor_socket_errno
(
conn
->
s
)))
{
log_fn
(
LOG_DEBUG
,
"in-progress connect failed. Removing."
);
connection_mark_for_close
(
conn
,
0
);
...
...
@@ -97,9 +102,7 @@ int connection_or_finished_flushing(connection_t *conn) {
}
}
/*********************/
/* Initialize conn to include all the relevant data from router.
/** Initialize <b>conn</b> to include all the relevant data from <b>router</b>.
* This function is called either from connection_or_connect(), if
* we initiated the connect, or from connection_tls_finish_handshake()
* if the other side initiated it.
...
...
@@ -115,11 +118,11 @@ connection_or_init_conn_from_router(connection_t *conn, routerinfo_t *router) {
conn
->
address
=
tor_strdup
(
router
->
address
);
}
/* Launch a new OR connection to
'
router
'
.
/*
*
Launch a new OR connection to
<b>
router
</b>
.
*
* If router is me, do nothing. If we're already connected to router,
* If
<b>
router
</b>
is me, do nothing. If we're already connected to
<b>
router
</b>
,
* return that connection. If the connect is in progress, set conn's
* state to 'connecting' and return. If connect to router succeeds, call
* state to 'connecting' and return. If connect to
<b>
router
</b>
succeeds, call
* connection_tls_start_handshake() on it.
*
* This function is called from router_retry_connections(), for
...
...
@@ -170,13 +173,13 @@ connection_t *connection_or_connect(routerinfo_t *router) {
return
NULL
;
}
/* Begin the tls handshake with conn
. '
receiving
'
is 0 if
we initiated
* the connection, else it's 1.
/*
*
Begin the tls handshake with
<b>
conn
</b>. <b>
receiving
</b>
is 0 if
*
we initiated
the connection, else it's 1.
*
* Assign a new tls object to conn->tls, begin reading on conn, and pass
* conn to connection_tls_continue_handshake().
* Assign a new tls object to conn->tls, begin reading on
<b>
conn
</b>
, and pass
*
<b>
conn
</b>
to connection_tls_continue_handshake().
*
* Return -1 if conn is broken, else return 0.
* Return -1 if
<b>
conn
</b>
is broken, else return 0.
*/
int
connection_tls_start_handshake
(
connection_t
*
conn
,
int
receiving
)
{
conn
->
state
=
OR_CONN_STATE_HANDSHAKING
;
...
...
@@ -193,10 +196,10 @@ int connection_tls_start_handshake(connection_t *conn, int receiving) {
return
0
;
}
/* Move forward with the tls handshake. If it finishes, hand
* conn to connection_tls_finish_handshake().
/*
*
Move forward with the tls handshake. If it finishes, hand
*
<b>
conn
</b>
to connection_tls_finish_handshake().
*
* Return -1 if conn is broken, else return 0.
* Return -1 if
<b>
conn
</b>
is broken, else return 0.
*/
int
connection_tls_continue_handshake
(
connection_t
*
conn
)
{
switch
(
tor_tls_handshake
(
conn
->
tls
))
{
...
...
@@ -217,7 +220,7 @@ int connection_tls_continue_handshake(connection_t *conn) {
return
0
;
}
/* The tls handshake is finished.
/*
*
The tls handshake is finished.
*
* Make sure we are happy with the person we just handshaked with:
* If it's an OP (that is, it has no certificate), make sure I'm an OR.
...
...
@@ -301,7 +304,7 @@ connection_tls_finish_handshake(connection_t *conn) {
return
0
;
}
/* Pack
'
cell
'
into wire-format, and write it onto conn's outbuf. */
/*
*
Pack
<b>
cell
</b>
into wire-format, and write it onto
<b>
conn
</b>
's outbuf. */
void
connection_or_write_cell_to_buf
(
const
cell_t
*
cell
,
connection_t
*
conn
)
{
char
networkcell
[
CELL_NETWORK_SIZE
];
char
*
n
=
networkcell
;
...
...
@@ -314,8 +317,11 @@ void connection_or_write_cell_to_buf(const cell_t *cell, connection_t *conn) {
connection_write_to_buf
(
n
,
CELL_NETWORK_SIZE
,
conn
);
}
/* Process cells from conn's inbuf. Loop: while inbuf contains a cell, pull
* it off the inbuf, unpack it, and hand it to command_process_cell().
/** Process cells from <b>conn</b>'s inbuf.
*
* Loop: while inbuf contains a cell, pull it off the inbuf, unpack it,
* and hand it to command_process_cell().
*
* Always return 0.
*/
static
int
connection_or_process_cells_from_inbuf
(
connection_t
*
conn
)
{
...
...
src/or/cpuworker.c
View file @
c6d4a00c
...
...
@@ -2,26 +2,34 @@
/* See LICENSE for licensing information */
/* $Id$ */
/*****
* cpuworker.c: Run computation-intensive tasks (generally for crypto) in
/**
* \file cpuworker.c
* \brief Run computation-intensive tasks (generally for crypto) in
* a separate execution context. [OR only.]
*
* Right now, we only use this for processing onionskins.
***
**/
**/
#include
"or.h"
extern
or_options_t
options
;
/* command-line and config-file options */
extern
or_options_t
options
;
/*
*<
command-line and config-file options */
/** The maximum number of cpuworker processes we will keep around */
#define MAX_CPUWORKERS 16
/** The minimum number of cpuworker processes we will keep around */
#define MIN_CPUWORKERS 1
/** The tag specifies which circuit this onionskin was from */
#define TAG_LEN 8
/** How many bytes are sent from tor to the cpuworker? */
#define LEN_ONION_QUESTION (1+TAG_LEN+ONIONSKIN_CHALLENGE_LEN)
/** How many bytes are sent from the cpuworker back to tor? */
#define LEN_ONION_RESPONSE (1+TAG_LEN+ONIONSKIN_REPLY_LEN+40+32)
/** How many cpuworkers we have running right now */
static
int
num_cpuworkers
=
0
;
/** How many of the running cpuworkers have an assigned task right now */
static
int
num_cpuworkers_busy
=
0
;
/* We need to spawn new cpuworkers whenever we rotate the onion keys
/*
*
We need to spawn new cpuworkers whenever we rotate the onion keys
* on platforms where execution contexts==processes. This variable stores
* the last time we got a key rotation event.*/
static
time_t
last_rotation_time
=
0
;
...
...
@@ -31,21 +39,21 @@ static int spawn_cpuworker(void);
static
void
spawn_enough_cpuworkers
(
void
);
static
void
process_pending_task
(
connection_t
*
cpuworker
);
/* Initialize the cpuworker subsystem.
/*
*
Initialize the cpuworker subsystem.
*/
void
cpu_init
(
void
)
{
last_rotation_time
=
time
(
NULL
);
spawn_enough_cpuworkers
();
}
/* Called when we're done sending a request to a cpuworker. */
/*
*
Called when we're done sending a request to a cpuworker. */
int
connection_cpu_finished_flushing
(
connection_t
*
conn
)
{
tor_assert
(
conn
&&
conn
->
type
==
CONN_TYPE_CPUWORKER
);
connection_stop_writing
(
conn
);
return
0
;
}
/* Pack addr,port,and circ_id; set *tag to the result. (See note on
/*
*
Pack addr,port,and circ_id; set *tag to the result. (See note on
* cpuworker_main for wire format.) */
static
void
tag_pack
(
char
*
tag
,
uint32_t
addr
,
uint16_t
port
,
uint16_t
circ_id
)
{
*
(
uint32_t
*
)
tag
=
addr
;
...
...
@@ -53,7 +61,7 @@ static void tag_pack(char *tag, uint32_t addr, uint16_t port, uint16_t circ_id)
*
(
uint16_t
*
)(
tag
+
6
)
=
circ_id
;
}
/* Unpack 'tag' into addr, port, and circ_id.
/*
*
Unpack 'tag' into addr, port, and circ_id.
*/
static
void
tag_unpack
(
const
char
*
tag
,
uint32_t
*
addr
,
uint16_t
*
port
,
uint16_t
*
circ_id
)
{
struct
in_addr
in
;
...
...
@@ -66,7 +74,7 @@ static void tag_unpack(const char *tag, uint32_t *addr, uint16_t *port, uint16_t
log_fn
(
LOG_DEBUG
,
"onion was from %s:%d, circ_id %d."
,
inet_ntoa
(
in
),
*
port
,
*
circ_id
);
}
/* Called when the onion key has changed and we need to spawn new
/*
*
Called when the onion key has changed and we need to spawn new
* cpuworkers. Close all currently idle cpuworkers, and mark the last
* rotation time as now.
*/
...
...
@@ -82,7 +90,7 @@ void cpuworkers_rotate(void)
spawn_enough_cpuworkers
();
}
/* Called when we get data from a cpuworker. If the answer is not complete,
/*
*
Called when we get data from a cpuworker. If the answer is not complete,
* wait for a complete answer. If the cpuworker closes the connection,
* mark it as closed and spawn a new one as needed. If the answer is complete,
* process it as appropriate.
...
...
@@ -162,8 +170,7 @@ done_processing:
return
0
;
}
/* Implement a cpuworker. 'data' is an fdarray as returned by socketpair.
/** Implement a cpuworker. 'data' is an fdarray as returned by socketpair.
* Read and writes from fdarray[1]. Reads requests, writes answers.
*
* Request format:
...
...
@@ -249,7 +256,7 @@ int cpuworker_main(void *data) {
return
0
;
/* windows wants this function to return an int */
}
/* Launch a new cpuworker.
/*
*
Launch a new cpuworker.
*/
static
int
spawn_cpuworker
(
void
)
{
int
fd
[
2
];
...
...
@@ -285,7 +292,7 @@ static int spawn_cpuworker(void) {
return
0
;
/* success */
}
/* If we have too few or too many active cpuworkers, try to spawn new ones
/*
*
If we have too few or too many active cpuworkers, try to spawn new ones
* or kill idle ones.
*/
static
void
spawn_enough_cpuworkers
(
void
)
{
...
...
@@ -305,7 +312,7 @@ static void spawn_enough_cpuworkers(void) {
}
}
/* Take a pending task from the queue and assign it to 'cpuworker' */
/*
*
Take a pending task from the queue and assign it to 'cpuworker' */
static
void
process_pending_task
(
connection_t
*
cpuworker
)
{
circuit_t
*
circ
;
...
...
@@ -320,7 +327,7 @@ static void process_pending_task(connection_t *cpuworker) {
log_fn
(
LOG_WARN
,
"assign_to_cpuworker failed. Ignoring."
);
}
/* if cpuworker is defined, assert that he's idle, and use him. else,
/*
*
if cpuworker is defined, assert that he's idle, and use him. else,
* look for an idle cpuworker and use him. if none idle, queue task onto
* the pending onion list and return.
* If question_type is CPUWORKER_TASK_ONION then task is a circ.
...
...
@@ -371,4 +378,3 @@ int assign_to_cpuworker(connection_t *cpuworker, unsigned char question_type,
c-basic-offset:2
End:
*/
src/or/directory.c
View file @
c6d4a00c
...
...
@@ -4,9 +4,10 @@
#include
"or.h"
/*****
* directory.c: Implement directory HTTP protocol.
*****/
/**
* \file directory.c
* \brief Implement directory HTTP protocol.
**/
static
void
directory_send_command
(
connection_t
*
conn
,
int
purpose
,
const
char
*
payload
,
int
payload_len
);
...
...
@@ -16,9 +17,9 @@ static int directory_handle_command(connection_t *conn);
extern
or_options_t
options
;
/* command-line and config-file options */
/* URL for publishing rendezvous descriptors. */
/*
*
URL for publishing rendezvous descriptors. */
char
rend_publish_string
[]
=
"/rendezvous/publish"
;
/* Prefix for downloading rendezvous descriptors. */
/*
*
Prefix for downloading rendezvous descriptors. */
char
rend_fetch_url
[]
=
"/rendezvous/"
;
#define MAX_HEADERS_SIZE 10000
...
...
@@ -26,7 +27,7 @@ char rend_fetch_url[] = "/rendezvous/";
/********* END VARIABLES ************/
/* Launch a new connection to the directory server 'router' to upload
/*
*
Launch a new connection to the directory server 'router' to upload
* or download a service or rendezvous descriptor. 'purpose' determines what
* kind of directory connection we're launching, and must be one of
* DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC}.
...
...
@@ -117,7 +118,7 @@ void directory_initiate_command(routerinfo_t *router, int purpose,
}
}
/* Queue an appropriate HTTP command on conn->outbuf. The args
/*
*
Queue an appropriate HTTP command on conn->outbuf. The args
* 'purpose', 'payload', and 'payload_len' are as in
* directory_initiate_command.
*/
...
...
@@ -163,7 +164,7 @@ static void directory_send_command(connection_t *conn, int purpose,
}
}
/* Parse an HTTP request string 'headers' of the form "%s %s HTTP/1..."
/*
*
Parse an HTTP request string 'headers' of the form "%s %s HTTP/1..."
* If it's well-formed, point *url to the second %s,
* null-terminate it (this modifies headers!) and return 0.
* Otherwise, return -1.
...
...
@@ -185,7 +186,7 @@ int parse_http_url(char *headers, char **url) {
return
0
;
}
/* Parse an HTTP response string 'headers' of the form "HTTP/1.%d %d%s\r\n...".
/*
*
Parse an HTTP response string 'headers' of the form "HTTP/1.%d %d%s\r\n...".