123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <errno.h>
- #ifdef WIN32
- #define random rand /* replace POSIX random with Windows rand */
- #include <winsock2.h> /* must always be included before ws2tcpip.h */
- #include <ws2tcpip.h> /* for sockaddr_storage */
- #include "winport.h"
- #endif
- #include "addrvec.h"
- #define ADDRVEC_DEFAULT_GROW_AMOUNT 16
- void addrvec_init(addrvec_t *avec)
- {
- assert(avec);
- avec->next = 0;
- avec->count = 0;
- avec->capacity = 0;
- avec->data = NULL;
- }
- void addrvec_free(addrvec_t *avec)
- {
- if (avec == NULL)
- {
- return;
- }
- avec->next = 0;
- avec->count = 0;
- avec->capacity = 0;
- if (avec->data) {
- free(avec->data);
- avec->data = NULL;
- }
- }
- int addrvec_alloc(addrvec_t *avec)
- {
- addrvec_init(avec);
- return addrvec_grow_default(avec);
- }
- int addrvec_alloc_capacity(addrvec_t* avec, uint32_t capacity)
- {
- addrvec_init(avec);
- return addrvec_grow(avec, capacity);
- }
- int addrvec_grow(addrvec_t *avec, uint32_t grow_amount)
- {
- unsigned int old_capacity = 0;
- struct sockaddr_storage *old_data = NULL;
- assert(avec);
- if (grow_amount == 0)
- {
- return 0;
- }
- // Save off old data and capacity in case there is a realloc failure
- old_capacity = avec->capacity;
- old_data = avec->data;
- avec->capacity += grow_amount;
- avec->data = realloc(avec->data, sizeof(*avec->data) * avec->capacity);
- if (avec->data == NULL)
- {
- avec->capacity = old_capacity;
- avec->data = old_data;
- errno = ENOMEM;
- return 1;
- }
- return 0;
- }
- int addrvec_grow_default(addrvec_t *avec)
- {
- return addrvec_grow(avec, ADDRVEC_DEFAULT_GROW_AMOUNT);
- }
- static int addrvec_grow_if_full(addrvec_t *avec)
- {
- assert(avec);
- if (avec->count == avec->capacity)
- {
- int rc = addrvec_grow_default(avec);
- if (rc != 0)
- {
- return rc;
- }
- }
- return 0;
- }
- int addrvec_contains(const addrvec_t *avec, const struct sockaddr_storage *addr)
- {
- uint32_t i = 0;
- if (!avec || !addr)
- {
- return 0;
- }
- for (i = 0; i < avec->count; i++)
- {
- if (avec->data[i].ss_family != addr->ss_family)
- continue;
- switch (addr->ss_family) {
- case AF_INET:
- if (memcmp(&((struct sockaddr_in*)&avec->data[i])->sin_addr,
- &((struct sockaddr_in*)addr)->sin_addr,
- sizeof(struct in_addr)) == 0)
- return 1;
- break;
- #ifdef AF_INET6
- case AF_INET6:
- if (memcmp(&((struct sockaddr_in6*)&avec->data[i])->sin6_addr,
- &((struct sockaddr_in6*)addr)->sin6_addr,
- sizeof(struct in6_addr)) == 0)
- return 1;
- break;
- #endif
- default:
- break;
- }
- }
- return 0;
- }
- int addrvec_append(addrvec_t *avec, const struct sockaddr_storage *addr)
- {
- int rc = 0;
- assert(avec);
- assert(addr);
- rc = addrvec_grow_if_full(avec);
- if (rc != 0)
- {
- return rc;
- }
- // Copy addrinfo into address list
- memcpy(avec->data + avec->count, addr, sizeof(*addr));
- ++avec->count;
- return 0;
- }
- int addrvec_append_addrinfo(addrvec_t *avec, const struct addrinfo *addrinfo)
- {
- int rc = 0;
- assert(avec);
- assert(addrinfo);
- rc = addrvec_grow_if_full(avec);
- if (rc != 0)
- {
- return rc;
- }
- // Copy addrinfo into address list
- memcpy(avec->data + avec->count, addrinfo->ai_addr, addrinfo->ai_addrlen);
- ++avec->count;
- return 0;
- }
- void addrvec_shuffle(addrvec_t *avec)
- {
- int i = 0;
- for (i = avec->count - 1; i > 0; --i) {
- long int j = random()%(i+1);
- if (i != j) {
- struct sockaddr_storage t = avec->data[i];
- avec->data[i] = avec->data[j];
- avec->data[j] = t;
- }
- }
- }
- int addrvec_hasnext(const addrvec_t *avec)
- {
- return avec->count > 0 && (avec->next < avec->count);
- }
- int addrvec_atend(const addrvec_t *avec)
- {
- return avec->count > 0 && avec->next >= avec->count;
- }
- void addrvec_next(addrvec_t *avec, struct sockaddr_storage *next)
- {
- int index;
- // If we're at the end of the list, then reset index to start
- if (addrvec_atend(avec)) {
- avec->next = 0;
- }
- if (!addrvec_hasnext(avec)) {
- if (next) {
- memset(next, 0, sizeof(*next));
- }
- return;
- }
- index = avec->next++;
- if (next) {
- *next = avec->data[index];
- }
- }
- void addrvec_peek(addrvec_t *avec, struct sockaddr_storage *next)
- {
- int index = avec->next;
- if (avec->count == 0) {
- memset(next, 0, sizeof(*next));
- return;
- }
- if (addrvec_atend(avec)) {
- index = 0;
- }
- *next = avec->data[index];
- }
- int addrvec_eq(const addrvec_t *a1, const addrvec_t *a2)
- {
- uint32_t i = 0;
- if (a1->count != a2->count)
- {
- return 0;
- }
- for (i = 0; i < a1->count; ++i)
- {
- if (!addrvec_contains(a2, &a1->data[i]))
- return 0;
- }
- return 1;
- }
|