Statistics
| Branch: | Revision:

grapes / som / TopologyManager / ncast.c @ ac9b476d

History | View | Annotate | Download (3.17 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 ncast_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
    remote_cache = entries_undump(buff + sizeof(struct topo_header), len - sizeof(struct topo_header));
102
    if (h->type == NCAST_QUERY) {
103
      ncast_reply(remote_cache, local_cache);
104
    }
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_tout(local_cache);
115
    ncast_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