ims_ipsec_pcscf: fixed possible use of uninitialized value in ipsec_forward()
[sip-router] / src / modules / ims_ipsec_pcscf / spi_gen.c
1 /*
2  * IMS IPSEC PCSCF module
3  *
4  * Copyright (C) 2018 Tsvetomir Dimitrov
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include "spi_gen.h"
25 #include "spi_list.h"
26 #include <pthread.h>
27
28 pthread_mutex_t spis_mut;
29 spi_list_t used_spis;
30 uint32_t spi_val;
31 uint32_t min_spi;
32 uint32_t max_spi;
33
34 int init_spi_gen(uint32_t start_val, uint32_t range)
35 {
36     if(start_val < 1) {
37         return 1;
38     }
39
40     if(UINT32_MAX - range < start_val)
41         return 2;
42
43     if(pthread_mutex_init(&spis_mut, NULL))
44         return 3;
45
46     used_spis = create_list();
47
48     spi_val = start_val;
49     min_spi = start_val;
50     max_spi = start_val + range;
51
52     return 0;
53 }
54
55 uint32_t acquire_spi()
56 {
57     //save the initial value for the highly unlikely case where there are no free SPIs
58     uint32_t initial_val = spi_val;
59     uint32_t ret = 0; // by default return invalid SPI
60
61     if(pthread_mutex_lock(&spis_mut) != 0) {
62         return ret;
63     }
64
65     while(1) {
66         if(spi_in_list(&used_spis, spi_val) == 0) {
67             ret = spi_val;
68             spi_val++;
69             break;
70         }
71
72         spi_val++; //the current SPI is not available - increment
73
74         if(spi_val >= max_spi) { //reached the top of the range - reset
75             spi_val = min_spi;
76         }
77
78         if(spi_val == initial_val) { //there are no free SPIs
79             break;
80         }
81
82     }
83
84     //found unused SPI - add it to the used list
85     if(spi_add(&used_spis, ret) != 0) {
86         ret = 0;
87     }
88
89     pthread_mutex_unlock(&spis_mut);
90
91     return ret;
92 }
93
94 int release_spi(uint32_t id)
95 {
96     if(pthread_mutex_lock(&spis_mut) != 0) {
97         return 1;
98     }
99
100     spi_remove(&used_spis, id);
101
102     pthread_mutex_unlock(&spis_mut);
103
104     return 0;
105 }
106
107 int destroy_spi_gen()
108 {
109     return pthread_mutex_destroy(&spis_mut);
110 }