"Fossies" - the Fresh Open Source Software Archive 
Member "apache-zookeeper-3.8.1/zookeeper-client/zookeeper-client-c/src/addrvec.c" (25 Jan 2023, 5938 Bytes) of package /linux/misc/apache-zookeeper-3.8.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "addrvec.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
3.6.0_vs_3.6.1.
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <assert.h>
22 #include <errno.h>
23 #ifdef WIN32
24 #define random rand /* replace POSIX random with Windows rand */
25 #include <winsock2.h> /* must always be included before ws2tcpip.h */
26 #include <ws2tcpip.h> /* for sockaddr_storage */
27 #include "winport.h"
28 #endif
29
30 #include "addrvec.h"
31
32 #define ADDRVEC_DEFAULT_GROW_AMOUNT 16
33
34 void addrvec_init(addrvec_t *avec)
35 {
36 assert(avec);
37 avec->next = 0;
38 avec->count = 0;
39 avec->capacity = 0;
40 avec->data = NULL;
41 }
42
43 void addrvec_free(addrvec_t *avec)
44 {
45 if (avec == NULL)
46 {
47 return;
48 }
49
50 avec->next = 0;
51 avec->count = 0;
52 avec->capacity = 0;
53 if (avec->data) {
54 free(avec->data);
55 avec->data = NULL;
56 }
57 }
58
59 int addrvec_alloc(addrvec_t *avec)
60 {
61 addrvec_init(avec);
62 return addrvec_grow_default(avec);
63 }
64
65 int addrvec_alloc_capacity(addrvec_t* avec, uint32_t capacity)
66 {
67 addrvec_init(avec);
68 return addrvec_grow(avec, capacity);
69 }
70
71 int addrvec_grow(addrvec_t *avec, uint32_t grow_amount)
72 {
73 unsigned int old_capacity = 0;
74 struct sockaddr_storage *old_data = NULL;
75 assert(avec);
76
77 if (grow_amount == 0)
78 {
79 return 0;
80 }
81
82 // Save off old data and capacity in case there is a realloc failure
83 old_capacity = avec->capacity;
84 old_data = avec->data;
85
86 avec->capacity += grow_amount;
87 avec->data = realloc(avec->data, sizeof(*avec->data) * avec->capacity);
88 if (avec->data == NULL)
89 {
90 avec->capacity = old_capacity;
91 avec->data = old_data;
92 errno = ENOMEM;
93 return 1;
94 }
95
96 return 0;
97 }
98
99 int addrvec_grow_default(addrvec_t *avec)
100 {
101 return addrvec_grow(avec, ADDRVEC_DEFAULT_GROW_AMOUNT);
102 }
103
104 static int addrvec_grow_if_full(addrvec_t *avec)
105 {
106 assert(avec);
107 if (avec->count == avec->capacity)
108 {
109 int rc = addrvec_grow_default(avec);
110 if (rc != 0)
111 {
112 return rc;
113 }
114 }
115
116 return 0;
117 }
118
119 int addrvec_contains(const addrvec_t *avec, const struct sockaddr_storage *addr)
120 {
121 uint32_t i = 0;
122 if (!avec || !addr)
123 {
124 return 0;
125 }
126
127 for (i = 0; i < avec->count; i++)
128 {
129 if (avec->data[i].ss_family != addr->ss_family)
130 continue;
131 switch (addr->ss_family) {
132 case AF_INET:
133 if (memcmp(&((struct sockaddr_in*)&avec->data[i])->sin_addr,
134 &((struct sockaddr_in*)addr)->sin_addr,
135 sizeof(struct in_addr)) == 0)
136 return 1;
137 break;
138 #ifdef AF_INET6
139 case AF_INET6:
140 if (memcmp(&((struct sockaddr_in6*)&avec->data[i])->sin6_addr,
141 &((struct sockaddr_in6*)addr)->sin6_addr,
142 sizeof(struct in6_addr)) == 0)
143 return 1;
144 break;
145 #endif
146 default:
147 break;
148 }
149 }
150
151 return 0;
152 }
153
154 int addrvec_append(addrvec_t *avec, const struct sockaddr_storage *addr)
155 {
156 int rc = 0;
157 assert(avec);
158 assert(addr);
159
160 rc = addrvec_grow_if_full(avec);
161 if (rc != 0)
162 {
163 return rc;
164 }
165
166 // Copy addrinfo into address list
167 memcpy(avec->data + avec->count, addr, sizeof(*addr));
168 ++avec->count;
169
170 return 0;
171 }
172
173 int addrvec_append_addrinfo(addrvec_t *avec, const struct addrinfo *addrinfo)
174 {
175 int rc = 0;
176 assert(avec);
177 assert(addrinfo);
178
179 rc = addrvec_grow_if_full(avec);
180 if (rc != 0)
181 {
182 return rc;
183 }
184
185 // Copy addrinfo into address list
186 memcpy(avec->data + avec->count, addrinfo->ai_addr, addrinfo->ai_addrlen);
187 ++avec->count;
188
189 return 0;
190 }
191
192 void addrvec_shuffle(addrvec_t *avec)
193 {
194 int i = 0;
195 for (i = avec->count - 1; i > 0; --i) {
196 long int j = random()%(i+1);
197 if (i != j) {
198 struct sockaddr_storage t = avec->data[i];
199 avec->data[i] = avec->data[j];
200 avec->data[j] = t;
201 }
202 }
203 }
204
205 int addrvec_hasnext(const addrvec_t *avec)
206 {
207 return avec->count > 0 && (avec->next < avec->count);
208 }
209
210 int addrvec_atend(const addrvec_t *avec)
211 {
212 return avec->count > 0 && avec->next >= avec->count;
213 }
214
215 void addrvec_next(addrvec_t *avec, struct sockaddr_storage *next)
216 {
217 int index;
218
219 // If we're at the end of the list, then reset index to start
220 if (addrvec_atend(avec)) {
221 avec->next = 0;
222 }
223
224 if (!addrvec_hasnext(avec)) {
225 if (next) {
226 memset(next, 0, sizeof(*next));
227 }
228
229 return;
230 }
231
232 index = avec->next++;
233
234 if (next) {
235 *next = avec->data[index];
236 }
237 }
238
239 void addrvec_peek(addrvec_t *avec, struct sockaddr_storage *next)
240 {
241 int index = avec->next;
242
243 if (avec->count == 0) {
244 memset(next, 0, sizeof(*next));
245 return;
246 }
247
248 if (addrvec_atend(avec)) {
249 index = 0;
250 }
251
252 *next = avec->data[index];
253 }
254
255
256 int addrvec_eq(const addrvec_t *a1, const addrvec_t *a2)
257 {
258 uint32_t i = 0;
259 if (a1->count != a2->count)
260 {
261 return 0;
262 }
263
264 for (i = 0; i < a1->count; ++i)
265 {
266 if (!addrvec_contains(a2, &a1->data[i]))
267 return 0;
268 }
269
270 return 1;
271 }