Statistics
| Branch: | Revision:

grapes / som / TopologyManager / ncast.c @ 18d83f26

History | View | Annotate | Download (3.58 KB)

1 8ab58ec7 Luca Abeni
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *
4
 *  This is free software; see lgpl-2.1.txt
5
 */
6
7 480921a6 Luca Abeni
#include <sys/time.h>
8
#include <time.h>
9
#include <stdlib.h>
10
#include <stdint.h>
11
#include <stdio.h>
12 badadecf CsabaKiraly
#include <stdbool.h>
13 480921a6 Luca Abeni
#include <string.h>
14
15 155319cd Luca Abeni
#include "net_helper.h"
16 480921a6 Luca Abeni
#include "topmanager.h"
17 faa3a9c7 Luca Abeni
#include "topocache.h"
18
#include "topo_proto.h"
19 480921a6 Luca Abeni
#include "proto.h"
20 a1333f46 Luca Abeni
#include "config.h"
21 026a7e5d Luca Abeni
#include "msg_types.h"
22 480921a6 Luca Abeni
23 a1333f46 Luca Abeni
#define DEFAULT_CACHE_SIZE 10
24 18d83f26 Luca Abeni
#define DEFAULT_MAX_TIMESTAMP 5
25 480921a6 Luca Abeni
26
static uint64_t currtime;
27 a1333f46 Luca Abeni
static int cache_size;
28 11485577 Luca Abeni
static struct peer_cache *local_cache;
29 badadecf CsabaKiraly
static bool bootstrap = true;
30 d85b5003 CsabaKiraly
static int bootstrap_period = 2000000;
31 480921a6 Luca Abeni
static int period = 10000000;
32
33
static uint64_t gettime(void)
34
{
35
  struct timeval tv;
36
37
  gettimeofday(&tv, NULL);
38
39
  return tv.tv_usec + tv.tv_sec * 1000000ull;
40
}
41
42
static int time_to_send(void)
43
{
44 badadecf CsabaKiraly
  int p = bootstrap ? bootstrap_period : period;
45
  if (gettime() - currtime > p) {
46
    currtime += p;
47 480921a6 Luca Abeni
48
    return 1;
49
  }
50
51
  return 0;
52
}
53
54
/*
55
 * Public Functions!
56
 */
