Line data Source code
1 : /* Copyright (c) 2013-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : #define CIRCUITLIST_PRIVATE
5 : #define RELAY_PRIVATE
6 : #include "core/or/or.h"
7 : #include "core/or/circuitlist.h"
8 : #include "core/or/relay.h"
9 : #include "test/test.h"
10 :
11 : #include "core/or/cell_st.h"
12 : #include "core/or/cell_queue_st.h"
13 : #include "core/or/or_circuit_st.h"
14 : #include "core/or/origin_circuit_st.h"
15 :
16 : static void
17 1 : test_cq_manip(void *arg)
18 : {
19 1 : packed_cell_t *pc1=NULL, *pc2=NULL, *pc3=NULL, *pc4=NULL, *pc_tmp=NULL;
20 1 : cell_queue_t cq;
21 1 : cell_t cell;
22 1 : (void) arg;
23 :
24 1 : cell_queue_init(&cq);
25 1 : tt_int_op(cq.n, OP_EQ, 0);
26 :
27 1 : pc1 = packed_cell_new();
28 1 : pc2 = packed_cell_new();
29 1 : pc3 = packed_cell_new();
30 1 : pc4 = packed_cell_new();
31 1 : tt_assert(pc1 && pc2 && pc3 && pc4);
32 :
33 1 : tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));
34 :
35 : /* Add and remove a singleton. */
36 1 : cell_queue_append(&cq, pc1);
37 1 : tt_int_op(cq.n, OP_EQ, 1);
38 1 : tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq));
39 1 : tt_int_op(cq.n, OP_EQ, 0);
40 :
41 : /* Add and remove four items */
42 1 : cell_queue_append(&cq, pc4);
43 1 : cell_queue_append(&cq, pc3);
44 1 : cell_queue_append(&cq, pc2);
45 1 : cell_queue_append(&cq, pc1);
46 1 : tt_int_op(cq.n, OP_EQ, 4);
47 1 : tt_ptr_op(pc4, OP_EQ, cell_queue_pop(&cq));
48 1 : tt_ptr_op(pc3, OP_EQ, cell_queue_pop(&cq));
49 1 : tt_ptr_op(pc2, OP_EQ, cell_queue_pop(&cq));
50 1 : tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq));
51 1 : tt_int_op(cq.n, OP_EQ, 0);
52 1 : tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));
53 :
54 : /* Try a packed copy (wide, then narrow, which is a bit of a cheat, since a
55 : * real cell queue has only one type.) */
56 1 : memset(&cell, 0, sizeof(cell));
57 1 : cell.circ_id = 0x12345678;
58 1 : cell.command = 10;
59 1 : strlcpy((char*)cell.payload, "Lorax ipsum gruvvulus thneed amet, snergelly "
60 : "once-ler lerkim, sed do barbaloot tempor gluppitus ut labore et "
61 : "truffula magna aliqua.",
62 : sizeof(cell.payload));
63 1 : cell_queue_append_packed_copy(NULL /*circ*/, &cq, 0 /*exitward*/, &cell,
64 : 1 /*wide*/, 0 /*stats*/);
65 1 : cell.circ_id = 0x2013;
66 1 : cell_queue_append_packed_copy(NULL /*circ*/, &cq, 0 /*exitward*/, &cell,
67 : 0 /*wide*/, 0 /*stats*/);
68 1 : tt_int_op(cq.n, OP_EQ, 2);
69 :
70 1 : pc_tmp = cell_queue_pop(&cq);
71 1 : tt_int_op(cq.n, OP_EQ, 1);
72 1 : tt_ptr_op(pc_tmp, OP_NE, NULL);
73 1 : tt_mem_op(pc_tmp->body, OP_EQ, "\x12\x34\x56\x78\x0a", 5);
74 1 : tt_mem_op(pc_tmp->body+5, OP_EQ, cell.payload, sizeof(cell.payload));
75 1 : packed_cell_free(pc_tmp);
76 :
77 1 : pc_tmp = cell_queue_pop(&cq);
78 1 : tt_int_op(cq.n, OP_EQ, 0);
79 1 : tt_ptr_op(pc_tmp, OP_NE, NULL);
80 1 : tt_mem_op(pc_tmp->body, OP_EQ, "\x20\x13\x0a", 3);
81 1 : tt_mem_op(pc_tmp->body+3, OP_EQ, cell.payload, sizeof(cell.payload));
82 1 : packed_cell_free(pc_tmp);
83 1 : pc_tmp = NULL;
84 :
85 1 : tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));
86 :
87 : /* Now make sure cell_queue_clear works. */
88 1 : cell_queue_append(&cq, pc2);
89 1 : cell_queue_append(&cq, pc1);
90 1 : tt_int_op(cq.n, OP_EQ, 2);
91 1 : cell_queue_clear(&cq);
92 1 : pc2 = pc1 = NULL; /* prevent double-free */
93 1 : tt_int_op(cq.n, OP_EQ, 0);
94 :
95 1 : done:
96 1 : packed_cell_free(pc1);
97 1 : packed_cell_free(pc2);
98 1 : packed_cell_free(pc3);
99 1 : packed_cell_free(pc4);
100 1 : packed_cell_free(pc_tmp);
101 :
102 1 : cell_queue_clear(&cq);
103 1 : }
104 :
105 : static void
106 1 : test_circuit_n_cells(void *arg)
107 : {
108 1 : packed_cell_t *pc1=NULL, *pc2=NULL, *pc3=NULL, *pc4=NULL, *pc5=NULL;
109 1 : origin_circuit_t *origin_c=NULL;
110 1 : or_circuit_t *or_c=NULL;
111 :
112 1 : (void)arg;
113 :
114 1 : pc1 = packed_cell_new();
115 1 : pc2 = packed_cell_new();
116 1 : pc3 = packed_cell_new();
117 1 : pc4 = packed_cell_new();
118 1 : pc5 = packed_cell_new();
119 1 : tt_assert(pc1 && pc2 && pc3 && pc4 && pc5);
120 :
121 1 : or_c = or_circuit_new(0, NULL);
122 1 : origin_c = origin_circuit_new();
123 1 : origin_c->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
124 :
125 1 : tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 0);
126 1 : cell_queue_append(&or_c->p_chan_cells, pc1);
127 1 : tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 1);
128 1 : cell_queue_append(&or_c->base_.n_chan_cells, pc2);
129 1 : cell_queue_append(&or_c->base_.n_chan_cells, pc3);
130 1 : tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 3);
131 :
132 1 : tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), OP_EQ, 0);
133 1 : cell_queue_append(&origin_c->base_.n_chan_cells, pc4);
134 1 : cell_queue_append(&origin_c->base_.n_chan_cells, pc5);
135 1 : tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), OP_EQ, 2);
136 :
137 1 : done:
138 1 : circuit_free_(TO_CIRCUIT(or_c));
139 1 : circuit_free_(TO_CIRCUIT(origin_c));
140 1 : }
141 :
142 : struct testcase_t cell_queue_tests[] = {
143 : { "basic", test_cq_manip, TT_FORK, NULL, NULL, },
144 : { "circ_n_cells", test_circuit_n_cells, TT_FORK, NULL, NULL },
145 : END_OF_TESTCASES
146 : };
147 :
|