Implemented link padding and receiver token buckets
Each socket reads at most 'bandwidth' bytes per second sustained, but
can handle bursts of up to 10*bandwidth bytes.
Cells are now sent out at evenly-spaced intervals, with padding sent
out otherwise. Set Linkpadding=0 in the rc file to send cells as soon
as they're available (and to never send padding cells).
Added license/copyrights statements at the top of most files.
router->min and router->max have been merged into a single 'bandwidth'
value. We should make the routerinfo_t reflect this (want to do that,
Mat?)
As the bandwidth increases, and we want to stop sleeping more and more
frequently to send a single cell, cpu usage goes up. At 128kB/s we're
pretty much calling poll with a timeout of 1ms or even 0ms. The current
code takes a timeout of 0-9ms and makes it 10ms. prepare_for_poll()
handles everything that should have happened in the past, so as long as
our buffers don't get too full in that 10ms, we're ok.
Speaking of too full, if you run three servers at 100kB/s with -l debug,
it spends too much time printing debugging messages to be able to keep
up with the cells. The outbuf ultimately fills up and it kills that
connection. If you run with -l err, it works fine up through 500kB/s and
probably beyond. Down the road we'll want to teach it to recognize when
an outbuf is getting full, and back off.
svn:r50
2002-07-16 03:12:15 +02:00
|
|
|
/* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
|
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
/* $Id$ */
|
2002-06-27 00:45:49 +02:00
|
|
|
|
|
|
|
#include "or.h"
|
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
extern or_options_t options; /* command-line and config-file options */
|
2002-09-04 08:29:28 +02:00
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
static int onion_process(circuit_t *circ);
|
|
|
|
static int onion_deliver_to_conn(aci_t aci, unsigned char *onion, uint32_t onionlen, connection_t *conn);
|
2003-04-08 08:44:38 +02:00
|
|
|
static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len);
|
2003-02-14 08:53:55 +01:00
|
|
|
static int find_tracked_onion(unsigned char *onion, uint32_t onionlen);
|
2002-06-27 00:45:49 +02:00
|
|
|
|
|
|
|
int decide_aci_type(uint32_t local_addr, uint16_t local_port,
|
|
|
|
uint32_t remote_addr, uint16_t remote_port) {
|
|
|
|
|
|
|
|
if(local_addr > remote_addr)
|
|
|
|
return ACI_TYPE_HIGHER;
|
|
|
|
if(local_addr < remote_addr)
|
|
|
|
return ACI_TYPE_LOWER;
|
|
|
|
if(local_port > remote_port)
|
|
|
|
return ACI_TYPE_HIGHER;
|
|
|
|
/* else */
|
|
|
|
return ACI_TYPE_LOWER;
|
|
|
|
}
|
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
/* global (within this file) variables used by the next few functions */
|
|
|
|
static struct onion_queue_t *ol_list=NULL;
|
|
|
|
static struct onion_queue_t *ol_tail=NULL;
|
|
|
|
static int ol_length=0;
|
|
|
|
|
|
|
|
int onion_pending_add(circuit_t *circ) {
|
|
|
|
struct onion_queue_t *tmp;
|
|
|
|
|
|
|
|
tmp = malloc(sizeof(struct onion_queue_t));
|
|
|
|
memset(tmp, 0, sizeof(struct onion_queue_t));
|
|
|
|
tmp->circ = circ;
|
|
|
|
|
|
|
|
if(!ol_tail) {
|
|
|
|
assert(!ol_list);
|
|
|
|
assert(!ol_length);
|
|
|
|
ol_list = tmp;
|
|
|
|
ol_tail = tmp;
|
|
|
|
ol_length++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(ol_list);
|
|
|
|
assert(!ol_tail->next);
|
|
|
|
|
|
|
|
if(ol_length >= options.MaxOnionsPending) {
|
|
|
|
log(LOG_INFO,"onion_pending_add(): Already have %d onions queued. Closing.", ol_length);
|
|
|
|
free(tmp);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ol_length++;
|
|
|
|
ol_tail->next = tmp;
|
|
|
|
ol_tail = tmp;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int onion_pending_check(void) {
|
|
|
|
if(ol_list)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void onion_pending_process_one(void) {
|
|
|
|
struct data_queue_t *tmpd;
|
2002-11-28 08:32:30 +01:00
|
|
|
circuit_t *circ;
|
2002-11-27 05:08:20 +01:00
|
|
|
|
|
|
|
if(!ol_list)
|
|
|
|
return; /* no onions pending, we're done */
|
|
|
|
|
|
|
|
assert(ol_list->circ && ol_list->circ->p_conn);
|
|
|
|
assert(ol_length > 0);
|
2002-11-28 08:32:30 +01:00
|
|
|
circ = ol_list->circ;
|
2002-11-27 05:08:20 +01:00
|
|
|
|
2002-11-28 08:32:30 +01:00
|
|
|
if(onion_process(circ) < 0) {
|
2002-11-27 05:08:20 +01:00
|
|
|
log(LOG_DEBUG,"onion_pending_process_one(): Failed. Closing.");
|
2002-11-28 08:32:30 +01:00
|
|
|
onion_pending_remove(circ);
|
|
|
|
circuit_close(circ);
|
2002-11-27 05:08:20 +01:00
|
|
|
} else {
|
|
|
|
log(LOG_DEBUG,"onion_pending_process_one(): Succeeded. Delivering queued data cells.");
|
|
|
|
for(tmpd = ol_list->data_cells; tmpd; tmpd=tmpd->next) {
|
2002-11-28 08:32:30 +01:00
|
|
|
command_process_data_cell(tmpd->cell, circ->p_conn);
|
2002-11-27 05:08:20 +01:00
|
|
|
}
|
2002-11-28 08:32:30 +01:00
|
|
|
onion_pending_remove(circ);
|
2002-11-27 05:08:20 +01:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* go through ol_list, find the onion_queue_t element which points to
|
|
|
|
* circ, remove and free that element. leave circ itself alone.
|
2002-11-27 05:08:20 +01:00
|
|
|
*/
|
|
|
|
void onion_pending_remove(circuit_t *circ) {
|
|
|
|
struct onion_queue_t *tmpo, *victim;
|
|
|
|
struct data_queue_t *tmpd;
|
|
|
|
|
|
|
|
if(!ol_list)
|
|
|
|
return; /* nothing here. */
|
|
|
|
|
|
|
|
/* first check to see if it's the first entry */
|
|
|
|
tmpo = ol_list;
|
|
|
|
if(tmpo->circ == circ) {
|
|
|
|
/* it's the first one. remove it from the list. */
|
|
|
|
ol_list = tmpo->next;
|
|
|
|
if(!ol_list)
|
|
|
|
ol_tail = NULL;
|
|
|
|
ol_length--;
|
|
|
|
victim = tmpo;
|
|
|
|
} else { /* we need to hunt through the rest of the list */
|
|
|
|
for( ;tmpo->next && tmpo->next->circ != circ; tmpo=tmpo->next) ;
|
|
|
|
if(!tmpo->next) {
|
|
|
|
log(LOG_WARNING,"onion_pending_remove(): circ (p_aci %d), not in list!",circ->p_aci);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* now we know tmpo->next->circ == circ */
|
|
|
|
victim = tmpo->next;
|
|
|
|
tmpo->next = victim->next;
|
|
|
|
if(ol_tail == victim)
|
|
|
|
ol_tail = tmpo;
|
|
|
|
ol_length--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now victim points to the element that needs to be removed */
|
|
|
|
|
|
|
|
/* first dump the attached data cells too, if any */
|
|
|
|
while(victim->data_cells) {
|
|
|
|
tmpd = victim->data_cells;
|
|
|
|
victim->data_cells = tmpd->next;
|
|
|
|
free(tmpd->cell);
|
|
|
|
free(tmpd);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(victim);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
struct data_queue_t *data_queue_add(struct data_queue_t *list, cell_t *cell) {
|
2002-11-27 05:08:20 +01:00
|
|
|
struct data_queue_t *tmpd, *newd;
|
|
|
|
|
|
|
|
newd = malloc(sizeof(struct data_queue_t));
|
|
|
|
memset(newd, 0, sizeof(struct data_queue_t));
|
|
|
|
newd->cell = malloc(sizeof(cell_t));
|
|
|
|
memcpy(newd->cell, cell, sizeof(cell_t));
|
|
|
|
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
if(!list) {
|
|
|
|
return newd;
|
|
|
|
}
|
|
|
|
for(tmpd = list; tmpd->next; tmpd=tmpd->next) ;
|
|
|
|
/* now tmpd->next is null */
|
|
|
|
tmpd->next = newd;
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* a data cell has arrived for a circuit which is still pending. Find
|
|
|
|
* the right entry in ol_list, and add it to the end of the 'data_cells'
|
|
|
|
* list.
|
|
|
|
*/
|
|
|
|
void onion_pending_data_add(circuit_t *circ, cell_t *cell) {
|
|
|
|
struct onion_queue_t *tmpo;
|
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
for(tmpo=ol_list; tmpo; tmpo=tmpo->next) {
|
|
|
|
if(tmpo->circ == circ) {
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
tmpo->data_cells = data_queue_add(tmpo->data_cells, cell);
|
2002-11-27 05:08:20 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* helper function for onion_process */
|
|
|
|
static int onion_deliver_to_conn(aci_t aci, unsigned char *onion, uint32_t onionlen, connection_t *conn) {
|
|
|
|
char *buf;
|
|
|
|
int buflen, dataleft;
|
|
|
|
cell_t cell;
|
|
|
|
|
|
|
|
assert(aci && onion && onionlen);
|
|
|
|
|
|
|
|
buflen = onionlen+4;
|
|
|
|
buf = malloc(buflen);
|
|
|
|
if(!buf)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
log(LOG_DEBUG,"onion_deliver_to_conn(): Setting onion length to %u.",onionlen);
|
|
|
|
*(uint32_t*)buf = htonl(onionlen);
|
2002-12-03 23:18:23 +01:00
|
|
|
memcpy((buf+4),onion,onionlen);
|
2002-11-27 05:08:20 +01:00
|
|
|
|
|
|
|
dataleft = buflen;
|
|
|
|
while(dataleft > 0) {
|
|
|
|
memset(&cell,0,sizeof(cell_t));
|
|
|
|
cell.command = CELL_CREATE;
|
|
|
|
cell.aci = aci;
|
|
|
|
if(dataleft >= CELL_PAYLOAD_SIZE)
|
|
|
|
cell.length = CELL_PAYLOAD_SIZE;
|
|
|
|
else
|
|
|
|
cell.length = dataleft;
|
|
|
|
memcpy(cell.payload, buf+buflen-dataleft, cell.length);
|
|
|
|
dataleft -= cell.length;
|
|
|
|
|
|
|
|
log(LOG_DEBUG,"onion_deliver_to_conn(): Delivering create cell, payload %d bytes.",cell.length);
|
|
|
|
if(connection_write_cell_to_buf(&cell, conn) < 0) {
|
|
|
|
log(LOG_DEBUG,"onion_deliver_to_conn(): Could not buffer new create cells. Closing.");
|
|
|
|
free(buf);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(buf);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int onion_process(circuit_t *circ) {
|
|
|
|
connection_t *n_conn;
|
|
|
|
int retval;
|
2002-06-27 00:45:49 +02:00
|
|
|
aci_t aci_type;
|
2002-10-03 00:54:20 +02:00
|
|
|
struct sockaddr_in me; /* my router identity */
|
|
|
|
|
|
|
|
if(learn_my_address(&me) < 0)
|
|
|
|
return -1;
|
2002-06-27 00:45:49 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* decrypt it in-place */
|
|
|
|
if(decrypt_onion(circ->onion,circ->onionlen,getprivatekey()) < 0) {
|
2002-06-27 00:45:49 +02:00
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): decrypt_onion() failed, closing circuit.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): Onion decrypted.");
|
|
|
|
|
|
|
|
/* check freshness */
|
2002-12-03 23:18:23 +01:00
|
|
|
if (ntohl(*(uint32_t *)(circ->onion+8)) < (uint32_t)time(NULL)) /* expired onion */
|
2002-06-27 00:45:49 +02:00
|
|
|
{
|
|
|
|
log(LOG_NOTICE,"I have just received an expired onion. This could be a replay attack.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-10-03 00:54:20 +02:00
|
|
|
aci_type = decide_aci_type(ntohl(me.sin_addr.s_addr), ntohs(me.sin_port),
|
2002-12-03 23:18:23 +01:00
|
|
|
ntohl(*(uint32_t *)(circ->onion+4)),ntohs(*(uint16_t *)(circ->onion+2)));
|
2002-06-27 00:45:49 +02:00
|
|
|
|
|
|
|
if(circuit_init(circ, aci_type) < 0) {
|
|
|
|
log(LOG_ERR,"process_onion(): init_circuit() failed.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-12-31 16:04:14 +01:00
|
|
|
/* check for replay. at the same time, add it to the pile of tracked onions. */
|
|
|
|
if(find_tracked_onion(circ->onion, circ->onionlen)) {
|
2002-06-27 00:45:49 +02:00
|
|
|
log(LOG_NOTICE,"process_onion(): I have just received a replayed onion. This could be a replay attack.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
/* now we must send create cells to the next router */
|
|
|
|
if(circ->n_addr && circ->n_port) {
|
|
|
|
n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
|
|
|
|
if(!n_conn || n_conn->type != CONN_TYPE_OR) {
|
|
|
|
/* i've disabled making connections through OPs, but it's definitely
|
|
|
|
* possible here. I'm not sure if it would be a bug or a feature. -RD
|
|
|
|
*/
|
|
|
|
/* note also that this will close circuits where the onion has the same
|
|
|
|
* router twice in a row in the path. i think that's ok. -RD
|
|
|
|
*/
|
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): Next router not connected. Closing.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
circ->n_addr = n_conn->addr; /* these are different if we found a twin instead */
|
|
|
|
circ->n_port = n_conn->port;
|
|
|
|
|
|
|
|
circ->n_conn = n_conn;
|
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): n_conn is %s:%u",n_conn->address,n_conn->port);
|
|
|
|
|
|
|
|
/* send the CREATE cells on to the next hop */
|
2002-12-03 23:18:23 +01:00
|
|
|
pad_onion(circ->onion, circ->onionlen, ONION_LAYER_SIZE);
|
2002-11-27 05:08:20 +01:00
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): Padded the onion with random data.");
|
|
|
|
|
|
|
|
retval = onion_deliver_to_conn(circ->n_aci, circ->onion, circ->onionlen, n_conn);
|
2002-12-03 23:18:23 +01:00
|
|
|
free(circ->onion);
|
2002-11-27 05:08:20 +01:00
|
|
|
circ->onion = NULL;
|
|
|
|
if (retval == -1) {
|
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): Could not deliver the onion to next conn. Closing.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else { /* this is destined for an exit */
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): create cell reached exit. Circuit established.");
|
|
|
|
#if 0
|
2002-11-27 05:08:20 +01:00
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): Creating new exit connection.");
|
|
|
|
n_conn = connection_new(CONN_TYPE_EXIT);
|
|
|
|
if(!n_conn) {
|
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): connection_new failed. Closing.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
n_conn->state = EXIT_CONN_STATE_CONNECTING_WAIT;
|
|
|
|
n_conn->receiver_bucket = -1; /* edge connections don't do receiver buckets */
|
|
|
|
n_conn->bandwidth = -1;
|
|
|
|
n_conn->s = -1; /* not yet valid */
|
|
|
|
if(connection_add(n_conn) < 0) { /* no space, forget it */
|
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): connection_add failed. Closing.");
|
|
|
|
connection_free(n_conn);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
circ->n_conn = n_conn;
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
#endif
|
2002-11-27 05:08:20 +01:00
|
|
|
}
|
2002-06-27 00:45:49 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
/* uses a weighted coin with weight cw to choose a route length */
|
|
|
|
int chooselen(double cw)
|
|
|
|
{
|
|
|
|
int len = 2;
|
|
|
|
int retval = 0;
|
|
|
|
unsigned char coin;
|
|
|
|
|
|
|
|
if ((cw < 0) || (cw >= 1)) /* invalid parameter */
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
{
|
2002-08-22 09:30:03 +02:00
|
|
|
retval = crypto_pseudo_rand(1, &coin);
|
|
|
|
if (retval)
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (coin > cw*255) /* don't extend */
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* returns an array of pointers to routent that define a new route through the OR network
|
|
|
|
* int cw is the coin weight to use when choosing the route
|
|
|
|
* order of routers is from last to first
|
|
|
|
*/
|
2002-08-24 06:59:21 +02:00
|
|
|
unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *routelen)
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
{
|
2002-08-23 05:35:44 +02:00
|
|
|
int i, j;
|
2003-04-08 08:44:38 +02:00
|
|
|
int num_acceptable_routers;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
unsigned int *route = NULL;
|
|
|
|
unsigned int oldchoice, choice;
|
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
assert((cw >= 0) && (cw < 1) && (rarray) && (routelen) ); /* valid parameters */
|
2002-07-22 06:38:36 +02:00
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
*routelen = chooselen(cw);
|
|
|
|
if (*routelen == -1) {
|
2002-08-23 05:35:44 +02:00
|
|
|
log(LOG_ERR,"Choosing route length failed.");
|
|
|
|
return NULL;
|
|
|
|
}
|
2002-08-24 06:59:21 +02:00
|
|
|
log(LOG_DEBUG,"new_route(): Chosen route length %d.",*routelen);
|
2002-08-23 05:35:44 +02:00
|
|
|
|
2003-04-08 08:44:38 +02:00
|
|
|
num_acceptable_routers = count_acceptable_routers(rarray, rarray_len);
|
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
if(num_acceptable_routers < *routelen) {
|
|
|
|
log(LOG_DEBUG,"new_route(): Cutting routelen from %d to %d.",*routelen, num_acceptable_routers);
|
|
|
|
*routelen = num_acceptable_routers;
|
2002-08-23 05:35:44 +02:00
|
|
|
}
|
2002-07-22 06:38:36 +02:00
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
if(*routelen < 1) {
|
2002-08-23 05:35:44 +02:00
|
|
|
log(LOG_ERR,"new_route(): Didn't find any acceptable routers. Failing.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allocate memory for the new route */
|
2002-08-24 06:59:21 +02:00
|
|
|
route = (unsigned int *)malloc(*routelen * sizeof(unsigned int));
|
2002-08-23 05:35:44 +02:00
|
|
|
if (!route) {
|
|
|
|
log(LOG_ERR,"Memory allocation failed.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
oldchoice = rarray_len;
|
2002-08-24 06:59:21 +02:00
|
|
|
for(i=0;i<*routelen;i++) {
|
2002-08-23 05:35:44 +02:00
|
|
|
log(LOG_DEBUG,"new_route(): Choosing hop %u.",i);
|
2002-08-24 06:59:21 +02:00
|
|
|
if(crypto_pseudo_rand(sizeof(unsigned int),(unsigned char *)&choice)) {
|
2002-08-23 05:35:44 +02:00
|
|
|
free((void *)route);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-08-23 05:35:44 +02:00
|
|
|
choice = choice % (rarray_len);
|
|
|
|
log(LOG_DEBUG,"new_route(): Contemplating router %u.",choice);
|
2002-08-23 07:27:50 +02:00
|
|
|
if(choice == oldchoice ||
|
2002-09-24 12:43:57 +02:00
|
|
|
(oldchoice < rarray_len && !crypto_pk_cmp_keys(rarray[choice]->pkey, rarray[oldchoice]->pkey)) ||
|
2003-03-18 02:49:55 +01:00
|
|
|
(options.ORPort && !connection_twin_get_by_addr_port(rarray[choice]->addr, rarray[choice]->or_port))) {
|
2002-08-23 05:35:44 +02:00
|
|
|
/* Same router as last choice, or router twin,
|
|
|
|
* or no routers with that key are connected to us.
|
|
|
|
* Try again. */
|
|
|
|
log(LOG_DEBUG,"new_route(): Picked a router %d that won't work as next hop.",choice);
|
2002-08-23 07:27:50 +02:00
|
|
|
i--;
|
|
|
|
continue;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
2002-08-23 05:35:44 +02:00
|
|
|
log(LOG_DEBUG,"new_route(): Chosen router %u for hop %u.",choice,i);
|
|
|
|
oldchoice = choice;
|
|
|
|
route[i] = choice;
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-08-23 05:35:44 +02:00
|
|
|
return route;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2003-04-08 08:44:38 +02:00
|
|
|
static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len) {
|
|
|
|
int i, j;
|
|
|
|
int num=0;
|
|
|
|
|
|
|
|
for(i=0;i<rarray_len;i++) {
|
|
|
|
log(LOG_DEBUG,"Contemplating whether router %d is a new option...",i);
|
|
|
|
if(options.ORPort &&
|
|
|
|
!connection_exact_get_by_addr_port(rarray[i]->addr, rarray[i]->or_port)) {
|
|
|
|
log(LOG_DEBUG,"Nope, %d is not connected.",i);
|
|
|
|
goto next_i_loop;
|
|
|
|
}
|
|
|
|
for(j=0;j<i;j++) {
|
|
|
|
if(!crypto_pk_cmp_keys(rarray[i]->pkey, rarray[j]->pkey)) {
|
|
|
|
/* these guys are twins. so we've already counted him. */
|
|
|
|
log(LOG_DEBUG,"Nope, %d is a twin of %d.",i,j);
|
|
|
|
goto next_i_loop;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
num++;
|
|
|
|
log(LOG_DEBUG,"I like %d. num_acceptable_routers now %d.",i, num);
|
|
|
|
next_i_loop:
|
|
|
|
; /* our compiler may need an explicit statement after the label */
|
|
|
|
}
|
|
|
|
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-02 22:39:51 +02:00
|
|
|
crypto_cipher_env_t *
|
|
|
|
create_onion_cipher(int cipher_type, char *key, char *iv, int encrypt_mode)
|
|
|
|
{
|
|
|
|
switch (cipher_type) {
|
|
|
|
case ONION_CIPHER_DES:
|
|
|
|
cipher_type = CRYPTO_CIPHER_DES;
|
|
|
|
break;
|
2003-03-19 21:48:56 +01:00
|
|
|
case ONION_CIPHER_3DES:
|
|
|
|
cipher_type = CRYPTO_CIPHER_3DES;
|
|
|
|
break;
|
2002-10-02 22:39:51 +02:00
|
|
|
case ONION_CIPHER_RC4 :
|
2002-12-03 23:18:23 +01:00
|
|
|
cipher_type = CRYPTO_CIPHER_RC4;
|
2002-10-02 22:39:51 +02:00
|
|
|
break;
|
|
|
|
case ONION_CIPHER_IDENTITY :
|
|
|
|
cipher_type = CRYPTO_CIPHER_IDENTITY;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
log(LOG_ERR, "Unknown cipher type %d", cipher_type);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return crypto_create_init_cipher(cipher_type, key, iv, encrypt_mode);
|
|
|
|
}
|
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
/* creates a new onion from route, stores it and its length into buf and len respectively */
|
|
|
|
unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int *route, int routelen, int *len, crypt_path_t **cpath)
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
{
|
|
|
|
int i,j;
|
2002-12-03 23:18:23 +01:00
|
|
|
char *layer;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
crypt_path_t *hop = NULL;
|
2002-08-24 06:59:21 +02:00
|
|
|
unsigned char *buf;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
routerinfo_t *router;
|
2002-08-22 09:30:03 +02:00
|
|
|
unsigned char iv[16];
|
2002-11-23 07:49:01 +01:00
|
|
|
struct in_addr netaddr;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
assert(rarray && route && len && routelen);
|
2002-07-20 03:59:28 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* calculate the size of the onion */
|
2002-12-03 23:18:23 +01:00
|
|
|
*len = routelen * ONION_LAYER_SIZE + ONION_PADDING_SIZE;
|
|
|
|
/* 28 bytes per layer + 100 bytes padding for the innermost layer */
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"create_onion() : Size of the onion is %u.",*len);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* allocate memory for the onion */
|
2002-12-03 23:18:23 +01:00
|
|
|
buf = malloc(*len);
|
|
|
|
if(!buf) {
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error allocating memory.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"create_onion() : Allocated memory for the onion.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
for(i=0; i<routelen; i++) {
|
2002-11-23 07:49:01 +01:00
|
|
|
netaddr.s_addr = htonl((rarray[route[i]])->addr);
|
|
|
|
|
|
|
|
log(LOG_DEBUG,"create_onion(): %u : %s:%u, %u/%u",routelen-i,
|
|
|
|
inet_ntoa(netaddr),
|
|
|
|
(rarray[route[i]])->or_port,
|
|
|
|
(rarray[route[i]])->pkey,
|
|
|
|
crypto_pk_keysize((rarray[route[i]])->pkey));
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
layer = buf + *len - ONION_LAYER_SIZE - ONION_PADDING_SIZE; /* pointer to innermost layer */
|
2002-11-23 07:49:01 +01:00
|
|
|
/* create the onion layer by layer, starting with the innermost */
|
|
|
|
for (i=0;i<routelen;i++) {
|
|
|
|
router = rarray[route[i]];
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
// log(LOG_DEBUG,"create_onion() : %u",router);
|
|
|
|
// log(LOG_DEBUG,"create_onion() : This router is %s:%u",inet_ntoa(*((struct in_addr *)&router->addr)),router->or_port);
|
|
|
|
// log(LOG_DEBUG,"create_onion() : Key pointer = %u.",router->pkey);
|
|
|
|
// log(LOG_DEBUG,"create_onion() : Key size = %u.",crypto_pk_keysize(router->pkey));
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
*layer = OR_VERSION;
|
2002-11-23 07:49:01 +01:00
|
|
|
/* Back F + Forw F both use DES OFB*/
|
2002-12-03 23:18:23 +01:00
|
|
|
*(layer+1) = (ONION_DEFAULT_CIPHER << 4) /* for backf */ +
|
|
|
|
ONION_DEFAULT_CIPHER; /* for forwf */
|
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* Dest Port */
|
|
|
|
if (i) /* not last hop */
|
2002-12-03 23:18:23 +01:00
|
|
|
*(uint16_t *)(layer+2) = htons(rarray[route[i-1]]->or_port);
|
2002-11-23 07:49:01 +01:00
|
|
|
else
|
2002-12-03 23:18:23 +01:00
|
|
|
*(uint16_t *)(layer+2) = htons(0);
|
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* Dest Addr */
|
|
|
|
if (i) /* not last hop */
|
2002-12-03 23:18:23 +01:00
|
|
|
*(uint32_t *)(layer+4) = htonl(rarray[route[i-1]]->addr);
|
2002-11-23 07:49:01 +01:00
|
|
|
else
|
2002-12-03 23:18:23 +01:00
|
|
|
*(uint32_t *)(layer+4) = htonl(0);
|
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* Expiration Time */
|
2002-12-03 23:18:23 +01:00
|
|
|
*(uint32_t *)(layer+8) = htonl((uint32_t)(time(NULL) + 86400)); /* NOW + 1 day */
|
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* Key Seed Material */
|
2002-12-03 23:18:23 +01:00
|
|
|
if(crypto_rand(16, layer+12)) { /* error */
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error generating random data.");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
// log(LOG_DEBUG,"create_onion() : Onion layer %u built : %u, %u, %u, %s, %u.",i+1,layer->zero,layer->backf,layer->forwf,inet_ntoa(*((struct in_addr *)&layer->addr)),layer->port);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* build up the crypt_path */
|
|
|
|
if(cpath) {
|
|
|
|
cpath[i] = (crypt_path_t *)malloc(sizeof(crypt_path_t));
|
|
|
|
if(!cpath[i]) {
|
|
|
|
log(LOG_ERR,"Error allocating memory.");
|
|
|
|
goto error;
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"create_onion() : Building hop %u of crypt path.",i+1);
|
|
|
|
hop = cpath[i];
|
|
|
|
/* set crypto functions */
|
2002-12-03 23:18:23 +01:00
|
|
|
hop->backf = *(layer+1) >> 4;
|
|
|
|
hop->forwf = *(layer+1) & 0x0f;
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* calculate keys */
|
2002-12-03 23:18:23 +01:00
|
|
|
crypto_SHA_digest(layer+12,16,hop->digest3);
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"create_onion() : First SHA pass performed.");
|
|
|
|
crypto_SHA_digest(hop->digest3,20,hop->digest2);
|
|
|
|
log(LOG_DEBUG,"create_onion() : Second SHA pass performed.");
|
|
|
|
crypto_SHA_digest(hop->digest2,20,hop->digest3);
|
|
|
|
log(LOG_DEBUG,"create_onion() : Third SHA pass performed.");
|
|
|
|
log(LOG_DEBUG,"create_onion() : Keys generated.");
|
|
|
|
/* set IV to zero */
|
|
|
|
memset((void *)iv,0,16);
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* initialize cipher engines */
|
|
|
|
if (! (hop->f_crypto = create_onion_cipher(hop->forwf, hop->digest3, iv, 1))) {
|
|
|
|
/* cipher initialization failed */
|
|
|
|
log(LOG_ERR,"Could not create a crypto environment.");
|
|
|
|
goto error;
|
|
|
|
}
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
if (! (hop->b_crypto = create_onion_cipher(hop->backf, hop->digest2, iv, 0))) {
|
|
|
|
/* cipher initialization failed */
|
|
|
|
log(LOG_ERR,"Could not create a crypto environment.");
|
|
|
|
goto error;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
2002-11-23 07:49:01 +01:00
|
|
|
|
|
|
|
log(LOG_DEBUG,"create_onion() : Built corresponding crypt path hop.");
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* padding if this is the innermost layer */
|
|
|
|
if (!i) {
|
2002-12-03 23:18:23 +01:00
|
|
|
if (crypto_pseudo_rand(ONION_PADDING_SIZE, layer + ONION_LAYER_SIZE)) { /* error */
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error generating pseudo-random data.");
|
|
|
|
goto error;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"create_onion() : This is the innermost layer. Adding 100 bytes of padding.");
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* encrypt */
|
2002-10-02 22:39:51 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
if(encrypt_onion(layer,ONION_PADDING_SIZE+(i+1)*ONION_LAYER_SIZE,router->pkey) < 0) {
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error encrypting onion layer.");
|
|
|
|
goto error;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"create_onion() : Encrypted layer.");
|
|
|
|
|
|
|
|
/* calculate pointer to next layer */
|
2002-12-03 23:18:23 +01:00
|
|
|
layer = buf + (routelen-i-2)*ONION_LAYER_SIZE;
|
2002-11-23 07:49:01 +01:00
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
return buf;
|
2002-12-03 23:18:23 +01:00
|
|
|
|
2002-10-02 22:39:51 +02:00
|
|
|
error:
|
2002-11-23 07:49:01 +01:00
|
|
|
if (buf)
|
2002-12-03 23:18:23 +01:00
|
|
|
free(buf);
|
2002-11-23 07:49:01 +01:00
|
|
|
if (cpath) {
|
|
|
|
for (j=0;j<i;j++) {
|
|
|
|
if(cpath[i]->f_crypto)
|
|
|
|
crypto_free_cipher_env(cpath[i]->f_crypto);
|
|
|
|
if(cpath[i]->b_crypto)
|
|
|
|
crypto_free_cipher_env(cpath[i]->b_crypto);
|
|
|
|
free((void *)cpath[i]);
|
2002-10-02 22:39:51 +02:00
|
|
|
}
|
2002-11-23 07:49:01 +01:00
|
|
|
}
|
|
|
|
return NULL;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* encrypts 128 bytes of the onion with the specified public key, the rest with
|
|
|
|
* DES OFB with the key as defined in the outter layer */
|
2002-12-03 23:18:23 +01:00
|
|
|
int encrypt_onion(unsigned char *onion, uint32_t onionlen, crypto_pk_env_t *pkey) {
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
unsigned char *tmpbuf = NULL; /* temporary buffer for crypto operations */
|
|
|
|
unsigned char digest[20]; /* stores SHA1 output - 160 bits */
|
|
|
|
unsigned char iv[8];
|
|
|
|
|
2002-10-02 22:39:51 +02:00
|
|
|
crypto_cipher_env_t *crypt_env = NULL; /* crypto environment */
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
assert(onion && pkey);
|
2002-12-03 23:18:23 +01:00
|
|
|
assert(onionlen >= 128);
|
2002-11-23 07:49:01 +01:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
memset(iv,0,8);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
// log(LOG_DEBUG,"Onion layer : %u, %u, %u, %s, %u.",onion->zero,onion->backf,onion->forwf,inet_ntoa(*((struct in_addr *)&onion->addr)),onion->port);
|
2002-11-23 07:49:01 +01:00
|
|
|
/* allocate space for tmpbuf */
|
|
|
|
tmpbuf = (unsigned char *)malloc(onionlen);
|
2002-12-03 23:18:23 +01:00
|
|
|
if(!tmpbuf) {
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Could not allocate memory.");
|
2002-12-03 23:18:23 +01:00
|
|
|
return -1;
|
2002-11-23 07:49:01 +01:00
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"encrypt_onion() : allocated %u bytes of memory for the encrypted onion (at %u).",onionlen,tmpbuf);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* get key1 = SHA1(KeySeed) */
|
2002-12-03 23:18:23 +01:00
|
|
|
if (crypto_SHA_digest(onion+12,16,digest)) {
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error computing SHA1 digest.");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"encrypt_onion() : Computed DES key.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"encrypt_onion() : Trying to RSA encrypt.");
|
|
|
|
/* encrypt 128 bytes with RSA *pkey */
|
2002-12-03 23:18:23 +01:00
|
|
|
if (crypto_pk_public_encrypt(pkey, onion, 128, tmpbuf, RSA_NO_PADDING) == -1) {
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error RSA-encrypting data :%s",crypto_perror());
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
log(LOG_DEBUG,"encrypt_onion() : RSA encrypted first 128 bytes of the onion.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2003-03-19 21:48:56 +01:00
|
|
|
/* now encrypt the rest with 3DES OFB */
|
|
|
|
crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, digest, iv, 1);
|
2002-11-23 07:49:01 +01:00
|
|
|
if (!crypt_env) {
|
|
|
|
log(LOG_ERR,"Error creating the crypto environment.");
|
|
|
|
goto error;
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
if (crypto_cipher_encrypt(crypt_env,onion+128, onionlen-128, (unsigned char *)tmpbuf+128)) { /* error */
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error performing DES encryption:%s",crypto_perror());
|
|
|
|
goto error;
|
|
|
|
}
|
2003-03-19 21:48:56 +01:00
|
|
|
log(LOG_DEBUG,"encrypt_onion() : 3DES OFB encrypted the rest of the onion.");
|
2002-10-02 22:39:51 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* now copy tmpbuf to onion */
|
2002-12-03 23:18:23 +01:00
|
|
|
memcpy(onion,tmpbuf,onionlen);
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"encrypt_onion() : Copied cipher to original onion buffer.");
|
2002-12-03 23:18:23 +01:00
|
|
|
free(tmpbuf);
|
2002-11-23 07:49:01 +01:00
|
|
|
crypto_free_cipher_env(crypt_env);
|
2002-12-03 23:18:23 +01:00
|
|
|
return 0;
|
2002-10-02 22:39:51 +02:00
|
|
|
|
|
|
|
error:
|
|
|
|
if (tmpbuf)
|
2002-12-03 23:18:23 +01:00
|
|
|
free(tmpbuf);
|
2002-10-02 22:39:51 +02:00
|
|
|
if (crypt_env)
|
|
|
|
crypto_free_cipher_env(crypt_env);
|
2002-12-03 23:18:23 +01:00
|
|
|
return -1;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* decrypts the first 128 bytes using RSA and prkey, decrypts the rest with DES OFB with key1 */
|
2002-12-03 23:18:23 +01:00
|
|
|
int decrypt_onion(unsigned char *onion, uint32_t onionlen, crypto_pk_env_t *prkey) {
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
void *tmpbuf = NULL; /* temporary buffer for crypto operations */
|
|
|
|
unsigned char digest[20]; /* stores SHA1 output - 160 bits */
|
|
|
|
unsigned char iv[8];
|
|
|
|
|
2002-10-02 22:39:51 +02:00
|
|
|
crypto_cipher_env_t *crypt_env =NULL; /* crypto environment */
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
assert(onion && prkey);
|
|
|
|
|
|
|
|
memset(iv,0,8);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* allocate space for tmpbuf */
|
|
|
|
tmpbuf = malloc(onionlen);
|
|
|
|
if (!tmpbuf) {
|
|
|
|
log(LOG_ERR,"Could not allocate memory.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"decrypt_onion() : Allocated memory for the temporary buffer.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* decrypt 128 bytes with RSA *prkey */
|
|
|
|
if (crypto_pk_private_decrypt(prkey, onion, 128, tmpbuf, RSA_NO_PADDING) == -1)
|
|
|
|
{
|
|
|
|
log(LOG_ERR,"Error RSA-decrypting data :%s",crypto_perror());
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"decrypt_onion() : RSA decryption complete.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* get key1 = SHA1(KeySeed) */
|
|
|
|
if (crypto_SHA_digest(tmpbuf+12,16,digest)) {
|
|
|
|
log(LOG_ERR,"Error computing SHA1 digest.");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"decrypt_onion() : Computed DES key.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2003-03-19 21:48:56 +01:00
|
|
|
/* now decrypt the rest with 3DES OFB */
|
|
|
|
crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, digest, iv, 0);
|
2002-12-03 23:18:23 +01:00
|
|
|
if (!crypt_env) {
|
|
|
|
log(LOG_ERR,"Error creating crypto environment");
|
|
|
|
goto error;
|
|
|
|
}
|
2002-10-02 22:39:51 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
if (crypto_cipher_decrypt(crypt_env,onion+128, onionlen-128,tmpbuf+128)) {
|
|
|
|
log(LOG_ERR,"Error performing DES decryption:%s",crypto_perror());
|
|
|
|
goto error;
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
log(LOG_DEBUG,"decrypt_onion() : DES decryption complete.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* now copy tmpbuf to onion */
|
|
|
|
memcpy(onion,tmpbuf,onionlen);
|
|
|
|
free(tmpbuf);
|
|
|
|
crypto_free_cipher_env(crypt_env);
|
|
|
|
return 0;
|
2002-10-02 22:39:51 +02:00
|
|
|
|
|
|
|
error:
|
|
|
|
if (tmpbuf)
|
2002-12-03 23:18:23 +01:00
|
|
|
free(tmpbuf);
|
2002-10-02 22:39:51 +02:00
|
|
|
if (crypt_env)
|
|
|
|
crypto_free_cipher_env(crypt_env);
|
2002-12-03 23:18:23 +01:00
|
|
|
return -1;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* delete first n bytes of the onion and pads the end with n bytes of random data */
|
2002-08-24 06:59:21 +02:00
|
|
|
void pad_onion(unsigned char *onion, uint32_t onionlen, int n)
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
{
|
2002-12-03 23:18:23 +01:00
|
|
|
assert(onion);
|
|
|
|
|
|
|
|
memmove(onion,onion+n,onionlen-n);
|
|
|
|
crypto_pseudo_rand(n, onion+onionlen-n);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2002-12-31 16:04:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* red black tree using Niels' tree.h. I used
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
http://www.openbsd.org/cgi-bin/cvsweb/src/regress/sys/sys/tree/rb/
|
2002-12-31 16:04:14 +01:00
|
|
|
as my guide */
|
|
|
|
|
|
|
|
#include "tree.h"
|
|
|
|
|
|
|
|
struct tracked_onion {
|
|
|
|
RB_ENTRY(tracked_onion) node;
|
|
|
|
uint32_t expire;
|
|
|
|
char digest[20]; /* SHA digest of the onion */
|
|
|
|
struct tracked_onion *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
RB_HEAD(tracked_tree, tracked_onion) tracked_root;
|
|
|
|
|
|
|
|
int compare_tracked_onions(struct tracked_onion *a, struct tracked_onion *b) {
|
|
|
|
return memcmp(a->digest, b->digest, 20);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2003-03-17 03:42:14 +01:00
|
|
|
RB_PROTOTYPE(tracked_tree, tracked_onion, node, compare_tracked_onions)
|
|
|
|
RB_GENERATE(tracked_tree, tracked_onion, node, compare_tracked_onions)
|
2002-12-31 16:04:14 +01:00
|
|
|
|
|
|
|
void init_tracked_tree(void) {
|
|
|
|
RB_INIT(&tracked_root);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2002-12-31 16:04:14 +01:00
|
|
|
/* see if this onion has been seen before. if so, return 1, else
|
|
|
|
* return 0 and add the sha1 of this onion to the tree.
|
|
|
|
*/
|
2003-02-14 08:53:55 +01:00
|
|
|
static int find_tracked_onion(unsigned char *onion, uint32_t onionlen) {
|
2002-12-31 16:04:14 +01:00
|
|
|
static struct tracked_onion *head_tracked_onions = NULL; /* linked list of tracked onions */
|
|
|
|
static struct tracked_onion *tail_tracked_onions = NULL;
|
|
|
|
|
|
|
|
uint32_t now = time(NULL);
|
|
|
|
struct tracked_onion *to;
|
|
|
|
|
|
|
|
/* first take this opportunity to see if there are any expired
|
2003-02-14 08:53:55 +01:00
|
|
|
* onions in the tree. we know this is fast because the linked list
|
2002-12-31 16:04:14 +01:00
|
|
|
* 'tracked_onions' is ordered by when they were seen.
|
|
|
|
*/
|
|
|
|
while(head_tracked_onions && (head_tracked_onions->expire < now)) {
|
|
|
|
to = head_tracked_onions;
|
|
|
|
log(LOG_DEBUG,"find_tracked_onion(): Forgetting old onion (expires %d)", to->expire);
|
|
|
|
head_tracked_onions = to->next;
|
|
|
|
if(!head_tracked_onions) /* if there are no more, */
|
|
|
|
tail_tracked_onions = NULL; /* then make sure the list's tail knows that too */
|
|
|
|
RB_REMOVE(tracked_tree, &tracked_root, to);
|
|
|
|
free(to);
|
|
|
|
}
|
|
|
|
|
|
|
|
to = malloc(sizeof(struct tracked_onion));
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
|
|
|
/* compute the SHA digest of the onion */
|
2002-12-31 16:04:14 +01:00
|
|
|
crypto_SHA_digest(onion, onionlen, to->digest);
|
|
|
|
|
|
|
|
/* try adding it to the tree. if it's already there it will return it. */
|
|
|
|
if(RB_INSERT(tracked_tree, &tracked_root, to)) {
|
|
|
|
/* yes, it's already there: this is a replay. */
|
|
|
|
free(to);
|
|
|
|
return 1;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2002-12-31 16:04:14 +01:00
|
|
|
/* this is a new onion. add it to the list. */
|
|
|
|
|
|
|
|
to->expire = ntohl(*(uint32_t *)(onion+8)); /* set the expiration date */
|
|
|
|
to->next = NULL;
|
|
|
|
|
|
|
|
if (!head_tracked_onions) {
|
|
|
|
head_tracked_onions = to;
|
|
|
|
} else {
|
|
|
|
tail_tracked_onions->next = to;
|
|
|
|
}
|
|
|
|
tail_tracked_onions = to;
|
|
|
|
|
|
|
|
log(LOG_DEBUG,"find_tracked_onion(): Remembered new onion (expires %d)", to->expire);
|
|
|
|
|
|
|
|
return 0;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
2002-12-03 23:18:23 +01:00
|
|
|
|
2003-04-07 04:12:02 +02:00
|
|
|
/*
|
|
|
|
Local Variables:
|
|
|
|
mode:c
|
|
|
|
indent-tabs-mode:nil
|
|
|
|
c-basic-offset:2
|
|
|
|
End:
|
|
|
|
*/
|