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
test_cq_manip(void * arg)17 test_cq_manip(void *arg)
18 {
19   packed_cell_t *pc1=NULL, *pc2=NULL, *pc3=NULL, *pc4=NULL, *pc_tmp=NULL;
20   cell_queue_t cq;
21   cell_t cell;
22   (void) arg;
23 
24   cell_queue_init(&cq);
25   tt_int_op(cq.n, OP_EQ, 0);
26 
27   pc1 = packed_cell_new();
28   pc2 = packed_cell_new();
29   pc3 = packed_cell_new();
30   pc4 = packed_cell_new();
31   tt_assert(pc1 && pc2 && pc3 && pc4);
32 
33   tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));
34 
35   /* Add and remove a singleton. */
36   cell_queue_append(&cq, pc1);
37   tt_int_op(cq.n, OP_EQ, 1);
38   tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq));
39   tt_int_op(cq.n, OP_EQ, 0);
40 
41   /* Add and remove four items */
42   cell_queue_append(&cq, pc4);
43   cell_queue_append(&cq, pc3);
44   cell_queue_append(&cq, pc2);
45   cell_queue_append(&cq, pc1);
46   tt_int_op(cq.n, OP_EQ, 4);
47   tt_ptr_op(pc4, OP_EQ, cell_queue_pop(&cq));
48   tt_ptr_op(pc3, OP_EQ, cell_queue_pop(&cq));
49   tt_ptr_op(pc2, OP_EQ, cell_queue_pop(&cq));
50   tt_ptr_op(pc1, OP_EQ, cell_queue_pop(&cq));
51   tt_int_op(cq.n, OP_EQ, 0);
52   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   memset(&cell, 0, sizeof(cell));
57   cell.circ_id = 0x12345678;
58   cell.command = 10;
59   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   cell_queue_append_packed_copy(NULL /*circ*/, &cq, 0 /*exitward*/, &cell,
64                                 1 /*wide*/, 0 /*stats*/);
65   cell.circ_id = 0x2013;
66   cell_queue_append_packed_copy(NULL /*circ*/, &cq, 0 /*exitward*/, &cell,
67                                 0 /*wide*/, 0 /*stats*/);
68   tt_int_op(cq.n, OP_EQ, 2);
69 
70   pc_tmp = cell_queue_pop(&cq);
71   tt_int_op(cq.n, OP_EQ, 1);
72   tt_ptr_op(pc_tmp, OP_NE, NULL);
73   tt_mem_op(pc_tmp->body, OP_EQ, "\x12\x34\x56\x78\x0a", 5);
74   tt_mem_op(pc_tmp->body+5, OP_EQ, cell.payload, sizeof(cell.payload));
75   packed_cell_free(pc_tmp);
76 
77   pc_tmp = cell_queue_pop(&cq);
78   tt_int_op(cq.n, OP_EQ, 0);
79   tt_ptr_op(pc_tmp, OP_NE, NULL);
80   tt_mem_op(pc_tmp->body, OP_EQ, "\x20\x13\x0a", 3);
81   tt_mem_op(pc_tmp->body+3, OP_EQ, cell.payload, sizeof(cell.payload));
82   packed_cell_free(pc_tmp);
83   pc_tmp = NULL;
84 
85   tt_ptr_op(NULL, OP_EQ, cell_queue_pop(&cq));
86 
87   /* Now make sure cell_queue_clear works. */
88   cell_queue_append(&cq, pc2);
89   cell_queue_append(&cq, pc1);
90   tt_int_op(cq.n, OP_EQ, 2);
91   cell_queue_clear(&cq);
92   pc2 = pc1 = NULL; /* prevent double-free */
93   tt_int_op(cq.n, OP_EQ, 0);
94 
95  done:
96   packed_cell_free(pc1);
97   packed_cell_free(pc2);
98   packed_cell_free(pc3);
99   packed_cell_free(pc4);
100   packed_cell_free(pc_tmp);
101 
102   cell_queue_clear(&cq);
103 }
104 
105 static void
test_circuit_n_cells(void * arg)106 test_circuit_n_cells(void *arg)
107 {
108   packed_cell_t *pc1=NULL, *pc2=NULL, *pc3=NULL, *pc4=NULL, *pc5=NULL;
109   origin_circuit_t *origin_c=NULL;
110   or_circuit_t *or_c=NULL;
111 
112   (void)arg;
113 
114   pc1 = packed_cell_new();
115   pc2 = packed_cell_new();
116   pc3 = packed_cell_new();
117   pc4 = packed_cell_new();
118   pc5 = packed_cell_new();
119   tt_assert(pc1 && pc2 && pc3 && pc4 && pc5);
120 
121   or_c = or_circuit_new(0, NULL);
122   origin_c = origin_circuit_new();
123   origin_c->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
124 
125   tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 0);
126   cell_queue_append(&or_c->p_chan_cells, pc1);
127   tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 1);
128   cell_queue_append(&or_c->base_.n_chan_cells, pc2);
129   cell_queue_append(&or_c->base_.n_chan_cells, pc3);
130   tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(or_c)), OP_EQ, 3);
131 
132   tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), OP_EQ, 0);
133   cell_queue_append(&origin_c->base_.n_chan_cells, pc4);
134   cell_queue_append(&origin_c->base_.n_chan_cells, pc5);
135   tt_int_op(n_cells_in_circ_queues(TO_CIRCUIT(origin_c)), OP_EQ, 2);
136 
137  done:
138   circuit_free_(TO_CIRCUIT(or_c));
139   circuit_free_(TO_CIRCUIT(origin_c));
140 }
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 
148