"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 }