Revision df98cd3a

View differences:

include/msg_types.h
4 4
#define MSG_TYPE_TOPOLOGY   0x10
5 5
#define MSG_TYPE_CHUNK      0x11
6 6
#define MSG_TYPE_SIGNALLING 0x12
7
#define MSG_TYPE_TMAN       0x13
7 8

  
8 9
#endif	/* MSG_TYPES_H */
include/tman.h
1
#ifndef TMAN_H
2
#define TMAN_H
3

  
4
/** @file tman.h
5
 *
6
 * @brief Tman interface.
7
 *
8
 * This is the Tman interface. Tman builds a given topology according to a user provided ranking
9
 * algorithm, by means of epidemic-style message exchanges with neighbor peers.
10
 *
11
 */
12

  
13
/**
14
  @brief Compare neighbors features.
15

  
16
  The functions implementing this prototype are used to compare neighbors features against a given
17
  target neighbor, in order to obtain a rank, to be used to build a given topology.
18

  
19
  @param target pointer to data that describe the target against which the ranking has to be made.
20
  @param p1 pointer to data that describe the first neighbor.
21
  @param p2 pointer to data that describe the second neighbor.
22
  @return 1 if p1 is to be ranked first; 2 if p2 is to be ranked first; 0 if there is a tie.
23
*/
24
typedef int (*tmanRankingFunction)(const void *target, const void *p1, const void *p2);
25

  
26
/*
27
  @brief Get the peer's neighbourhood.
28

  
29
  This function returns the current neighbourhood (i.e., the set of
30
  known peers) of a peer, and its size. Note that the current neighbourhood
31
  size can be different from the requested one, because of how the overlay
32
  management protocols work. 
33

  
34
  @param n pointer to an integer where the neighbourhood size is returned.
35
           Is set to -1 in case of error, or 0 if the neighbourhood is empty.
36
  @return a pointer to an array of nodeID describing the neighbourhood. NULL
37
          in case of error, or if the neighbourhood is empty.
38
*/
39
//const struct nodeID **tmanGetNeighbourhood(int *n);
40

  
41
/*
42
  @brief Remove a peer from the neighbourhood.
43

  
44
  This function can be used to remove a specified neighbour from the
45
  neighbourhood. Note that the requested neighbourhood size is not
46
  modified, so the peer will be soon replaced by a different one.
47
  @param neighbour the id of the peer to be removed from the neighbourhood.
48
  @return 0 in case of success; -1 in case of error.
49
*/
50
//int tmanRemoveNeighbour(struct nodeID *neighbour);
51

  
52
/**
53
  @brief Initialise Tman.
54

  
55
  This function initializes tman protocol with all the mandatory parameters.
56

  
57
  @param myID the ID of this peer.
58
  @param metadata Pointer to data associated with the local peer.
59
  @param metadata_size Size (number of bytes) of the metadata associated with the local peer.
60
  @param rfun Ranking function to be used to order the peers in tman cache.
61
  @param gossip_peers Number of peers, among those in the cache, to be gossiped in a messaged exchange.
62
  @return 0 in case of success; -1 in case of error.
63
*/
64
int tmanInit(struct nodeID *myID, void *metadata, int metadata_size, tmanRankingFunction rfun, int gossip_peers); 
65
//, int max_peers, int max_idle, int periodicity
66

  
67
/*
68
  @brief Start Tman.
69

  
70
  This function starts Tman by feeding it with fresh peers from some known source (usually a
71
  peer sampling service, giving a random sample of the network).
72

  
73
  @param peers Array of nodeID pointers to be added in tman cache.
74
  @param size Number of elements in peers.
75
  @param metadata Pointer to the array of metadata belonging to the peers to be added.
76
  @param metadata_size Number of bytes of each metadata.
77
  @param rfun Ranking function to be used to order the peers in tman cache.
78
  @param best_peers
79
  @param gossip_peers
80
  @return 0 in case of success; -1 in case of error.
81
*/
82
//int tmanStart(const struct nodeID **peers, int size, const void *metadata, int metadata_size);
83

  
84

  
85
/**
86
  @brief Insert a peer in the neighbourhood.
87

  
88
  This function can be used to add a specified neighbour to the
89
  neighbourhood.
90
  @param neighbour the id of the peer to be added to the neighbourhood.
91
  @param metadata Pointer to the array of metadata belonging to the peers to be added.
92
  @param metadata_size Number of bytes of each metadata.
93
  @return 0 in case of success; -1 in case of error.
94
*/
95
int tmanAddNeighbour(struct nodeID *neighbour, void *metadata, int metadata_size);
96

  
97
/**
98
  @brief Pass a received packet to Tman.
99

  
100
  This function passes to Tman a packet that has
101
  been received from the network. The Topology Manager will parse
102
  such packet and run the protocol, adding or removing peers to the
103
  neighbourhood, and sending overlay management messages to other peers.
104
  @param buff a memory buffer containing the received message.
105
  @param len the size of such a memory buffer.
106
  @param peers Array of nodeID pointers to be added in tman cache.
107
  @param size Number of elements in peers.
108
  @param metadata Pointer to the array of metadata belonging to the peers to be added.
109
  @param metadata_size Number of bytes of each metadata.
110
  @return 0 in case of success; -1 in case of error.
111
*/
112
int tmanParseData(const uint8_t *buff, int len, const struct nodeID **peers, int size, const void *metadata, int metadata_size);
113

  
114

  
115
/**
116
  @brief Change the metadata in tman neighborhood.
117

  
118
  This function changes the metadata associated with the current node.
119

  
120
  @param metadata Pointer to the metadata belonging to the peer.
121
  @param metadata_size Number of bytes of the metadata.
122
  @return 1 if successful, -1 otherwise.
123
 */
