/** Fill <b>cell_out</b> with a correctly formatted version of the * CREATED{,_FAST,2} cell in <b>cell_in</b>. Return 0 on success, -1 on * failure. */ int created_cell_format(cell_t *cell_out, const created_cell_t *cell_in) { if (check_created_cell(cell_in) < 0) return -1; memset(cell_out->payload, 0, sizeof(cell_out->payload)); cell_out->command = cell_in->cell_type; switch (cell_in->cell_type) { case CELL_CREATED: case CELL_CREATED_FAST: tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)); memcpy(cell_out->payload, cell_in->reply, cell_in->handshake_len); break; case CELL_CREATED2: tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)-2); set_uint16(cell_out->payload, htons(cell_in->handshake_len)); memcpy(cell_out->payload + 2, cell_in->reply, cell_in->handshake_len); break; default: return -1; } return 0; }
/** Parse a CREATED, CREATED_FAST, or CREATED2 cell from <b>cell_in</b> into * <b>cell_out</b>. Return 0 on success, -1 on failure. */ int created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in) { memset(cell_out, 0, sizeof(*cell_out)); switch (cell_in->command) { case CELL_CREATED: cell_out->cell_type = CELL_CREATED; cell_out->handshake_len = TAP_ONIONSKIN_REPLY_LEN; memcpy(cell_out->reply, cell_in->payload, TAP_ONIONSKIN_REPLY_LEN); break; case CELL_CREATED_FAST: cell_out->cell_type = CELL_CREATED_FAST; cell_out->handshake_len = CREATED_FAST_LEN; memcpy(cell_out->reply, cell_in->payload, CREATED_FAST_LEN); break; case CELL_CREATED2: { const uint8_t *p = cell_in->payload; cell_out->cell_type = CELL_CREATED2; cell_out->handshake_len = ntohs(get_uint16(p)); if (cell_out->handshake_len > CELL_PAYLOAD_SIZE - 2) return -1; memcpy(cell_out->reply, p+2, cell_out->handshake_len); break; } } return check_created_cell(cell_out); }
/** Parse a CREATED, CREATED_FAST, or CREATED2 cell from <b>cell_in</b> into * <b>cell_out</b>. Return 0 on success, -1 on failure. */ int created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in) { // printf("\nAsserting in created_cell_parse"); memmgr_assert((void*)cell_in); memset(cell_out, 0, sizeof(cell_t)); int i; switch (cell_in->command) { case CELL_CREATED: // printf("\ncreated cell t case 1"); cell_out->cell_type = CELL_CREATED; cell_out->handshake_len = TAP_ONIONSKIN_REPLY_LEN; for(i=0; i<TAP_ONIONSKIN_REPLY_LEN; i++){ cell_out->reply[i] = cell_in->payload[i]; } // memcpy(cell_out->reply, cell_in->payload, TAP_ONIONSKIN_REPLY_LEN); // printf("\ncreated cell t case 1 done"); break; case CELL_CREATED_FAST: // printf("\ncreated cell t case 2"); cell_out->cell_type = CELL_CREATED_FAST; cell_out->handshake_len = CREATED_FAST_LEN; for(i=0; i<CREATED_FAST_LEN; i++){ cell_out->reply[i] = cell_in->payload[i]; } // memcpy(cell_out->reply, cell_in->payload, CREATED_FAST_LEN); // printf("\ncreated cell t case 2 done"); break; case CELL_CREATED2: { // printf("\ncreated cell t case 3"); const uint8_t *p = cell_in->payload; cell_out->cell_type = CELL_CREATED2; cell_out->handshake_len = ntohs(get_uint16(p)); if (cell_out->handshake_len > CELL_PAYLOAD_SIZE - 2) return -1; for(i=0; i<cell_out->handshake_len; i++){ cell_out->reply[i] = p[i+2]; } // memcpy(cell_out->reply, p+2, cell_out->handshake_len); // printf("\ncreated cell t case 3 done"); break; } } return check_created_cell(cell_out); }
/** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. */ static int check_extended_cell(const extended_cell_t *cell) { if (cell->created_cell.cell_type == CELL_CREATED) { if (cell->cell_type != RELAY_COMMAND_EXTENDED) return -1; } else if (cell->created_cell.cell_type == CELL_CREATED2) { if (cell->cell_type != RELAY_COMMAND_EXTENDED2) return -1; } else { return -1; } return check_created_cell(&cell->created_cell); }