diff options
Diffstat (limited to 'src/or/command.c')
-rw-r--r-- | src/or/command.c | 69 |
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 */ |