124
int tmanChangeMetadata(void *metadata, int metadata_size);
125

  
126
/**
127
  @brief Get the metadata of the neighbors.
128
  @param metadata_size Address of the integer that will be set to the size of each metadata.
129
  @return a pointer to the array of metadata associated with the peers in the neighbourhood. NULL
130
          in case of error, or if the neighbourhood is empty.
131
*/
132
const void *tmanGetMetadata(int *metadata_size);
133

  
134

  
135
/**
136
  @brief Get the current neighborhood size.
137

  
138
  This function returns the current number of peers in the local tman neighborhood.
139

  
140
  @return The current size of the neighborhood.
141
*/
142
const int tmanGetNeighbourhoodSize();
143

  
144
/*
145
	@brief Get the state of Tman.
146

  
147
	This function tells whether Tman is active or idle.
148

  
149
	@return 1 if Tman is active, 0 if it is idle.
150
*/
151
//const int tmanGetState();
152

  
153

  
154
//int tmanSetRankingFunction(tmanRankingFunction f);
155

  
156

  
157
//int tmanSetBestPeers(int p);
158

  
159

  
160
//int tmanSetPeriod(int p);
161

  
162
/**
163
 * @brief Get the highest ranked tman peers.
164
 *
165
 * This function allows the user to retrieve the highest ranked n peers from tman cache, along with
166
 * their metadata. The number of peers actually returned may be different from what is asked, depending
167
 * on the current size of the cache.
168
 * Notice that if the user asks for a number of peers that exceeds the current cache size, a join with
169
 * the known peers set provided via tmanParseData will be triggered at the next
170
 * time tmanParseData is called. This will change (and make unstable,
171
 * at least for few subsequent iterations) the current known topology. Thus, it is advisable to do so only if
172
 * necessary (i.e. when the user really needs more peers to communicate with).
173
 *
174
 * @param n The number of peer tman is asked for.
175
 * @param peers Array of nodeID pointers to be filled.
176
 * @param metadata Pointer to the array of metadata belonging to the peers to be given.
177
 * @return The number of elements in peers.
178
 */