57 04df3b0f Luca
int topInit(struct nodeID *myID, void *metadata, int metadata_size, const char *config)
58 480921a6 Luca Abeni
{
59 a1333f46 Luca Abeni
  struct tag *cfg_tags;
60 18d83f26 Luca Abeni
  int res, max_timestamp;
61 a1333f46 Luca Abeni
62
  cfg_tags = config_parse(config);
63
  res = config_value_int(cfg_tags, "cache_size", &cache_size);
64
  if (!res) {
65
    cache_size = DEFAULT_CACHE_SIZE;
66
  }
67 18d83f26 Luca Abeni
  res = config_value_int(cfg_tags, "max_timestamp", &max_timestamp);
68
  if (!res) {
69
    max_timestamp = DEFAULT_MAX_TIMESTAMP;
70
  }
71 a1333f46 Luca Abeni
  free(cfg_tags);
72
  
73 18d83f26 Luca Abeni
  local_cache = cache_init(cache_size, metadata_size, max_timestamp);
74 480921a6 Luca Abeni
  if (local_cache == NULL) {
75
    return -1;
76
  }
77 01873987 Luca Abeni
  topo_proto_init(myID, metadata, metadata_size);
78 480921a6 Luca Abeni
  currtime = gettime();
79 badadecf CsabaKiraly
  bootstrap = true;
80 480921a6 Luca Abeni
81
  return 1;
82
}
83
84 90cea048 Luca
int topChangeMetadata(struct nodeID *peer, void *metadata, int metadata_size)
85
{
86 01873987 Luca Abeni
  if (topo_proto_metadata_update(peer, metadata, metadata_size) <= 0) {
87 90cea048 Luca
    return -1;
88
  }
89
90
  return 1;
91
}
92
93 005954ae Luca Abeni
int topAddNeighbour(struct nodeID *neighbour, void *metadata, int metadata_size)
94 480921a6 Luca Abeni
{
95 886456d7 Luca
  if (cache_add(local_cache, neighbour, metadata, metadata_size) < 0) {
96 36b460c1 Csaba Kiraly
    return -1;
97
  }
98 df98cd3a Luca Abeni
  return ncast_query_peer(local_cache, neighbour);
99 480921a6 Luca Abeni
}
100
101 651ed37d Luca
int topParseData(const uint8_t *buff, int len)
102 480921a6 Luca Abeni
{
103 661d190d Luca Abeni
  int dummy;
104
105 480921a6 Luca Abeni
  if (len) {
106 01873987 Luca Abeni
    const struct topo_header *h = (const struct topo_header *)buff;
107 11485577 Luca Abeni
    struct peer_cache *new, *remote_cache;
108 480921a6 Luca Abeni
109 026a7e5d Luca Abeni
    if (h->protocol != MSG_TYPE_TOPOLOGY) {
110 480921a6 Luca Abeni
      fprintf(stderr, "NCAST: Wrong protocol!\n");
111
112
      return -1;
113
    }
114
115 badadecf CsabaKiraly
    bootstrap = false;
116
117 418dafe6 Luca
    remote_cache = entries_undump(buff + sizeof(struct topo_header), len - sizeof(struct topo_header));
118 480921a6 Luca Abeni
    if (h->type == NCAST_QUERY) {
119 df98cd3a Luca Abeni
      ncast_reply(remote_cache, local_cache);
120 480921a6 Luca Abeni
    }
121 661d190d Luca Abeni
    new = merge_caches(local_cache, remote_cache, cache_size, &dummy);
122 6ee18244 Luca
    cache_free(remote_cache);
123 480921a6 Luca Abeni
    if (new != NULL) {
124 6ee18244 Luca
      cache_free(local_cache);
125 480921a6 Luca Abeni
      local_cache = new;
126
    }
127
  }
128
129
  if (time_to_send()) {
130 ac9b476d Luca Abeni
    cache_update_tout(local_cache);
131 df98cd3a Luca Abeni
    ncast_query(local_cache);
132 480921a6 Luca Abeni
  }
133
134
  return 0;
135
}
136
137 651ed37d Luca
const struct nodeID **topGetNeighbourhood(int *n)
138 480921a6 Luca Abeni
{
139 3c7f8a0c Luca Abeni
  static struct nodeID **r;
140 480921a6 Luca Abeni
141 3c7f8a0c Luca Abeni
  r = realloc(r, cache_size * sizeof(struct nodeID *));
142
  if (r == NULL) {
143
    return NULL;
144
  }
145
146
  for (*n = 0; nodeid(local_cache, *n) && (*n < cache_size); (*n)++) {
147 480921a6 Luca Abeni
    r[*n] = nodeid(local_cache, *n);
148
    //fprintf(stderr, "Checking table[%d]\n", *n);
149
  }
150 3c7f8a0c Luca Abeni
151 651ed37d Luca
  return (const struct nodeID **)r;
152 480921a6 Luca Abeni
}
153
154 bbbdd9d1 Luca Abeni
const void *topGetMetadata(int *metadata_size)
155 005954ae Luca Abeni
{
156 fe701696 Luca
  return get_metadata(local_cache, metadata_size);
157 005954ae Luca Abeni
}
158
159 480921a6 Luca Abeni
int topGrowNeighbourhood(int n)
160
{
161
  cache_size += n;
162
163
  return cache_size;
164
}
165
166
int topShrinkNeighbourhood(int n)
167
{
168
  if (cache_size < n) {
169
    return -1;
170
  }
171
  cache_size -= n;
172
173
  return cache_size;
174
}
175
176 651ed37d Luca
int topRemoveNeighbour(struct nodeID *neighbour)
177 480921a6 Luca Abeni
{
178
  return cache_del(local_cache, neighbour);
179
}