Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
blacklist.c
00001 /* 00002 * Copyright (c) 2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #include "nsconfig.h" 00018 #include "string.h" 00019 #include "ns_types.h" 00020 #include "ns_trace.h" 00021 #include "eventOS_scheduler.h" 00022 #include "nsdynmemLIB.h" 00023 #include "randLIB.h" 00024 #include "NWK_INTERFACE/Include/protocol.h" 00025 #include "Service_Libs/blacklist/blacklist.h" 00026 00027 #define TRACE_GROUP "bl" 00028 00029 static blacklist_entry_t *blacklist_entry_find(const uint8_t *eui64); 00030 static void blacklist_entry_add(const uint8_t *eui64); 00031 static int8_t blacklist_entry_free(blacklist_entry_t *blacklist_entry); 00032 static uint16_t blacklist_entries_count(void); 00033 00034 static blacklist_data_t *blacklist_data = NULL; 00035 00036 uint8_t blacklist_init(void) 00037 { 00038 if (blacklist_data) { 00039 return 0; 00040 } 00041 00042 blacklist_data = ns_dyn_mem_alloc(sizeof(blacklist_data_t)); 00043 00044 if (!blacklist_data) { 00045 return 1; 00046 } 00047 00048 ns_list_init(&blacklist_data->blacklist); 00049 00050 blacklist_data->blacklist_purge_ttl = BLACKLIST_DEFAULT_PURGE_TIMER_TIMEOUT; 00051 blacklist_data->blacklist_entry_lifetime = BLACKLIST_DEFAULT_ENTRY_LIFETIME; 00052 blacklist_data->blacklist_timer_max_timeout = BLACKLIST_DEFAULT_TIMER_MAX_TIMEOUT; 00053 blacklist_data->blacklist_timer_timeout = BLACKLIST_DEFAULT_TIMER_TIMEOUT; 00054 blacklist_data->blacklist_entry_max_nbr = BLACKLIST_DEFAULT_ENTRY_MAX_NBR; 00055 blacklist_data->blacklist_purge_nbr = BLACKLIST_DEFAULT_PURGE_NBR; 00056 blacklist_data->blacklist_purge_timer_timeout = BLACKLIST_DEFAULT_PURGE_TIMER_TIMEOUT; 00057 00058 return 0; 00059 } 00060 00061 void blacklist_params_set(uint16_t entry_lifetime, uint16_t timer_max_timeout, uint16_t timer_timeout, uint16_t entry_max_nbr, uint16_t purge_nbr, uint16_t purge_timer_timeout) 00062 { 00063 if (!blacklist_data) { 00064 return; 00065 } 00066 00067 blacklist_data->blacklist_purge_ttl = purge_timer_timeout; 00068 blacklist_data->blacklist_entry_lifetime = entry_lifetime; 00069 blacklist_data->blacklist_timer_max_timeout = timer_max_timeout; 00070 blacklist_data->blacklist_timer_timeout = timer_timeout; 00071 blacklist_data->blacklist_entry_max_nbr = entry_max_nbr; 00072 blacklist_data->blacklist_purge_nbr = purge_nbr; 00073 blacklist_data->blacklist_purge_timer_timeout = purge_timer_timeout; 00074 } 00075 00076 bool blacklist_reject(const uint8_t *ll64_address) 00077 { 00078 if (!blacklist_data) { 00079 return false; 00080 } 00081 00082 blacklist_entry_t *blacklist_entry; 00083 00084 blacklist_entry = blacklist_entry_find(ll64_address + 8); 00085 00086 // If blacklist entry exists 00087 if (blacklist_entry) { 00088 // If address is blacklisted rejects 00089 if (blacklist_entry->ttl > blacklist_data->blacklist_entry_lifetime) { 00090 tr_debug("blacklist reject: %s", trace_array(ll64_address + 8, 8)); 00091 return true; 00092 // Neighbor heard; updates blacklist entry TTL to full lifetime 00093 } else { 00094 blacklist_entry->ttl = blacklist_data->blacklist_entry_lifetime; 00095 return false; 00096 } 00097 } else { 00098 // If blacklist is full rejects 00099 if (blacklist_entries_count() >= blacklist_data->blacklist_entry_max_nbr) { 00100 tr_debug("blacklist full reject"); 00101 return true; 00102 } else { 00103 tr_debug("blacklist not found %s", trace_array(ll64_address + 8, 8)); 00104 return false; 00105 } 00106 } 00107 } 00108 00109 void blacklist_update(const uint8_t *ll64_address, bool success) 00110 { 00111 if (!blacklist_data) { 00112 return; 00113 } 00114 00115 blacklist_entry_t *blacklist_entry; 00116 00117 if (!ll64_address) { 00118 return; 00119 } 00120 00121 // Check that address is LL64 (not LL16) 00122 if (memcmp(ll64_address, ADDR_LINK_LOCAL_PREFIX, 8) != 0) { 00123 return; 00124 } 00125 00126 if (memcmp((ll64_address + 8), ADDR_SHORT_ADR_SUFFIC, 6) == 0) { 00127 return; 00128 } 00129 00130 blacklist_entry = blacklist_entry_find(ll64_address + 8); 00131 00132 // On successful link establishment remove address from blacklist 00133 if (success) { 00134 if (blacklist_entry) { 00135 tr_debug("Blacklist removed"); 00136 blacklist_entry_free(blacklist_entry); 00137 } 00138 // On failure add address to blacklist or update timeout 00139 } else { 00140 if (blacklist_entry) { 00141 blacklist_entry->interval = blacklist_entry->interval * 2; 00142 if (blacklist_entry->interval > blacklist_data->blacklist_timer_max_timeout) { 00143 blacklist_entry->interval = blacklist_data->blacklist_timer_max_timeout; 00144 } 00145 /* TTL is blacklist entry lifetime + from 1.0 to 1.5 * interval */ 00146 blacklist_entry->ttl = blacklist_data->blacklist_entry_lifetime + randLIB_randomise_base(blacklist_entry->interval, 0x8000, 0xC000); 00147 tr_debug("Blacklist updated, ttl=%"PRIu16, blacklist_entry->ttl); 00148 } else { 00149 tr_debug("Blacklist add"); 00150 blacklist_entry_add(ll64_address + 8); 00151 } 00152 } 00153 } 00154 00155 void blacklist_clear(void) 00156 { 00157 if (!blacklist_data) { 00158 return; 00159 } 00160 00161 ns_list_foreach_safe(blacklist_entry_t, blacklist_entry, &blacklist_data->blacklist) { 00162 blacklist_entry_free(blacklist_entry); 00163 } 00164 } 00165 00166 void blacklist_free(void) 00167 { 00168 if (!blacklist_data) { 00169 return; 00170 } 00171 00172 ns_dyn_mem_free(blacklist_data); 00173 blacklist_data = NULL; 00174 } 00175 00176 void blacklist_ttl_update(uint16_t ticks) 00177 { 00178 if (!blacklist_data) { 00179 return; 00180 } 00181 00182 if (blacklist_data->blacklist_purge_ttl > ticks) { 00183 blacklist_data->blacklist_purge_ttl -= ticks; 00184 } else { 00185 /* 0.5 to 1.5 times timeout */ 00186 blacklist_data->blacklist_purge_ttl = randLIB_randomise_base(blacklist_data->blacklist_purge_timer_timeout, 0x4000, 0xC000); 00187 00188 if (blacklist_entries_count() >= blacklist_data->blacklist_entry_max_nbr - blacklist_data->blacklist_purge_nbr) { 00189 uint8_t count = 0; 00190 blacklist_entry_t *blacklist_entry_min_ttl; 00191 00192 tr_debug("Blacklist entries purge"); 00193 00194 while (count++ < blacklist_data->blacklist_purge_nbr) { 00195 blacklist_entry_min_ttl = NULL; 00196 ns_list_foreach(blacklist_entry_t, blacklist_entry, &blacklist_data->blacklist) { 00197 if (!blacklist_entry_min_ttl) { 00198 blacklist_entry_min_ttl = blacklist_entry; 00199 } else if (blacklist_entry->ttl < blacklist_entry_min_ttl->ttl) { 00200 blacklist_entry_min_ttl = blacklist_entry; 00201 } 00202 } 00203 if (blacklist_entry_min_ttl) { 00204 blacklist_entry_free(blacklist_entry_min_ttl); 00205 } 00206 } 00207 } 00208 } 00209 00210 ns_list_foreach_safe(blacklist_entry_t, blacklist_entry, &blacklist_data->blacklist) { 00211 if (blacklist_entry->ttl > ticks) { 00212 blacklist_entry->ttl -= ticks; 00213 } else { 00214 tr_debug("Blacklist remove entry: %s", trace_array(blacklist_entry->eui64, 8)); 00215 blacklist_entry_free(blacklist_entry); 00216 } 00217 } 00218 } 00219 00220 static blacklist_entry_t *blacklist_entry_find(const uint8_t *eui64) 00221 { 00222 if (!eui64) { 00223 return NULL; 00224 } 00225 00226 if (!blacklist_data) { 00227 return NULL; 00228 } 00229 00230 ns_list_foreach(blacklist_entry_t, blacklist_entry, &blacklist_data->blacklist) { 00231 if (memcmp(blacklist_entry->eui64, eui64, 8) == 0) { 00232 return blacklist_entry; 00233 } 00234 } 00235 return NULL; 00236 } 00237 00238 static void blacklist_entry_add(const uint8_t *eui64) 00239 { 00240 blacklist_entry_t *blacklist_entry; 00241 00242 if (!eui64) { 00243 return; 00244 } 00245 00246 if (!blacklist_data) { 00247 return; 00248 } 00249 00250 if (blacklist_entries_count() >= blacklist_data->blacklist_entry_max_nbr) { 00251 return; 00252 } 00253 00254 blacklist_entry = ns_dyn_mem_alloc(sizeof(blacklist_entry_t)); 00255 00256 if (!blacklist_entry) { 00257 return; 00258 } 00259 00260 blacklist_entry->interval = blacklist_data->blacklist_timer_timeout; 00261 00262 /* TTL is blacklist entry lifetime + from 1.0 to 1.5 * interval */ 00263 blacklist_entry->ttl = blacklist_data->blacklist_entry_lifetime + randLIB_randomise_base(blacklist_entry->interval, 0x8000, 0xC000); 00264 00265 memcpy(blacklist_entry->eui64, eui64, 8); 00266 tr_debug("Blacklist add, ttl=%"PRIu16, blacklist_entry->ttl); 00267 ns_list_add_to_start(&blacklist_data->blacklist, blacklist_entry); 00268 } 00269 00270 static int8_t blacklist_entry_free(blacklist_entry_t *blacklist_entry) 00271 { 00272 if (!blacklist_entry) { 00273 return -1; 00274 } 00275 00276 if (!blacklist_data) { 00277 return -2; 00278 } 00279 00280 ns_list_remove(&blacklist_data->blacklist, blacklist_entry); //Remove from the list 00281 ns_dyn_mem_free(blacklist_entry); // Free entry 00282 return 0; 00283 } 00284 00285 static uint16_t blacklist_entries_count(void) 00286 { 00287 uint16_t entry_count = 0; 00288 00289 if (!blacklist_data) { 00290 return 0; 00291 } 00292 00293 entry_count = ns_list_count(&blacklist_data->blacklist); 00294 00295 return entry_count; 00296 }
Generated on Tue Jul 12 2022 14:23:25 by
