Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (3.58 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 "config.h"
21
#include "msg_types.h"
22

    
23
#define DEFAULT_CACHE_SIZE 10
24
#define DEFAULT_MAX_TIMESTAMP 5
25

    
26
static uint64_t currtime;
27
static int cache_size;
28
static struct peer_cache *local_cache;
29
static bool bootstrap = true;
30
static int bootstrap_period = 2000000;
31
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
  int p = bootstrap ? bootstrap_period : period;
45
  if (gettime() - currtime > p) {
46
    currtime += p;
47

    
48
    return 1;
49
  }
50

    
51
  return 0;
52
}
53

    
54
/*
55
 * Public Functions!
56
 */
57
int topInit(struct nodeID *myID, void *metadata, int metadata_size, const char *config)
58
{
59
  struct tag *cfg_tags;
60
  int res, max_timestamp;
61

    
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
  res = config_value_int(cfg_tags, "max_timestamp", &max_timestamp);
68
  if (!res) {
69
    max_timestamp = DEFAULT_MAX_TIMESTAMP;
70
  }
71
  free(cfg_tags);
72
  
73
  local_cache = cache_init(cache_size, metadata_size, max_timestamp);
74
  if (local_cache == NULL) {
75
    return -1;
76
  }
77
  topo_proto_init(myID, metadata, metadata_size);
78
  currtime = gettime();
79
  bootstrap = true;
80

    
81
  return 1;
82
}
83

    
84
int topChangeMetadata(struct nodeID *peer, void *metadata, int metadata_size)
85
{
86
  if (topo_proto_metadata_update(peer, metadata, metadata_size) <= 0) {
87
    return -1;
88
  }
89

    
90
  return 1;
91
}
92

    
93
int topAddNeighbour(struct nodeID *neighbour, void *metadata, int metadata_size)
94
{
95
  if (cache_add(local_cache, neighbour, metadata, metadata_size) < 0) {
96
    return -1;
97
  }
98
  return ncast_query_peer(local_cache, neighbour);
99
}
100

    
101
int topParseData(const uint8_t *buff, int len)
102
{
103
  int dummy;
104

    
105
  if (len) {
106
    const struct topo_header *h = (const struct topo_header *)buff;
107
    struct peer_cache *new, *remote_cache;
108

    
109
    if (h->protocol != MSG_TYPE_TOPOLOGY) {
110
      fprintf(stderr, "NCAST: Wrong protocol!\n");
111

    
112
      return -1;
113
    }
114

    
115
    bootstrap = false;
116

    
117
    remote_cache = entries_undump(buff + sizeof(struct topo_header), len - sizeof(struct topo_header));
118
    if (h->type == NCAST_QUERY) {
119
      ncast_reply(remote_cache, local_cache);
120
    }
121
    new = merge_caches(local_cache, remote_cache, cache_size, &dummy);
122
    cache_free(remote_cache);
123
    if (new != NULL) {
124
      cache_free(local_cache);
125
      local_cache = new;
126
    }
127
  }
128

    
129
  if (time_to_send()) {
130
    cache_update_tout(local_cache);
131
    ncast_query(local_cache);
132
  }
133

    
134
  return 0;
135
}
136

    
137
const struct nodeID **topGetNeighbourhood(int *n)
138
{
139
  static struct nodeID **r;
140

    
141
  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
    r[*n] = nodeid(local_cache, *n);
148
    //fprintf(stderr, "Checking table[%d]\n", *n);
149
  }
150

    
151
  return (const struct nodeID **)r;
152
}
153

    
154
const void *topGetMetadata(int *metadata_size)
155
{
156
  return get_metadata(local_cache, metadata_size);
157
}
158

    
159
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
int topRemoveNeighbour(struct nodeID *neighbour)
177
{
178
  return cache_del(local_cache, neighbour);
179
}
180