Statistics
| Branch: | Revision:

streamers / chunk_signaling.c @ 7ad9ec5e

History | View | Annotate | Download (4.71 KB)

1
/*
2
 *  Copyright (c) 2009 Alessandro Russo.
3
 *
4
 *  This is free software;
5
 *  see GPL.txt
6
 *
7
 * Chunk Signaling API - Higher Abstraction
8
 *
9
 * The Chunk Signaling HA provides a set of primitives for chunks signaling negotiation with other peers, in order to collect information for the effective chunk exchange with other peers. <br>
10
 * This is a part of the Data Exchange Protocol which provides high level abstraction for chunks' negotiations, like requesting and proposing chunks.
11
 *
12
 */
13

    
14
#include <stdint.h>
15
#include <stdlib.h>
16
#include <stdio.h>
17
#include <sys/time.h>
18
#include <errno.h>
19
#include <assert.h>
20
#include "peer.h"
21
#include "peerset.h"
22
#include "chunkidset.h"
23
#include "trade_sig_la.h"
24
#include "chunk_signaling.h"
25
#include "msg_types.h"
26
#include "net_helper.h"
27

    
28
#include "dbg.h"
29

    
30
static struct nodeID *localID;
31
static struct peerset *pset;
32

    
33

    
34
struct peer *nodeid_to_peer(const struct nodeID* id, int reg)
35
{
36
  struct peer *p = peerset_get_peer(pset, id);
37
  if (!p) {
38
    fprintf(stderr,"warning: received message from unknown peer: %s!\n",node_addr(id));
39
    if (reg) {
40
      fprintf(stderr,"Adding %s to neighbourhood!\n", node_addr(id));
41
      peerset_add_peer(pset,id);
42
      p = peerset_get_peer(pset,id);
43
    }
44
  }
45

    
46
  return p;
47
}
48

    
49
void bmap_received(const struct nodeID *fromid, const struct nodeID *ownerid, struct chunkID_set *c_set, int trans_id) {
50
  struct peer *owner = nodeid_to_peer(ownerid,1);
51
  if (owner) {        //now we have it almost sure
52
    chunkID_set_union(owner->bmap,c_set);        //don't send it back
53
    gettimeofday(&owner->bmap_timestamp, NULL);
54
  }
55
}
56

    
57
 /**
58
 * Dispatcher for signaling messages.
59
 *
60
 * This method decodes the signaling messages, retrieving the set of chunk and the signaling
61
 * message, invoking the corresponding method.
62
 *
63
 * @param[in] buff buffer which contains the signaling message
64
 * @param[in] buff_len length of the buffer
65
 * @param[in] msgtype type of message in the buffer
66
 * @param[in] max_deliver deliver at most this number of Chunks
67
 * @param[in] arg parameters associated to the signaling message
68
 * @return 0 on success, <0 on error
69
 */
70

    
71
int sigParseData(const struct nodeID *fromid, uint8_t *buff, int buff_len) {
72
    struct chunkID_set *c_set;
73
    void *meta;
74
    int meta_len;
75
    struct sig_nal *signal;
76
    int sig;
77
    dprintf("\tDecoding signaling message...");
78
    c_set = decodeChunkSignaling(&meta, &meta_len, buff+1, buff_len-1);
79
    dprintf("SIG_HEADER: len: %d, of which meta: %d\n", buff_len, meta_len);
80
    if (!c_set) {
81
      fprintf(stdout, "ERROR decoding signaling message\n");
82
      return -1;
83
    }
84
    dprintf("done\n");
85
    signal = (struct sig_nal *) meta;
86
    sig = (int) (signal->type);
87
    dprintf("\tSignaling Type %d\n", sig);
88
    //MaxDelivery  and Trans_Id to be defined
89
    switch (sig) {
90
        case MSG_SIG_BMOFF:
91
        {
92
          int dummy;
93
          struct nodeID *ownerid = nodeid_undump(&(signal->third_peer),&dummy);
94
          bmap_received(fromid, ownerid, c_set, signal->trans_id);
95
          break;
96
        }
97
        default:
98
          return -1;
99
    }
100
    return 1;
101
}
102

    
103
/**
104
 * Send a BufferMap to a Peer.
105
 *
106
 * Send (our own or some other peer's) BufferMap to a third Peer.
107
 *
108
 * @param[in] to PeerID.
109
 * @param[in] owner Owner of the BufferMap to send.
110
 * @param[in] bmap the BufferMap to send.
111
 * @param[in] bmap_len length of the buffer map
112
 * @param[in] trans_id transaction number associated with this send
113
 * @return 0 on success, <0 on error
114
 */
115
int sendBufferMap(const struct nodeID *to_id, const struct nodeID *owner_id, ChunkIDSet *bmap, int bmap_len, int trans_id) {    
116
    int buff_len, id_len, msg_len, ret;
117
    uint8_t *buff;
118
    //msgtype = MSG_TYPE_SIGNALLING;
119
    struct sig_nal sigmex;
120
    sigmex.type = MSG_SIG_BMOFF;
121
    sigmex.trans_id = trans_id;
122
    id_len = nodeid_dump(&sigmex.third_peer, owner_id);
123
    buff_len = 1 + bmap_len * 4 + 12 + sizeof(sigmex)-1 + id_len; // this should be enough
124
    dprintf("SIG_HEADER: Type %d Tx %d PP %s\n",sigmex.type,sigmex.trans_id,node_addr(owner_id));
125
    buff = malloc(buff_len);
126
    if (!buff) {
127
      return -1;
128
    }
129
    buff[0] = MSG_TYPE_SIGNALLING;
130
    msg_len = 1 + encodeChunkSignaling(bmap, &sigmex, sizeof(sigmex)-1 + id_len, buff+1, buff_len-1);
131
    dprintf("SIG_HEADER: len: %d, of which meta: %d\n", msg_len, sizeof(sigmex)-1 + id_len);
132
    if (msg_len < 0) {
133
      fprintf(stderr, "Error in encoding chunk set for sending a buffermap\n");
134
      ret = -1;
135
    } else {
136
      send_to_peer(localID, to_id, buff, msg_len);
137
    }
138
    ret = 1;
139
    free(buff);
140
    return ret;
141
}
142

    
143
int sendMyBufferMap(const struct nodeID *to_id, ChunkIDSet *bmap, int bmap_len, int trans_id)
144
{
145
  return sendBufferMap(to_id, localID, bmap, bmap_len, trans_id);
146
}
147

    
148
int sigInit(struct nodeID *myID, struct peerset *ps)
149
{
150
  localID = myID;
151
  pset = ps;
152
  return 1;
153
}