grapes / som / TopologyManager / ncast.c @ 661d190d
History | View | Annotate | Download (3.21 KB)
1 |
/*
|
---|---|
2 |
* Copyright (c) 2010 Luca Abeni
|
3 |
*
|
4 |
* This is free software; see lgpl-2.1.txt
|
5 |
*/
|
6 |
|
7 |
#include <sys/time.h> |
8 |
#include <time.h> |
9 |
#include <stdlib.h> |
10 |
#include <stdint.h> |
11 |
#include <stdio.h> |
12 |
#include <stdbool.h> |
13 |
#include <string.h> |
14 |
|
15 |
#include "net_helper.h" |
16 |
#include "topmanager.h" |
17 |
#include "topocache.h" |
18 |
#include "topo_proto.h" |
19 |
#include "proto.h" |
20 |
#include "msg_types.h" |
21 |
|
22 |
#define MAX_PEERS 30 |
23 |
|
24 |
static uint64_t currtime;
|
25 |
static int cache_size = MAX_PEERS; |
26 |
static struct peer_cache *local_cache; |
27 |
static bool bootstrap = true; |
28 |
static int bootstrap_period = 2000000; |
29 |
static int period = 10000000; |
30 |
|
31 |
static uint64_t gettime(void) |
32 |
{ |
33 |
struct timeval tv;
|
34 |
|
35 |
gettimeofday(&tv, NULL);
|
36 |
|
37 |
return tv.tv_usec + tv.tv_sec * 1000000ull; |
38 |
} |
39 |
|
40 |
static int time_to_send(void) |
41 |
{ |
42 |
int p = bootstrap ? bootstrap_period : period;
|
43 |
if (gettime() - currtime > p) {
|
44 |
currtime += p; |
45 |
|
46 |
return 1; |
47 |
} |
48 |
|
49 |
return 0; |
50 |
} |
51 |
|
52 |
/*
|
53 |
* Public Functions!
|
54 |
*/
|
55 |
int topInit(struct nodeID *myID, void *metadata, int metadata_size, const char *config) |
56 |
{ |
57 |
local_cache = cache_init(cache_size, metadata_size); |
58 |
if (local_cache == NULL) { |
59 |
return -1; |
60 |
} |
61 |
topo_proto_init(myID, metadata, metadata_size); |
62 |
currtime = gettime(); |
63 |
bootstrap = true;
|
64 |
|
65 |
return 1; |
66 |
} |
67 |
|
68 |
int topChangeMetadata(struct nodeID *peer, void *metadata, int metadata_size) |
69 |
{ |
70 |
if (topo_proto_metadata_update(peer, metadata, metadata_size) <= 0) { |
71 |
return -1; |
72 |
} |
73 |
|
74 |
return 1; |
75 |
} |
76 |
|
77 |
int topAddNeighbour(struct nodeID *neighbour, void *metadata, int metadata_size) |
78 |
{ |
79 |
if (cache_add(local_cache, neighbour, metadata, metadata_size) < 0) { |
80 |
return -1; |
81 |
} |
82 |
return topo_query_peer(local_cache, neighbour);
|
83 |
} |
84 |
|
85 |
int topParseData(const uint8_t *buff, int len) |
86 |
{ |
87 |
int dummy;
|
88 |
|
89 |
if (len) {
|
90 |
const struct topo_header *h = (const struct topo_header *)buff; |
91 |
struct peer_cache *new, *remote_cache;
|
92 |
|
93 |
if (h->protocol != MSG_TYPE_TOPOLOGY) {
|
94 |
fprintf(stderr, "NCAST: Wrong protocol!\n");
|
95 |
|
96 |
return -1; |
97 |
} |
98 |
|
99 |
bootstrap = false;
|
100 |
|
101 |
if (h->type == NCAST_QUERY) {
|
102 |
topo_reply(buff + sizeof(struct topo_header), len - sizeof(struct topo_header), local_cache); |
103 |
} |
104 |
remote_cache = entries_undump(buff + sizeof(struct topo_header), len - sizeof(struct topo_header)); |
105 |
new = merge_caches(local_cache, remote_cache, cache_size, &dummy); |
106 |
cache_free(remote_cache); |
107 |
if (new != NULL) { |
108 |
cache_free(local_cache); |
109 |
local_cache = new; |
110 |
} |
111 |
} |
112 |
|
113 |
if (time_to_send()) {
|
114 |
cache_update(local_cache); |
115 |
topo_query(local_cache); |
116 |
} |
117 |
|
118 |
return 0; |
119 |
} |
120 |
|
121 |
const struct nodeID **topGetNeighbourhood(int *n) |
122 |
{ |
123 |
static struct nodeID **r; |
124 |
|
125 |
r = realloc(r, cache_size * sizeof(struct nodeID *)); |
126 |
if (r == NULL) { |
127 |
return NULL; |
128 |
} |
129 |
|
130 |
for (*n = 0; nodeid(local_cache, *n) && (*n < cache_size); (*n)++) { |
131 |
r[*n] = nodeid(local_cache, *n); |
132 |
//fprintf(stderr, "Checking table[%d]\n", *n);
|
133 |
} |
134 |
|
135 |
return (const struct nodeID **)r; |
136 |
} |
137 |
|
138 |
const void *topGetMetadata(int *metadata_size) |
139 |
{ |
140 |
return get_metadata(local_cache, metadata_size);
|
141 |
} |
142 |
|
143 |
int topGrowNeighbourhood(int n) |
144 |
{ |
145 |
cache_size += n; |
146 |
|
147 |
return cache_size;
|
148 |
} |
149 |
|
150 |
int topShrinkNeighbourhood(int n) |
151 |
{ |
152 |
if (cache_size < n) {
|
153 |
return -1; |
154 |
} |
155 |
cache_size -= n; |
156 |
|
157 |
return cache_size;
|
158 |
} |
159 |
|
160 |
int topRemoveNeighbour(struct nodeID *neighbour) |
161 |
{ |
162 |
return cache_del(local_cache, neighbour);
|
163 |
} |
164 |
|