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