179
int tmanGivePeers (int n, struct nodeID **peers, void *metadata);//, int *metadata_size);
180

  
181

  
182
/**
183
  @brief Increase the neighbourhood size.
184

  
185
  This function can be used to increase the number of neighbours (that is,
186
       the degree of the overlay graph) by a specified amount.
187
       The actual size change will be done the next time tmanParseData is called.
188
       As currently implemented, it doubles the current size at most.
189
       If the argument is negative or a resize has already been requested, but not performed yet,
190
       no change will occur and an error code is returned.
191
  @param n number of peers by which the neighbourhood size must be incremented.
192
  @return the new neighbourhood size in case of success; -1 in case of error.
193
*/
194
int tmanGrowNeighbourhood(int n);
195

  
196

  
197
/**
198
  @brief Decrease the neighbourhood size.
199

  
200
  This function can be used to reduce the number of neighbours (that is,
201
       the degree of the overlay graph) by a specified amount.
202
       The actual size change will be done the next time tmanParseData is called.
203
       If the argument is negative, or greater equal than the current cache size,
204
        or a resize has already been requested, but not performed yet,
205
       no change will occur and an error code is returned.
206
  @param n number of peers by which the neighbourhood size must be decreased.
207
  @return the new neighbourhood size in case of success; -1 in case of error.
208
*/
209
int tmanShrinkNeighbourhood(int n);
210

  
211
#endif /* TMAN_H */
som/TopologyManager/Makefile
1 1
BASE = ../..
2 2

  
3
OBJS = ncast.o topo_proto.o topocache.o
3
OBJS = ncast.o topo_proto.o topocache.o tman.o
4 4

  
5 5
all: libtopman.a
6 6

  
som/TopologyManager/ncast.c
79 79
  if (cache_add(local_cache, neighbour, metadata, metadata_size) < 0) {
80 80
    return -1;
81 81
  }
82
  return topo_query_peer(local_cache, neighbour);
82
  return ncast_query_peer(local_cache, neighbour);
83 83
}
84 84

  
85 85
int topParseData(const uint8_t *buff, int len)
......
100 100

  
101 101
    remote_cache = entries_undump(buff + sizeof(struct topo_header), len - sizeof(struct topo_header));
102 102
    if (h->type == NCAST_QUERY) {
103
      topo_reply(remote_cache, local_cache);
103
      ncast_reply(remote_cache, local_cache);
104 104
    }
105 105
    new = merge_caches(local_cache, remote_cache, cache_size, &dummy);
106 106
    cache_free(remote_cache);
......
112 112

  
113 113
  if (time_to_send()) {
114 114
    cache_update(local_cache);
115
    topo_query(local_cache);
115
    ncast_query(local_cache);
116 116
  }
117 117

  
118 118
  return 0;
