Statistics
| Branch: | Revision:

grapes / som / TopologyManager / ncast.c @ 483ff9b6

History | View | Annotate | Download (3.23 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 10
23
#define BOOTSTRAP_CYCLES 5
24

    
25
static uint64_t currtime;
26
static int cache_size = MAX_PEERS;
27
static struct peer_cache *local_cache;
28
static bool bootstrap = true;
29
static int bootstrap_period = 2000000;
30
static int period = 10000000;
31
static int counter;
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
  local_cache = cache_init(cache_size, metadata_size);
60
  if (local_cache == NULL) {
61
    return -1;
62
  }
63
  topo_proto_init(myID, metadata, metadata_size);
64
  currtime = gettime();
65
  bootstrap = true;
66

    
67
  return 1;
68
}
69

    
70
int topChangeMetadata(void *metadata, int metadata_size)
71
{
72
  if (topo_proto_metadata_update(metadata, metadata_size) <= 0) {
73
    return -1;
74
  }
75

    
76
  return 1;
77
}
78

    
79
int topAddNeighbour(struct nodeID *neighbour, void *metadata, int metadata_size)
80
{
81
  if (cache_add(local_cache, neighbour, metadata, metadata_size) < 0) {
82
    return -1;
83
  }
84
  return ncast_query_peer(local_cache, neighbour);
85
}
86

    
87
int topParseData(const uint8_t *buff, int len)
88
{
89
  int dummy;
90

    
91
  if (len) {
92
    const struct topo_header *h = (const struct topo_header *)buff;
93
    struct peer_cache *new, *remote_cache;
94

    
95
    if (h->protocol != MSG_TYPE_TOPOLOGY) {
96
      fprintf(stderr, "NCAST: Wrong protocol!\n");
97

    
98
      return -1;
99
    }
100

    
101
    counter++;
102
    if (counter == BOOTSTRAP_CYCLES) bootstrap = false;
103

    
104
    remote_cache = entries_undump(buff + sizeof(struct topo_header), len - sizeof(struct topo_header));
105
    if (h->type == NCAST_QUERY) {
106
      ncast_reply(remote_cache, local_cache);
107
    }
108
    new = merge_caches(local_cache, remote_cache, cache_size, &dummy);
109
    cache_free(remote_cache);
110
    if (new != NULL) {
111
      cache_free(local_cache);
112
      local_cache = new;
113
    }
114
  }
115

    
116
  if (time_to_send()) {
117
    cache_update_tout(local_cache);
118
    ncast_query(local_cache);
119
  }
120

    
121
  return 0;
122
}
123

    
124
const struct nodeID **topGetNeighbourhood(int *n)
125
{
126
  static struct nodeID **r;
127

    
128
  r = realloc(r, cache_size * sizeof(struct nodeID *));
129
  if (r == NULL) {
130
    return NULL;
131
  }
132

    
133
  for (*n = 0; nodeid(local_cache, *n) && (*n < cache_size); (*n)++) {
134
    r[*n] = nodeid(local_cache, *n);
135
    //fprintf(stderr, "Checking table[%d]\n", *n);
136
  }
137

    
138
  return (const struct nodeID **)r;
139
}
140

    
141
const void *topGetMetadata(int *metadata_size)
142
{
143
  return get_metadata(local_cache, metadata_size);
144
}
145

    
146
int topGrowNeighbourhood(int n)
147
{
148
  cache_size += n;
149

    
150
  return cache_size;
151
}
152

    
153
int topShrinkNeighbourhood(int n)
154
{
155
  if (cache_size < n) {
156
    return -1;
157
  }
158
  cache_size -= n;
159

    
160
  return cache_size;
161
}
162

    
163
int topRemoveNeighbour(struct nodeID *neighbour)
164
{
165
  return cache_del(local_cache, neighbour);
166
}
167