Statistics
| Branch: | Revision:

grapes / src / Cache / topo_proto.c @ bf8e2cfd

History | View | Annotate | Download (3.14 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
struct topo_context{
17
 struct peer_cache *myEntry;
18
 uint8_t *pkt;
19
 int pkt_size;
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 = 1000; // FIXME: 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
  struct topo_header *h = (struct topo_header *)context->pkt;
52
  int len, res;
53
  struct nodeID *dst;
54

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

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

    
69
  return res;
70
}
71

    
72
int topo_query_peer(struct topo_context *context, const struct peer_cache *local_cache, struct nodeID *dst, int protocol, int type, int max_peers)
73
{
74
  struct topo_header *h = (struct topo_header *)context->pkt;
75
  int len;
76

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

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

    
89
  return -1;
90
}
91

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

    
96
  con = malloc(sizeof(struct topo_context));
97
  if (!con) return NULL;
98
  con->pkt_size = 60 * 1024;        // FIXME: Do something smarter, here!
99
  con->pkt = malloc(con->pkt_size);
100
  if (!con->pkt) {
101
    free(con);
102

    
103
    return NULL;
104
  }
105

    
106
  con->myEntry = cache_init(1, meta_size, 0);
107
  cache_add(con->myEntry, s, meta, meta_size);
108

    
109
  return con;
110
}