som/TopologyManager/proto.h
5 5

  
6 6
#define NCAST_QUERY 0x01
7 7
#define NCAST_REPLY 0x02
8
#define TMAN_QUERY 0x03
9
#define TMAN_REPLY 0x04
10

  
som/TopologyManager/tman.c
1
/*
2
 *  Copyright (c) 2010 Marco Biazzini
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 <string.h>
13

  
14
#include "net_helper.h"
15
#include "topmanager.h"
16
#include "topocache.h"
17
#include "topo_proto.h"
18
#include "proto.h"
19
#include "msg_types.h"
20

  
21
#define TMAN_MAX_PEERS 5 // max # of neighbors in local cache (should be > than the next)
22
#define TMAN_MAX_PREFERRED_PEERS 5 // # of peers to choose a receiver among (should be < than the previous)
23
#define TMAN_MAX_GOSSIPING_PEERS 5 // # size of the view to be sent to receiver peer (should be <= than the previous)
24
#define TMAN_IDLE_TIME 10 // # of iterations to wait before switching to inactive state
25
#define TMAN_STD_PERIOD 1000000
26

  
27
static const int TMAN_FLAGS = 2;
28
static const int TMAN_BLACK = 0;
29
static const int TMAN_STICKY = 1;
30

  
31
//static const int MAX_PEERS = TMAN_MAX_PEERS;
32
static  int MAX_PREFERRED_PEERS = TMAN_MAX_PREFERRED_PEERS;
33
static  int MAX_GOSSIPING_PEERS = TMAN_MAX_GOSSIPING_PEERS;
34
static  int IDLE_TIME = TMAN_IDLE_TIME;
35

  
36
static uint64_t currtime;
37
static int cache_size = TMAN_MAX_PEERS;
38
static struct peer_cache *local_cache = NULL;
39
static int period = TMAN_STD_PERIOD;
40
static int active = 0;
41
static ranking_function rfun;
42
static void *mymeta;
43

  
44
static struct peer_cache *rank_cache (const struct peer_cache *c, const struct nodeID *target, const void *target_meta)
45
{
46
	struct peer_cache *res;
47
	int i,msize,max = MAX_GOSSIPING_PEERS;
48
	const uint8_t *mdata;
49

  
50
        mdata = get_metadata(c,&msize);
51
	res = cache_init(cache_size,msize);
52
        if (res == NULL) {
53
          return res;
54
        }
55

  
56
        for (i=0;nodeid(c,i) && i<max;i++) {
57
				if (!nodeid_equal(nodeid(c,i),target))
58
					cache_add_ranked(res,nodeid(c,i),mdata+i*msize,msize, rfun, target_meta);
59
				else
60
					max++;
61
	}
62

  
63
	return res;
64
}
65

  
66
static uint64_t gettime(void)
67
{
68
  struct timeval tv;
69

  
70
  gettimeofday(&tv, NULL);
71

  
72
  return tv.tv_usec + tv.tv_sec * 1000000ull;
73
}
74

  
75
int tmanInit(struct nodeID *myID, void *metadata, int metadata_size, ranking_function f) //, int max_peers, int max_idle, int periodicity
76
{
77
  rfun = f;
78
  topo_proto_init(myID, metadata, metadata_size);
79
  mymeta = metadata;
80
//  if (max_peers) {
81
//	  cache_size = max_peers;
82
//  }
83
//  else
84
	  cache_size = TMAN_MAX_PEERS;
85
  local_cache = cache_init(cache_size, metadata_size);
86
  if (local_cache == NULL) {
87
    return -1;
88
  }
89
//  if (max_idle)
90
//	  IDLE_TIME = max_idle;
91
//  else
92
	  IDLE_TIME = TMAN_IDLE_TIME;
93
//  if (periodicity>=1000000)
94
//	  period = periodicity;
95
//  else
96
	  period = TMAN_STD_PERIOD;
97

  
98
  currtime = gettime();
99

  
100
  return 0;
101
}
102

  
103

  
104
int tmanStart(struct nodeID **peers, int size, const void *metadata, int metadata_size,
105
	int best_peers, int gossip_peers)
106
{
107
	int j,res=0;
108

  
109
	if (best_peers)
110
		MAX_PREFERRED_PEERS = best_peers;
111
	else MAX_PREFERRED_PEERS = TMAN_MAX_PREFERRED_PEERS;
112
	if (gossip_peers)
113
		MAX_GOSSIPING_PEERS = gossip_peers;
114
	else
115
		MAX_GOSSIPING_PEERS = TMAN_MAX_GOSSIPING_PEERS;
116
	// TODO: empty tabu list, if any...
117
	for (j=0;j<size && res!=-3;j++) // TODO: conditions to keep some peers if app needs...
118
		res = cache_add_ranked(local_cache,peers[j],(const uint8_t *)metadata+j*metadata_size,metadata_size,rfun, mymeta);
119
	if (res == -3)
120
		return -1;
121
	active = TMAN_IDLE_TIME;
122
	return 0;
123
}
124

  
125
static int time_to_send()
126
{
127
	if (gettime() - currtime > period) {
128
		currtime += period;
129
		if (active > 0)
130
			return 1;
131
	}
132

  
133
  return 0;
134
}
135

  
136

  
137
int tmanChangeMetadata(struct nodeID *peer, void *metadata, int metadata_size)
138
{
139
  if (topo_proto_metadata_update(peer, metadata, metadata_size) <= 0) {
140
    return -1;
141
  }
142
  mymeta = metadata;
143

  
144
  return 1;
145
}
146

  
147
int tmanAddNeighbour(struct nodeID *neighbour, void *metadata, int metadata_size)
148
{
149
  // TODO: change this for flagging...
150
	if (cache_add_ranked(local_cache, neighbour, metadata, metadata_size, rfun, mymeta) < 0) {
151
    return -1;
152
  }
153
  return 1;//topo_query_peer(local_cache, neighbour, TMAN_QUERY);
154
}
155

  
156
int tmanParseData(const uint8_t *buff, int len)
157
{
158
        int msize,s;
159
        const uint8_t *mdata;
160
	struct peer_cache *new;
161

  
162
        new = NULL;
163
	  // TODO: change this for flagging...
164
	if (local_cache == NULL) return 1;
165
	if (len) {
166
		const struct topo_header *h = (const struct topo_header *)buff;
167
		struct peer_cache *remote_cache; int idx;
168
                int from;
169

  
170
	    if (h->protocol != MSG_TYPE_TOPOLOGY) {
171
	      fprintf(stderr, "TMAN: Wrong protocol!\n");
172
	      return -1;
173
	    }
174

  
175
	    if (h->type != TMAN_QUERY && h->type != TMAN_REPLY) {
176
	      return -1;
177
	    }
178
		remote_cache = entries_undump(buff + sizeof(struct topo_header), len - sizeof(struct topo_header));
179
		mdata = get_metadata(remote_cache,&msize);
180
		get_metadata(local_cache,&s);
181

  
182
		if (msize != s) {
183
			fprintf(stderr, "TMAN: Metadata size mismatch! -> local (%d) != received (%d)\n",
184
				s, msize);
185
			return 1;
186
		}
187

  
188
		if (h->type == TMAN_QUERY) {
189
//			fprintf(stderr, "\tTman: Parsing received msg to reply...\n");
190
			new = rank_cache(local_cache, nodeid(remote_cache, 0), get_metadata(remote_cache, &msize));
191
			if (new) {
192
				tman_reply(remote_cache, new);
193
				cache_free(new);
194
				// TODO: put sender in tabu list (check list size, etc.), if any...
195
			}
196
		}
197
		idx = cache_add_ranked(local_cache, nodeid(remote_cache,0), mdata, msize,rfun, mymeta);
198
//		fprintf(stderr, "\tidx = %d\n",idx);
199
		new = merge_caches_ranked(local_cache, remote_cache, cache_size, &from, rfun, mymeta);
200

  
201
//		  newsize = new_cache->current_size>c1->cache_size?new_cache->current_size:c1->cache_size;
202
//		  newsize = cache_shrink(new_cache,(new_cache->cache_size-newsize));
203
//		  // TODO: check newsize??
204
//		  return new_cache;
205

  
206
		cache_free(remote_cache);
207
		if (new!=NULL) {
208
		  cache_free(local_cache);
209
		  local_cache = new;
210
                }
211
	
212
                if (from == 1) {
213
		     	if (active > 0) active = TMAN_IDLE_TIME;
214
                }	else if (active > 0){
215
		     	active--;
216
		}
217
  }
218

  
219
  if (time_to_send()) {
220
	void *meta;
221
	struct nodeID *chosen;
222

  
223
	cache_update(local_cache);
224
	mdata = get_metadata(local_cache,&msize);
225
	chosen = rand_peer(local_cache, &meta);		//MAX_PREFERRED_PEERS
226
		 // TODO: check for chosen peer against tabu list, if any...
227
		new = rank_cache(local_cache, chosen, meta);
228
		if (new==NULL) {
229
			fprintf(stderr, "TMAN: No cache could be sent to remote peer!\n");
230
			return 1;
231
	}
232
	if (new) {
233
		tman_query_peer(new, chosen);
234
		cache_free(new);
235
	}
236
  }
237

  
238
  return 0;
239
}
240

  
241
const struct nodeID **tmanGetNeighbourhood(int *n)
242
{
243
  static struct nodeID *r[2000 /*FIXME!*/];
