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