xref: /freebsd/crypto/openssl/ssl/pqueue.c (revision e71b70530d95c4f34d8bdbd78d1242df1ba4a945)
1*e71b7053SJung-uk Kim /*
2*e71b7053SJung-uk Kim  * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved.
3*e71b7053SJung-uk Kim  *
4*e71b7053SJung-uk Kim  * Licensed under the OpenSSL license (the "License").  You may not use
5*e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6*e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7*e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
8*e71b7053SJung-uk Kim  */
9*e71b7053SJung-uk Kim 
10*e71b7053SJung-uk Kim #include "ssl_locl.h"
11*e71b7053SJung-uk Kim #include <openssl/bn.h>
12*e71b7053SJung-uk Kim 
13*e71b7053SJung-uk Kim struct pqueue_st {
14*e71b7053SJung-uk Kim     pitem *items;
15*e71b7053SJung-uk Kim     int count;
16*e71b7053SJung-uk Kim };
17*e71b7053SJung-uk Kim 
18*e71b7053SJung-uk Kim pitem *pitem_new(unsigned char *prio64be, void *data)
19*e71b7053SJung-uk Kim {
20*e71b7053SJung-uk Kim     pitem *item = OPENSSL_malloc(sizeof(*item));
21*e71b7053SJung-uk Kim 
22*e71b7053SJung-uk Kim     if (item == NULL) {
23*e71b7053SJung-uk Kim         SSLerr(SSL_F_PITEM_NEW, ERR_R_MALLOC_FAILURE);
24*e71b7053SJung-uk Kim         return NULL;
25*e71b7053SJung-uk Kim     }
26*e71b7053SJung-uk Kim 
27*e71b7053SJung-uk Kim     memcpy(item->priority, prio64be, sizeof(item->priority));
28*e71b7053SJung-uk Kim     item->data = data;
29*e71b7053SJung-uk Kim     item->next = NULL;
30*e71b7053SJung-uk Kim     return item;
31*e71b7053SJung-uk Kim }
32*e71b7053SJung-uk Kim 
33*e71b7053SJung-uk Kim void pitem_free(pitem *item)
34*e71b7053SJung-uk Kim {
35*e71b7053SJung-uk Kim     OPENSSL_free(item);
36*e71b7053SJung-uk Kim }
37*e71b7053SJung-uk Kim 
38*e71b7053SJung-uk Kim pqueue *pqueue_new(void)
39*e71b7053SJung-uk Kim {
40*e71b7053SJung-uk Kim     pqueue *pq = OPENSSL_zalloc(sizeof(*pq));
41*e71b7053SJung-uk Kim 
42*e71b7053SJung-uk Kim     if (pq == NULL)
43*e71b7053SJung-uk Kim         SSLerr(SSL_F_PQUEUE_NEW, ERR_R_MALLOC_FAILURE);
44*e71b7053SJung-uk Kim 
45*e71b7053SJung-uk Kim     return pq;
46*e71b7053SJung-uk Kim }
47*e71b7053SJung-uk Kim 
48*e71b7053SJung-uk Kim void pqueue_free(pqueue *pq)
49*e71b7053SJung-uk Kim {
50*e71b7053SJung-uk Kim     OPENSSL_free(pq);
51*e71b7053SJung-uk Kim }
52*e71b7053SJung-uk Kim 
53*e71b7053SJung-uk Kim pitem *pqueue_insert(pqueue *pq, pitem *item)
54*e71b7053SJung-uk Kim {
55*e71b7053SJung-uk Kim     pitem *curr, *next;
56*e71b7053SJung-uk Kim 
57*e71b7053SJung-uk Kim     if (pq->items == NULL) {
58*e71b7053SJung-uk Kim         pq->items = item;
59*e71b7053SJung-uk Kim         return item;
60*e71b7053SJung-uk Kim     }
61*e71b7053SJung-uk Kim 
62*e71b7053SJung-uk Kim     for (curr = NULL, next = pq->items;
63*e71b7053SJung-uk Kim          next != NULL; curr = next, next = next->next) {
64*e71b7053SJung-uk Kim         /*
65*e71b7053SJung-uk Kim          * we can compare 64-bit value in big-endian encoding with memcmp:-)
66*e71b7053SJung-uk Kim          */
67*e71b7053SJung-uk Kim         int cmp = memcmp(next->priority, item->priority, 8);
68*e71b7053SJung-uk Kim         if (cmp > 0) {          /* next > item */
69*e71b7053SJung-uk Kim             item->next = next;
70*e71b7053SJung-uk Kim 
71*e71b7053SJung-uk Kim             if (curr == NULL)
72*e71b7053SJung-uk Kim                 pq->items = item;
73*e71b7053SJung-uk Kim             else
74*e71b7053SJung-uk Kim                 curr->next = item;
75*e71b7053SJung-uk Kim 
76*e71b7053SJung-uk Kim             return item;
77*e71b7053SJung-uk Kim         }
78*e71b7053SJung-uk Kim 
79*e71b7053SJung-uk Kim         else if (cmp == 0)      /* duplicates not allowed */
80*e71b7053SJung-uk Kim             return NULL;
81*e71b7053SJung-uk Kim     }
82*e71b7053SJung-uk Kim 
83*e71b7053SJung-uk Kim     item->next = NULL;
84*e71b7053SJung-uk Kim     curr->next = item;
85*e71b7053SJung-uk Kim 
86*e71b7053SJung-uk Kim     return item;
87*e71b7053SJung-uk Kim }
88*e71b7053SJung-uk Kim 
89*e71b7053SJung-uk Kim pitem *pqueue_peek(pqueue *pq)
90*e71b7053SJung-uk Kim {
91*e71b7053SJung-uk Kim     return pq->items;
92*e71b7053SJung-uk Kim }
93*e71b7053SJung-uk Kim 
94*e71b7053SJung-uk Kim pitem *pqueue_pop(pqueue *pq)
95*e71b7053SJung-uk Kim {
96*e71b7053SJung-uk Kim     pitem *item = pq->items;
97*e71b7053SJung-uk Kim 
98*e71b7053SJung-uk Kim     if (pq->items != NULL)
99*e71b7053SJung-uk Kim         pq->items = pq->items->next;
100*e71b7053SJung-uk Kim 
101*e71b7053SJung-uk Kim     return item;
102*e71b7053SJung-uk Kim }
103*e71b7053SJung-uk Kim 
104*e71b7053SJung-uk Kim pitem *pqueue_find(pqueue *pq, unsigned char *prio64be)
105*e71b7053SJung-uk Kim {
106*e71b7053SJung-uk Kim     pitem *next;
107*e71b7053SJung-uk Kim     pitem *found = NULL;
108*e71b7053SJung-uk Kim 
109*e71b7053SJung-uk Kim     if (pq->items == NULL)
110*e71b7053SJung-uk Kim         return NULL;
111*e71b7053SJung-uk Kim 
112*e71b7053SJung-uk Kim     for (next = pq->items; next->next != NULL; next = next->next) {
113*e71b7053SJung-uk Kim         if (memcmp(next->priority, prio64be, 8) == 0) {
114*e71b7053SJung-uk Kim             found = next;
115*e71b7053SJung-uk Kim             break;
116*e71b7053SJung-uk Kim         }
117*e71b7053SJung-uk Kim     }
118*e71b7053SJung-uk Kim 
119*e71b7053SJung-uk Kim     /* check the one last node */
120*e71b7053SJung-uk Kim     if (memcmp(next->priority, prio64be, 8) == 0)
121*e71b7053SJung-uk Kim         found = next;
122*e71b7053SJung-uk Kim 
123*e71b7053SJung-uk Kim     if (!found)
124*e71b7053SJung-uk Kim         return NULL;
125*e71b7053SJung-uk Kim 
126*e71b7053SJung-uk Kim     return found;
127*e71b7053SJung-uk Kim }
128*e71b7053SJung-uk Kim 
129*e71b7053SJung-uk Kim pitem *pqueue_iterator(pqueue *pq)
130*e71b7053SJung-uk Kim {
131*e71b7053SJung-uk Kim     return pqueue_peek(pq);
132*e71b7053SJung-uk Kim }
133*e71b7053SJung-uk Kim 
134*e71b7053SJung-uk Kim pitem *pqueue_next(piterator *item)
135*e71b7053SJung-uk Kim {
136*e71b7053SJung-uk Kim     pitem *ret;
137*e71b7053SJung-uk Kim 
138*e71b7053SJung-uk Kim     if (item == NULL || *item == NULL)
139*e71b7053SJung-uk Kim         return NULL;
140*e71b7053SJung-uk Kim 
141*e71b7053SJung-uk Kim     /* *item != NULL */
142*e71b7053SJung-uk Kim     ret = *item;
143*e71b7053SJung-uk Kim     *item = (*item)->next;
144*e71b7053SJung-uk Kim 
145*e71b7053SJung-uk Kim     return ret;
146*e71b7053SJung-uk Kim }
147*e71b7053SJung-uk Kim 
148*e71b7053SJung-uk Kim size_t pqueue_size(pqueue *pq)
149*e71b7053SJung-uk Kim {
150*e71b7053SJung-uk Kim     pitem *item = pq->items;
151*e71b7053SJung-uk Kim     size_t count = 0;
152*e71b7053SJung-uk Kim 
153*e71b7053SJung-uk Kim     while (item != NULL) {
154*e71b7053SJung-uk Kim         count++;
155*e71b7053SJung-uk Kim         item = item->next;
156*e71b7053SJung-uk Kim     }
157*e71b7053SJung-uk Kim     return count;
158*e71b7053SJung-uk Kim }
159