Statistics
| Branch: | Revision:

grapes / src / Cache / topo_proto.c @ 2cc1d4ec

History | View | Annotate | Download (2.97 KB)

1
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *
4
 *  This is free software; see lgpl-2.1.txt
5
 */
6

    
7
#include <stdint.h>
8
#include <stdlib.h>
9
#include <stdio.h>
10

    
11
#include "net_helper.h"
12
#include "topocache.h"
13
#include "proto.h"
14
#include "topo_proto.h"
15

    
16
#define MAX_MSG_SIZE 1500
17

    
18
struct topo_context{
19
 struct peer_cache *myEntry;
20
};
21

    
22
static int topo_payload_fill(struct topo_context *context, uint8_t *payload, int size, const struct peer_cache *c, const struct nodeID *snot, int max_peers, int include_me)
23
{
24
  int i;
25
  uint8_t *p = payload;
26

    
27
  if (!max_peers) max_peers = MAX_MSG_SIZE; // just to be sure to dump the whole cache...
28
  p += cache_header_dump(p, c, include_me);
29
  if (include_me) {
30
    p += entry_dump(p, context->myEntry, 0, size - (p - payload));
31
    max_peers--;
32
  }
33
  for (i = 0; nodeid(c, i) && max_peers; i++) {
34
    if (!nodeid_equal(nodeid(c, i), snot)) {
35
      int res;
36
      res = entry_dump(p, c, i, size - (p - payload));
37
      if (res < 0) {
38
        fprintf(stderr, "too many entries!\n");
39
        return -1;
40
      }
41
      p += res;
42
      --max_peers;
43
    }
44
  }
45

    
46
  return p - payload;
47
}
48

    
49
int topo_reply(struct topo_context *context, const struct peer_cache *c, const struct peer_cache *local_cache, int protocol, int type, int max_peers, int include_me)
50
{
51
  uint8_t pkt[MAX_MSG_SIZE];
52
  struct topo_header *h = (struct topo_header *)pkt;
53
  int len, res;
54
  struct nodeID *dst;
55

    
56
#if 0
57
  n = psize / sizeof(struct cache_entry);
58
  if (n * sizeof(struct cache_entry) != psize) {
59
    fprintf(stderr, "Wrong number of elems %d (%d / %d)!!!\n", n, psize, sizeof(struct cache_entry));
60
    return -1;
61
  }
62
#endif
63
  dst = nodeid(c, 0);
64
  h->protocol = protocol;
65
  h->type = type;
66
  len = topo_payload_fill(context, pkt + sizeof(struct topo_header), MAX_MSG_SIZE - sizeof(struct topo_header), local_cache, dst, max_peers, include_me);
67

    
68
  res = len > 0 ? send_to_peer(nodeid(context->myEntry, 0), dst, pkt, sizeof(struct topo_header) + len) : len;
69

    
70
  return res;
71
}
72

    
73
int topo_query_peer(struct topo_context *context, const struct peer_cache *local_cache, struct nodeID *dst, int protocol, int type, int max_peers)
74
{
75
  uint8_t pkt[MAX_MSG_SIZE];
76
  struct topo_header *h = (struct topo_header *)pkt;
77
  int len;
78

    
79
  h->protocol = protocol;
80
  h->type = type;
81
  len = topo_payload_fill(context, pkt + sizeof(struct topo_header), MAX_MSG_SIZE - sizeof(struct topo_header), local_cache, dst, max_peers, 1);
82
  return len > 0  ? send_to_peer(nodeid(context->myEntry, 0), dst, pkt, sizeof(struct topo_header) + len) : len;
83
}
84

    
85
int topo_proto_metadata_update(struct topo_context *context, const void *meta, int meta_size)
86
{
87
  if (cache_metadata_update(context->myEntry, nodeid(context->myEntry, 0), meta, meta_size) > 0) {
88
    return 1;
89
  }
90

    
91
  return -1;
92
}
93

    
94
struct topo_context* topo_proto_init(struct nodeID *s, const void *meta, int meta_size)
95
{
96
  struct topo_context* con;
97

    
98
  con = malloc(sizeof(struct topo_context));
99
  if (!con) return NULL;
100

    
101
  con->myEntry = cache_init(1, meta_size, 0);
102
  cache_add(con->myEntry, s, meta, meta_size);
103

    
104
  return con;
105
}