summaryrefslogtreecommitdiff
path: root/src/or/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/command.c')
-rw-r--r--src/or/command.c69
1 files changed, 45 insertions, 24 deletions
diff --git a/src/or/command.c b/src/or/command.c
index bbcb6d23fd..43474bf870 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -31,13 +31,50 @@ void command_process_cell(cell_t *cell, connection_t *conn) {
}
}
+/* helper function for command_process_create_cell */
+static int deliver_onion_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,"deliver_onion_to_conn(): Setting onion length to %u.",onionlen);
+ *(uint32_t*)buf = htonl(onionlen);
+ memcpy((void *)(buf+4),(void *)onion,onionlen);
+
+ 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,"deliver_onion_to_conn(): Delivering create cell, payload %d bytes.",cell.length);
+ if(connection_write_cell_to_buf(&cell, conn) < 0) {
+ log(LOG_DEBUG,"deliver_onion_to_conn(): Could not buffer new create cells. Closing.");
+ free(buf);
+ return -1;
+ }
+ }
+ free(buf);
+ return 0;
+}
+
void command_process_create_cell(cell_t *cell, connection_t *conn) {
circuit_t *circ;
connection_t *n_conn;
- unsigned char *cellbuf; /* array of cells */
- int cellbuflen; /* size of cellbuf in bytes */
- cell_t *tmpcell; /* pointer to an arbitrary cell */
- int retval, i;
+ int retval;
circ = circuit_get_by_aci_conn(cell->aci, conn);
@@ -122,30 +159,14 @@ void command_process_create_cell(cell_t *cell, connection_t *conn) {
pad_onion(circ->onion,circ->onionlen, sizeof(onion_layer_t));
log(LOG_DEBUG,"command_process_create_cell(): Padded the onion with random data.");
- retval = pack_create(circ->n_aci, circ->onion, circ->onionlen, &cellbuf, &cellbuflen);
+ retval = deliver_onion_to_conn(circ->n_aci, circ->onion, circ->onionlen, n_conn);
+// retval = pack_create(circ->n_aci, circ->onion, circ->onionlen, &cellbuf, &cellbuflen);
free((void *)circ->onion);
circ->onion = NULL;
- if (retval == -1) /* pack_create() error */
- {
- log(LOG_DEBUG,"command_process_create_cell(): Could not pack the onion into CREATE cells. Closing the connection.");
+ if (retval == -1) {
+ log(LOG_DEBUG,"command_process_create_cell(): Could not deliver the onion to next conn. Closing.");
circuit_close(circ);
- return;
- }
- log(LOG_DEBUG,"command_process_create_cell(): Onion packed into CREATE cells. Buffering the cells.");
- /* queue the create cells for transmission to the next hop */
- tmpcell = (cell_t *)cellbuf;
- for (i=0;i<cellbuflen/sizeof(cell_t);i++)
- {
- retval = connection_write_cell_to_buf(tmpcell, n_conn);
- if (retval == -1) /* buffering failed, drop the connection */
- {
- log(LOG_DEBUG,"command_process_create_cell(): Could not buffer new create cells. Closing.");
- circuit_close(circ);
- return;
- }
- tmpcell++;
}
- free((void *)cellbuf);
return;
} else { /* this is destined for an exit */