Parent Directory
|
Revision Log
|
Revision Graph
It almost works, but it hangs on get_ext_maps()
1 /* This file is part of Netsukuku 2 * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org> 3 * 4 * This source code is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as published 6 * by the Free Software Foundation; either version 2 of the License, 7 * or (at your option) any later version. 8 * 9 * This source code is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * Please refer to the GNU Public License for more details. 13 * 14 * You should have received a copy of the GNU Public License along with 15 * this source code; if not, write to: 16 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 * 18 * -- 19 * bmap.c: 20 * Border node map code. 21 */ 22 23 #include "includes.h" 24 25 #include "common.h" 26 #include "inet.h" 27 #include "endianness.h" 28 #include "map.h" 29 #include "gmap.h" 30 #include "bmap.h" 31 32 void bmap_levels_init(u_char levels, map_bnode ***bmap, u_int **bmap_nodes) 33 { 34 *bmap=xmalloc(sizeof(map_bnode *) * levels); 35 *bmap_nodes=(u_int *)xmalloc(sizeof(u_int) * levels); 36 37 setzero(*bmap, sizeof(map_bnode *) * levels); 38 bmap_counter_reset(levels, *bmap_nodes); 39 } 40 41 void bmap_levels_free(map_bnode **bmap, u_int *bmap_nodes) 42 { 43 xfree(bmap); 44 xfree(bmap_nodes); 45 } 46 47 void bmap_counter_init(u_char levels, u_int **bnodes_closed, u_int **bnodes_opened) 48 { 49 *bnodes_closed=(u_int *)xmalloc(sizeof(u_int) * levels); 50 *bnodes_opened=(u_int *)xmalloc(sizeof(u_int) * levels); 51 52 bmap_counter_reset(levels, *bnodes_closed); 53 bmap_counter_reset(levels, *bnodes_opened); 54 } 55 56 void bmap_counter_free(u_int *bnodes_closed, u_int *bnodes_opened) 57 { 58 xfree(bnodes_closed); 59 xfree(bnodes_opened); 60 } 61 62 void bmap_counter_reset(u_char levels, u_int *counter) 63 { 64 setzero(counter, sizeof(u_int) * levels); 65 } 66 67 /* 68 * map_add_bnode: It adds a new bnode in the `bmap' and then returns its position 69 * in the bmap. It also increments the `*bmap_nodes' counter. The bnode_ptr is set 70 * to `bnode' and the links to `links'. 71 * Note that the `bmap' argument must be an adress of a pointer. 72 */ 73 int map_add_bnode(map_bnode **bmap, u_int *bmap_nodes, u_int bnode, u_int links) 74 { 75 map_bnode *bnode_map; 76 u_int bm; 77 78 bm=*bmap_nodes; 79 (*bmap_nodes)++; 80 if(!bm) 81 *bmap=xmalloc(sizeof(map_bnode)); 82 else 83 *bmap=xrealloc(*bmap, sizeof(map_bnode) * *bmap_nodes); 84 85 bnode_map=*bmap; 86 setzero(bnode_map, sizeof(map_bnode)); 87 bnode_map[bm].bnode_ptr=bnode; 88 bnode_map[bm].links=links; 89 return bm; 90 } 91 92 /* 93 * map_bnode_del: It deletes the `bnode' in the `bmap' which has `bmap_nodes'. 94 * It returns the newly rescaled `bmap'. 95 * It returns 0 if the `bmap' doesn't exist anymore.*/ 96 map_bnode *map_bnode_del(map_bnode *bmap, u_int *bmap_nodes, map_bnode *bnode) 97 { 98 map_node_del((map_node *)bnode); 99 100 if( ((char *)bnode-(char *)bmap)/sizeof(map_bnode) != (*bmap_nodes)-1 ) 101 memcpy(bnode, &bmap[*bmap_nodes-1], sizeof(map_bnode)); 102 103 (*bmap_nodes)--; 104 if(*bmap_nodes) 105 return xrealloc(bmap, (*bmap_nodes) * sizeof(map_bnode)); 106 else { 107 *bmap_nodes=0; 108 xfree(bmap); 109 return 0; 110 } 111 } 112 113 /* 114 * bmap_del_rnode_by_level: it is pretty specific, it deletes all the rnodes 115 * of `bnode' which point to a gnode located in a level not equal to `level'. 116 * The number of rnode deleted is returned. 117 * `total_levels' must be equal to the maximum levels 118 * available (use FAMILY_LVLS). 119 */ 120 int bmap_del_rnode_by_level(map_bnode *bnode, int level, map_gnode **ext_map, 121 int total_levels) 122 { 123 map_gnode *gn; 124 int i, ret=0, lvl; 125 126 127 for(i=0; i < bnode->links; i++) { 128 gn=(map_gnode *)bnode->r_node[i].r_node; 129 lvl=extmap_find_level(ext_map, gn, total_levels); 130 131 if(lvl != level) { 132 rnode_del(bnode, i); 133 ret++; 134 } 135 } 136 137 return ret; 138 } 139 140 /* 141 * map_find_bnode: Find the given `node' (in the pos_from_node() format) in the 142 * given map_bnode `bmap'. 143 */ 144 int map_find_bnode(map_bnode *bmap, int bmap_nodes, int node) 145 { 146 int e; 147 148 for(e=0; e<bmap_nodes; e++) 149 if(bmap[e].bnode_ptr == node) 150 return e; 151 152 return -1; 153 } 154 155 /* 156 * map_find_bnode_rnode: Find the first bnode in the `bmap' which has a rnode 157 * which points to `n'. If it is found the pos of the bnode in the `bmap' is 158 * returned, otherwise -1 is the return value. 159 */ 160 int map_find_bnode_rnode(map_bnode *bmap, int bmap_nodes, void *n) 161 { 162 int e; 163 164 for(e=0; e<bmap_nodes; e++) 165 if(rnode_find((map_node *)&bmap[e], (map_node *)n) != -1) 166 return e; 167 168 return -1; 169 } 170 171 /* 172 * map_count_bnode_rnode: counts how many bnode which have a rnode which 173 * points to `n' there are in `bmap'. 174 */ 175 int map_count_bnode_rnode(map_bnode *bmap, int bmap_nodes, void *n) 176 { 177 int e, i; 178 179 for(i=0, e=0; i<bmap_nodes; i++) 180 if(rnode_find((map_node *)&bmap[i], (map_node *)n) != -1) 181 e++; 182 183 return e; 184 } 185 186 /* 187 * bmaps_count_bnode_rnode: applies map_count_bnode_rnode() to each level of 188 * `bmap' and returns the sum of the results. 189 * `levels' are the total levels of `bmap'. 190 */ 191 int bmaps_count_bnode_rnode(map_bnode **bmap, int *bmap_nodes, int levels, void *n) 192 { 193 int i, e; 194 195 for(i=0, e=0; i<levels; i++) 196 e+=map_count_bnode_rnode(bmap[i], bmap_nodes[i], n); 197 198 return e; 199 } 200 201 /* 202 * map_del_bnode_rnode: deletes all the rnodes of the bnode, present in `bmap', 203 * which points to `n' and deletes the bnodes remained empty. 204 * `bmap' is the address of the pointer to the bmap. 205 * It returns the number of rnodes deleted. 206 */ 207 int map_del_bnode_rnode(map_bnode **bmap, int *bmap_nodes, void *n) 208 { 209 map_bnode *bm; 210 int e, p, ret=0; 211 212 bm=*bmap; 213 for(e=0; e < *bmap_nodes; e++) { 214 if((p=rnode_find((map_node *)&bm[e], (map_node *)n)) != -1) { 215 rnode_del(&bm[e], p); 216 217 if(!bm[e].links) { 218 *bmap=map_bnode_del(*bmap,(u_int*)bmap_nodes, &bm[e]); 219 bm=*bmap; 220 } 221 ret++; 222 } 223 } 224 225 return ret; 226 } 227 228 /* 229 * bmaps_del_bnode_rnode: applies map_del_bnode_rnode() to each level of 230 * `bmap'. 231 * `levels' are the total levels of `bmap'. 232 * It returns the total number of rnodes deleted 233 */ 234 int bmaps_del_bnode_rnode(map_bnode **bmap, int *bmap_nodes, int levels, void *n) 235 { 236 int i, e; 237 238 for(i=0, e=0; i<levels; i++) 239 e+=map_del_bnode_rnode(&bmap[i], &bmap_nodes[i], n); 240 241 return e; 242 } 243 244 /* 245 * map_set_bnode_flag: sets the `flags' to all the `bmap_nodes'# present in 246 * `bmap'. 247 */ 248 void map_set_bnode_flag(map_bnode *bmap, int bmap_nodes, int flags) 249 { 250 int e; 251 for(e=0; e<bmap_nodes; e++) 252 bmap[e].flags|=flags; 253 } 254 255 /* 256 * bmaps_set_bnode_flag: sets the `flags' to all the bnodes present in the 257 * `levels'# `bmap'. 258 */ 259 void bmaps_set_bnode_flag(map_bnode **bmap, int *bmap_nodes, int levels, int flags) 260 { 261 int i; 262 263 for(i=0; i<levels; i++) 264 map_set_bnode_flag(bmap[i], bmap_nodes[i], flags); 265 } 266 267 /* 268 * pack_all_bmaps: It creates the block of all the `bmaps' which have 269 * `bmap_nodes' nodes. `ext_map' and `quadg' are the structs referring 270 * to the external map. In `pack_sz' is stored the size of the block. 271 * The address pointing to the block is returned otherwise 0 is given. 272 * The package will be in network order. 273 */ 274 char * 275 pack_all_bmaps(map_bnode **bmaps, u_int *bmap_nodes, map_gnode **ext_map, 276 quadro_group quadg, size_t *pack_sz) 277 { 278 struct bnode_maps_hdr bmaps_hdr; 279 size_t sz, tmp_sz[BMAP_LEVELS(quadg.levels)]; 280 char *pack[BMAP_LEVELS(quadg.levels)], *final_pack, *buf; 281 u_char level; 282 283 *pack_sz=0; 284 285 for(level=0; level < BMAP_LEVELS(quadg.levels); level++) { 286 pack[level]=pack_map((map_node *)bmaps[level], (int *)ext_map[_EL(level+1)], 287 bmap_nodes[level], 0, &sz); 288 tmp_sz[level]=sz; 289 (*pack_sz)+=sz; 290 } 291 292 bmaps_hdr.levels=BMAP_LEVELS(quadg.levels); 293 bmaps_hdr.bmaps_block_sz=*pack_sz; 294 (*pack_sz)+=sizeof(struct bnode_maps_hdr); 295 296 final_pack=xmalloc((*pack_sz)); 297 memcpy(final_pack, &bmaps_hdr, sizeof(struct bnode_maps_hdr)); 298 ints_host_to_network(final_pack, bnode_maps_hdr_iinfo); 299 300 buf=final_pack+sizeof(struct bnode_maps_hdr); 301 for(level=0; level < BMAP_LEVELS(quadg.levels); level++) { 302 memcpy(buf, pack[level], tmp_sz[level]); 303 buf+=tmp_sz[level]; 304 xfree(pack[level]); 305 } 306 307 return final_pack; 308 } 309 310 /* 311 * unpack_all_bmaps: Given a block `pack' of size `pack_sz' containing `levels' 312 * it unpacks each bnode map it finds in it. 313 * `ext_map' is the external map used by the new bmaps. 314 * In `bmap_nodes' unpack_all_bmaps stores the address of the newly xmallocated 315 * array of u_int. Each bmap_nodes[x] contains the number of nodes of the bmap 316 * of level x. 317 * `maxbnodes' is the maximum number of nodes each bmap can contain, 318 * while `maxbnode_rnodeblock' is the maximum number of rnodes each node can 319 * contain. 320 * On error 0 is returned. 321 * Note: `pack' will be modified during the unpacking. 322 */ 323 map_bnode ** 324 unpack_all_bmaps(char *pack, u_char max_levels, map_gnode **ext_map, 325 u_int **bmap_nodes, int maxbnodes, int maxbnode_rnodeblock) 326 { 327 struct bnode_maps_hdr *bmaps_hdr; 328 struct bnode_map_hdr *bmap_hdr; 329 map_bnode **bmap, *unpacked_bmap; 330 size_t bblock_sz, pack_sz; 331 int i,e=0; 332 char *bblock, *buf; 333 u_char levels; 334 335 bmaps_hdr=(struct bnode_maps_hdr *)pack; 336 ints_network_to_host(bmaps_hdr, bnode_maps_hdr_iinfo); 337 338 levels=bmaps_hdr->levels; 339 pack_sz=bmaps_hdr->bmaps_block_sz; 340 341 if(levels > max_levels || pack_sz < sizeof(struct bnode_maps_hdr)) 342 return 0; 343 344 bmap_levels_init(levels, &bmap, bmap_nodes); 345 346 buf=pack+sizeof(struct bnode_maps_hdr); 347 for(i=0; i<levels; i++) { 348 bmap_hdr=(struct bnode_map_hdr *)buf; 349 if(!bmap_hdr->bnode_map_sz) { 350 buf+=sizeof(struct bnode_map_hdr); 351 continue; 352 } 353 354 /*Extracting the map...*/ 355 bblock=(char *)bmap_hdr; 356 unpacked_bmap=unpack_map(bblock, (int *)ext_map[_EL(i+1)], 0, 357 maxbnodes, maxbnode_rnodeblock); 358 if(!unpacked_bmap) { 359 error("Cannot unpack the bnode_map at level %d ! Skipping...", i); 360 e++; 361 continue; 362 } 363 364 (*bmap_nodes)[i]=bmap_hdr->bnode_map_sz/MAP_BNODE_PACK_SZ; 365 bblock_sz=INT_MAP_BLOCK_SZ(bmap_hdr->bnode_map_sz, bmap_hdr->rblock_sz); 366 367 bmap[i]=unpacked_bmap; 368 369 buf+=bblock_sz; 370 } 371 372 if(e == levels) 373 /* Not a single map was restored */ 374 return 0; 375 376 return bmap; 377 } 378 379 /* * * save/load bnode_map * * */ 380 381 /* 382 * save_bmap: It saves the bnode maps `bmaps' in `file'. The each `bmaps[x]' has 383 * `bmap_nodes[x]' nodes. `ext_map' is the pointer to the external map the bmap is 384 * referring to. 385 */ 386 int save_bmap(map_bnode **bmaps, u_int *bmap_nodes, map_gnode **ext_map, 387 quadro_group quadg, char *file) 388 { 389 FILE *fd; 390 char *pack; 391 size_t pack_sz; 392 393 394 pack=pack_all_bmaps(bmaps, bmap_nodes, ext_map, quadg, &pack_sz); 395 if(!pack_sz || !pack) 396 return 0; 397 398 if((fd=fopen(file, "w"))==NULL) { 399 error("Cannot save the bnode_map in %s: %s", file, strerror(errno)); 400 return -1; 401 } 402 fwrite(pack, pack_sz, 1, fd); 403 404 xfree(pack); 405 fclose(fd); 406 return 0; 407 } 408 409 /* 410 * load_bmap: It loads all the bnode maps from `file' and returns the address 411 * of the array of pointer to the loaded bmaps. `ext_map' is the external maps 412 * the bmap shall refer to. In `bmap_nodes' the address of the u_int array, used 413 * to count the nodes in each bmaps, is stored. On error 0 is returned. 414 */ 415 map_bnode **load_bmap(char *file, map_gnode **ext_map, u_char max_levels, u_int **bmap_nodes) 416 { 417 map_bnode **bmap=0; 418 FILE *fd; 419 struct bnode_maps_hdr bmaps_hdr; 420 size_t pack_sz; 421 u_char levels; 422 char *pack=0; 423 424 if((fd=fopen(file, "r"))==NULL) { 425 error("Cannot load the bmap from %s: %s", file, strerror(errno)); 426 return 0; 427 } 428 429 if(!fread(&bmaps_hdr, sizeof(struct bnode_maps_hdr), 1, fd)) 430 goto finish; 431 432 ints_network_to_host(&bmaps_hdr, bnode_maps_hdr_iinfo); 433 levels=bmaps_hdr.levels; 434 pack_sz=bmaps_hdr.bmaps_block_sz; 435 if(levels > max_levels || pack_sz < sizeof(struct bnode_maps_hdr)) 436 goto finish; 437 438 /* Extracting the map... */ 439 rewind(fd); 440 pack=xmalloc(pack_sz); 441 if(!fread(pack, pack_sz, 1, fd)) 442 goto finish; 443 444 bmap=unpack_all_bmaps(pack, max_levels, ext_map, bmap_nodes, 445 MAXGROUPNODE, MAXBNODE_RNODEBLOCK); 446 447 finish: 448 fclose(fd); 449 if(pack) 450 xfree(pack); 451 if(!bmap) 452 error("Malformed bmap file. Cannot load the bnode maps."); 453 return bmap; 454 }
| alpt (at) freaknet (dot) org | ViewVC Help |
| Powered by ViewVC 1.1-dev |