1160814Ssimon/* crypto/pqueue/pqueue.c */
2280297Sjkim/*
3160814Ssimon * DTLS implementation written by Nagendra Modadugu
4280297Sjkim * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5160814Ssimon */
6160814Ssimon/* ====================================================================
7160814Ssimon * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
8160814Ssimon *
9160814Ssimon * Redistribution and use in source and binary forms, with or without
10160814Ssimon * modification, are permitted provided that the following conditions
11160814Ssimon * are met:
12160814Ssimon *
13160814Ssimon * 1. Redistributions of source code must retain the above copyright
14280297Sjkim *    notice, this list of conditions and the following disclaimer.
15160814Ssimon *
16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright
17160814Ssimon *    notice, this list of conditions and the following disclaimer in
18160814Ssimon *    the documentation and/or other materials provided with the
19160814Ssimon *    distribution.
20160814Ssimon *
21160814Ssimon * 3. All advertising materials mentioning features or use of this
22160814Ssimon *    software must display the following acknowledgment:
23160814Ssimon *    "This product includes software developed by the OpenSSL Project
24160814Ssimon *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25160814Ssimon *
26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27160814Ssimon *    endorse or promote products derived from this software without
28160814Ssimon *    prior written permission. For written permission, please contact
29160814Ssimon *    openssl-core@OpenSSL.org.
30160814Ssimon *
31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL"
32160814Ssimon *    nor may "OpenSSL" appear in their names without prior written
33160814Ssimon *    permission of the OpenSSL Project.
34160814Ssimon *
35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following
36160814Ssimon *    acknowledgment:
37160814Ssimon *    "This product includes software developed by the OpenSSL Project
38160814Ssimon *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39160814Ssimon *
40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43160814Ssimon * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE.
52160814Ssimon * ====================================================================
53160814Ssimon *
54160814Ssimon * This product includes cryptographic software written by Eric Young
55160814Ssimon * (eay@cryptsoft.com).  This product includes software written by Tim
56160814Ssimon * Hudson (tjh@cryptsoft.com).
57160814Ssimon *
58160814Ssimon */
59160814Ssimon
60160814Ssimon#include "cryptlib.h"
61160814Ssimon#include <openssl/bn.h>
62160814Ssimon#include "pqueue.h"
63160814Ssimon
64280297Sjkimtypedef struct _pqueue {
65280297Sjkim    pitem *items;
66280297Sjkim    int count;
67280297Sjkim} pqueue_s;
68160814Ssimon
69280297Sjkimpitem *pitem_new(unsigned char *prio64be, void *data)
70280297Sjkim{
71280297Sjkim    pitem *item = (pitem *)OPENSSL_malloc(sizeof(pitem));
72280297Sjkim    if (item == NULL)
73280297Sjkim        return NULL;
74160814Ssimon
75280297Sjkim    memcpy(item->priority, prio64be, sizeof(item->priority));
76160814Ssimon
77280297Sjkim    item->data = data;
78280297Sjkim    item->next = NULL;
79160814Ssimon
80280297Sjkim    return item;
81280297Sjkim}
82160814Ssimon
83280297Sjkimvoid pitem_free(pitem *item)
84280297Sjkim{
85280297Sjkim    if (item == NULL)
86280297Sjkim        return;
87160814Ssimon
88280297Sjkim    OPENSSL_free(item);
89280297Sjkim}
90160814Ssimon
91280297Sjkimpqueue_s *pqueue_new()
92280297Sjkim{
93280297Sjkim    pqueue_s *pq = (pqueue_s *)OPENSSL_malloc(sizeof(pqueue_s));
94280297Sjkim    if (pq == NULL)
95280297Sjkim        return NULL;
96160814Ssimon
97280297Sjkim    memset(pq, 0x00, sizeof(pqueue_s));
98280297Sjkim    return pq;
99280297Sjkim}
100160814Ssimon
101280297Sjkimvoid pqueue_free(pqueue_s *pq)
102280297Sjkim{
103280297Sjkim    if (pq == NULL)
104280297Sjkim        return;
105160814Ssimon
106280297Sjkim    OPENSSL_free(pq);
107280297Sjkim}
108160814Ssimon
109280297Sjkimpitem *pqueue_insert(pqueue_s *pq, pitem *item)
110280297Sjkim{
111280297Sjkim    pitem *curr, *next;
112160814Ssimon
113280297Sjkim    if (pq->items == NULL) {
114280297Sjkim        pq->items = item;
115280297Sjkim        return item;
116280297Sjkim    }
117160814Ssimon
118280297Sjkim    for (curr = NULL, next = pq->items;
119280297Sjkim         next != NULL; curr = next, next = next->next) {
120280297Sjkim        /*
121280297Sjkim         * we can compare 64-bit value in big-endian encoding with memcmp:-)
122280297Sjkim         */
123280297Sjkim        int cmp = memcmp(next->priority, item->priority, 8);
124280297Sjkim        if (cmp > 0) {          /* next > item */
125280297Sjkim            item->next = next;
126160814Ssimon
127280297Sjkim            if (curr == NULL)
128280297Sjkim                pq->items = item;
129280297Sjkim            else
130280297Sjkim                curr->next = item;
131160814Ssimon
132280297Sjkim            return item;
133280297Sjkim        }
134160814Ssimon
135280297Sjkim        else if (cmp == 0)      /* duplicates not allowed */
136280297Sjkim            return NULL;
137280297Sjkim    }
138160814Ssimon
139280297Sjkim    item->next = NULL;
140280297Sjkim    curr->next = item;
141160814Ssimon
142280297Sjkim    return item;
143280297Sjkim}
144160814Ssimon
145280297Sjkimpitem *pqueue_peek(pqueue_s *pq)
146280297Sjkim{
147280297Sjkim    return pq->items;
148280297Sjkim}
149160814Ssimon
150280297Sjkimpitem *pqueue_pop(pqueue_s *pq)
151280297Sjkim{
152280297Sjkim    pitem *item = pq->items;
153160814Ssimon
154280297Sjkim    if (pq->items != NULL)
155280297Sjkim        pq->items = pq->items->next;
156160814Ssimon
157280297Sjkim    return item;
158280297Sjkim}
159160814Ssimon
160280297Sjkimpitem *pqueue_find(pqueue_s *pq, unsigned char *prio64be)
161280297Sjkim{
162280297Sjkim    pitem *next;
163280297Sjkim    pitem *found = NULL;
164160814Ssimon
165280297Sjkim    if (pq->items == NULL)
166280297Sjkim        return NULL;
167160814Ssimon
168280297Sjkim    for (next = pq->items; next->next != NULL; next = next->next) {
169280297Sjkim        if (memcmp(next->priority, prio64be, 8) == 0) {
170280297Sjkim            found = next;
171280297Sjkim            break;
172280297Sjkim        }
173280297Sjkim    }
174160814Ssimon
175280297Sjkim    /* check the one last node */
176280297Sjkim    if (memcmp(next->priority, prio64be, 8) == 0)
177280297Sjkim        found = next;
178280297Sjkim
179280297Sjkim    if (!found)
180280297Sjkim        return NULL;
181280297Sjkim
182280297Sjkim#if 0                           /* find works in peek mode */
183280297Sjkim    if (prev == NULL)
184280297Sjkim        pq->items = next->next;
185280297Sjkim    else
186280297Sjkim        prev->next = next->next;
187238405Sjkim#endif
188238405Sjkim
189280297Sjkim    return found;
190280297Sjkim}
191160814Ssimon
192280297Sjkimvoid pqueue_print(pqueue_s *pq)
193280297Sjkim{
194280297Sjkim    pitem *item = pq->items;
195160814Ssimon
196280297Sjkim    while (item != NULL) {
197280297Sjkim        printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n",
198280297Sjkim               item->priority[0], item->priority[1],
199280297Sjkim               item->priority[2], item->priority[3],
200280297Sjkim               item->priority[4], item->priority[5],
201280297Sjkim               item->priority[6], item->priority[7]);
202280297Sjkim        item = item->next;
203280297Sjkim    }
204280297Sjkim}
205160814Ssimon
206280297Sjkimpitem *pqueue_iterator(pqueue_s *pq)
207280297Sjkim{
208280297Sjkim    return pqueue_peek(pq);
209280297Sjkim}
210160814Ssimon
211280297Sjkimpitem *pqueue_next(pitem **item)
212280297Sjkim{
213280297Sjkim    pitem *ret;
214160814Ssimon
215280297Sjkim    if (item == NULL || *item == NULL)
216280297Sjkim        return NULL;
217160814Ssimon
218280297Sjkim    /* *item != NULL */
219280297Sjkim    ret = *item;
220280297Sjkim    *item = (*item)->next;
221160814Ssimon
222280297Sjkim    return ret;
223280297Sjkim}
224160814Ssimon
225280297Sjkimint pqueue_size(pqueue_s *pq)
226280297Sjkim{
227280297Sjkim    pitem *item = pq->items;
228280297Sjkim    int count = 0;
229196474Ssimon
230280297Sjkim    while (item != NULL) {
231280297Sjkim        count++;
232280297Sjkim        item = item->next;
233280297Sjkim    }
234280297Sjkim    return count;
235196474Ssimon}
236