244
  for (*n = 0; nodeid(local_cache, *n); (*n)++) {
245
    r[*n] = nodeid(local_cache, *n);
246
    //fprintf(stderr, "Checking table[%d]\n", *n);
247
  }
248
  fprintf(stderr, "\tTman : active = %d\n",active);
249
  return (const struct nodeID **)r;
250
}
251

  
252
// not self metadata, but neighbors'.
253
const void *tmanGetMetadata(int *metadata_size)
254
{
255
  return get_metadata(local_cache, metadata_size);
256
}
257

  
258
//assuming peers are always ordered
259
int tmanGivePeers (int n, struct nodeID **peers, uint8_t *metadata) {
260

  
261
//	void *m[n];
262
	int msize;
263
	const uint8_t *mdata = get_metadata(local_cache,&msize);
264
	int i;
265
	for (i=0; nodeid(local_cache, i) && (i < n); i++)
266
			peers[i] = nodeid(local_cache,i);
267
			if (msize)
268
				memcpy(metadata+i*msize,mdata+i*msize,msize);
269
	return i;
270
}
som/TopologyManager/topo_proto.c
38 38
  return p - payload;
39 39
}
40 40

  
41
int topo_reply(const struct peer_cache *c, struct peer_cache *local_cache)
41
static int topo_reply(const struct peer_cache *c, struct peer_cache *local_cache, int protocol, int type)
42 42
{
43 43
  uint8_t pkt[MAX_MSG_SIZE];
44 44
  struct topo_header *h = (struct topo_header *)pkt;
......
53 53
  }
54 54
#endif
55 55
  dst = nodeid(c, 0);
56
  h->protocol = MSG_TYPE_TOPOLOGY;
57
  h->type = NCAST_REPLY;
56
  h->protocol = protocol;
57
  h->type = type;
58 58
  len = ncast_payload_fill(pkt + sizeof(struct topo_header), MAX_MSG_SIZE - sizeof(struct topo_header), local_cache, dst);
59 59

  
60 60
  res = len > 0 ? send_to_peer(nodeid(myEntry, 0), dst, pkt, sizeof(struct topo_header) + len) : len;
......
62 62
  return res;
63 63
}
64 64

  
65
int topo_query_peer(struct peer_cache *local_cache, struct nodeID *dst)
65
static int topo_query_peer(struct peer_cache *local_cache, struct nodeID *dst, int protocol, int type)
66 66
{
67 67
  uint8_t pkt[MAX_MSG_SIZE];
68 68
  struct topo_header *h = (struct topo_header *)pkt;
69 69
  int len;
70 70

  
71
  h->protocol = MSG_TYPE_TOPOLOGY;
72
  h->type = NCAST_QUERY;
71
  h->protocol = protocol;
72
  h->type = type;
73 73
  len = ncast_payload_fill(pkt + sizeof(struct topo_header), MAX_MSG_SIZE - sizeof(struct topo_header), local_cache, dst);
74 74
  return len > 0  ? send_to_peer(nodeid(myEntry, 0), dst, pkt, sizeof(struct topo_header) + len) : len;
75 75
}
76 76

  
77
int topo_query(struct peer_cache *local_cache)
77
int ncast_reply(const struct peer_cache *c, struct peer_cache *local_cache)
78
{
79
  return topo_reply(c, local_cache, MSG_TYPE_TOPOLOGY, NCAST_REPLY);
80
}
81

  
82
int tman_reply(const struct peer_cache *c, struct peer_cache *local_cache)
83
{
84
  return topo_reply(c, local_cache, MSG_TYPE_TMAN, TMAN_REPLY);
85
}
86

  
87
int ncast_query_peer(struct peer_cache *local_cache, struct nodeID *dst)
88
{
89
  return topo_query_peer(local_cache, dst, MSG_TYPE_TOPOLOGY, NCAST_QUERY);
90
}
91

  
92
int tman_query_peer(struct peer_cache *local_cache, struct nodeID *dst)
93
{
94
  return topo_query_peer(local_cache, dst, MSG_TYPE_TMAN, TMAN_QUERY);
95
}
96

  
97
int ncast_query(struct peer_cache *local_cache)
78 98
{
79 99
  struct nodeID *dst;
80 100

  
81
  dst = rand_peer(local_cache);
101
  dst = rand_peer(local_cache, NULL);
82 102
  if (dst == NULL) {
83 103
    return 0;
84 104
  }
85
  return topo_query_peer(local_cache, dst);
105
  return topo_query_peer(local_cache, dst, MSG_TYPE_TOPOLOGY, NCAST_QUERY);
86 106
}
87 107

  
88 108
int topo_proto_metadata_update(struct nodeID *peer, void *meta, int meta_size)
som/TopologyManager/topo_proto.h
1
int topo_reply(const struct peer_cache *c, struct peer_cache *local_cache);
2
int topo_query_peer(struct peer_cache *local_cache, struct nodeID *dst);
3
int topo_query(struct peer_cache *local_cache);
1
int ncast_reply(const struct peer_cache *c, struct peer_cache *local_cache);
2
int tman_reply(const struct peer_cache *c, struct peer_cache *local_cache);
3
int ncast_query(struct peer_cache *local_cache);
4
int tman_query(struct peer_cache *local_cache);
5
int tman_query_peer(struct peer_cache *local_cache, struct nodeID *dst);
6
int ncast_query_peer(struct peer_cache *local_cache, struct nodeID *dst);
7
//int topo_query_peer(struct peer_cache *local_cache, struct nodeID *dst);
4 8
int topo_proto_metadata_update(struct nodeID *peer, void *meta, int meta_size);
5 9
int topo_proto_init(struct nodeID *s, void *meta, int meta_size);
som/TopologyManager/topocache.c
214 214
  return 0;
215 215
}
216 216

  
217
struct nodeID *rand_peer(struct peer_cache *c)
217
struct nodeID *rand_peer(struct peer_cache *c, void **meta)
218 218
{
219 219
  int j;
220 220

  
......
223 223
  }
224 224
  j = ((double)rand() / (double)RAND_MAX) * c->current_size;
225 225

  
226
  if (*meta) {
227
    *meta = c->metadata + (j * c->metadata_size);
228
  }
229

  
226 230
  return c->entries[j].id;
227 231
}
228 232

  
som/TopologyManager/topocache.h
13 13
int cache_add(struct peer_cache *c, struct nodeID *neighbour, const void *meta, int meta_size);
14 14
int cache_del(struct peer_cache *c, struct nodeID *neighbour);
15 15

  
16
struct nodeID *rand_peer(struct peer_cache *c);
16
struct nodeID *rand_peer(struct peer_cache *c, void **meta);
17 17

  
18 18
struct peer_cache *entries_undump(const uint8_t *buff, int size);
19 19
int cache_header_dump(uint8_t *b, const struct peer_cache *c);

Also available in: Unified diff