streamers / chunk_signaling.c @ a0192c66
History | View | Annotate | Download (4.31 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 <errno.h> |
18 |
#include <assert.h> |
19 |
#include "peer.h" |
20 |
#include "peerset.h" |
21 |
#include "chunkidset.h" |
22 |
#include "trade_sig_la.h" |
23 |
#include "chunk_signaling.h" |
24 |
#include "msg_types.h" |
25 |
#include "net_helper.h" |
26 |
|
27 |
#include "dbg.h" |
28 |
|
29 |
static struct nodeID *localID; |
30 |
static struct peerset *pset; |
31 |
|
32 |
|
33 |
/**
|
34 |
* Dispatcher for signaling messages.
|
35 |
*
|
36 |
* This method decodes the signaling messages, retrieving the set of chunk and the signaling
|
37 |
* message, invoking the corresponding method.
|
38 |
*
|
39 |
* @param[in] buff buffer which contains the signaling message
|
40 |
* @param[in] buff_len length of the buffer
|
41 |
* @param[in] msgtype type of message in the buffer
|
42 |
* @param[in] max_deliver deliver at most this number of Chunks
|
43 |
* @param[in] arg parameters associated to the signaling message
|
44 |
* @return 0 on success, <0 on error
|
45 |
*/
|
46 |
|
47 |
int sigParseData(uint8_t *buff, int buff_len) { |
48 |
struct chunkID_set *c_set;
|
49 |
void *meta;
|
50 |
int meta_len;
|
51 |
struct sig_nal *signal;
|
52 |
int sig;
|
53 |
fprintf(stdout, "\tDecoding signaling message...");
|
54 |
fprintf(stdout, "done\n");
|
55 |
c_set = decodeChunkSignaling(&meta, &meta_len, buff+1, buff_len-1); |
56 |
if (!c_set) {
|
57 |
fprintf(stdout, "ERROR decoding signaling message\n");
|
58 |
return -1; |
59 |
} |
60 |
signal = (struct sig_nal *) meta;
|
61 |
sig = (int) (signal->type);
|
62 |
fprintf(stdout, "\tSignaling Type %d\n", sig);
|
63 |
//MaxDelivery and Trans_Id to be defined
|
64 |
switch (sig) {
|
65 |
case MSG_SIG_BMOFF:
|
66 |
{//BufferMap Received
|
67 |
int dummy;
|
68 |
struct nodeID *ownerid = nodeid_undump(&(signal->third_peer),&dummy);
|
69 |
struct peer *owner = peerset_get_peer(pset, ownerid);
|
70 |
if (!owner) {
|
71 |
printf("warning: received bmap of unknown peer: %s! Adding it to neighbourhood!\n", node_addr(ownerid));
|
72 |
peerset_add_peer(pset,ownerid); |
73 |
owner = peerset_get_peer(pset,ownerid); |
74 |
} |
75 |
if (owner) { //now we have it almost sure |
76 |
chunkID_set_union(owner->bmap,c_set); //don't send it back
|
77 |
} |
78 |
} |
79 |
default:
|
80 |
{ |
81 |
return -1; |
82 |
} |
83 |
} |
84 |
return 1; |
85 |
} |
86 |
|
87 |
/**
|
88 |
* Send a BufferMap to a Peer.
|
89 |
*
|
90 |
* Send (our own or some other peer's) BufferMap to a third Peer.
|
91 |
*
|
92 |
* @param[in] to PeerID.
|
93 |
* @param[in] owner Owner of the BufferMap to send.
|
94 |
* @param[in] bmap the BufferMap to send.
|
95 |
* @param[in] bmap_len length of the buffer map
|
96 |
* @param[in] trans_id transaction number associated with this send
|
97 |
* @return 0 on success, <0 on error
|
98 |
*/
|
99 |
int sendBufferMap(const struct nodeID *to_id, const struct nodeID *owner_id, ChunkIDSet *bmap, int bmap_len, int trans_id) { |
100 |
int buff_len, id_len, msg_len, ret;
|
101 |
uint8_t *buff; |
102 |
//msgtype = MSG_TYPE_SIGNALLING;
|
103 |
struct sig_nal sigmex;
|
104 |
sigmex.type = MSG_SIG_BMOFF; |
105 |
sigmex.trans_id = trans_id; |
106 |
id_len = nodeid_dump(&sigmex.third_peer, owner_id); |
107 |
buff_len = 1 + bmap_len * 4 + 12 + sizeof(sigmex)-1 + id_len; // this should be enough |
108 |
dprintf("SIG_HEADER: Type %d Tx %d PP %s\n",sigmex.type,sigmex.trans_id,node_addr(owner_id));
|
109 |
buff = malloc(buff_len); |
110 |
if (!buff) {
|
111 |
return -1; |
112 |
} |
113 |
buff[0] = MSG_TYPE_SIGNALLING;
|
114 |
msg_len = 1 + encodeChunkSignaling(bmap, &sigmex, sizeof(sigmex)-1 + id_len, buff+1, buff_len-1); |
115 |
dprintf("SIG_HEADER: len: %d, of which meta: %d\n", msg_len, sizeof(sigmex)-1 + id_len); |
116 |
if (msg_len < 0) { |
117 |
fprintf(stderr, "Error in encoding chunk set for sending a buffermap\n");
|
118 |
ret = -1;
|
119 |
} else {
|
120 |
send_to_peer(localID, to_id, buff, msg_len); |
121 |
} |
122 |
ret = 1;
|
123 |
free(buff); |
124 |
return ret;
|
125 |
} |
126 |
|
127 |
int sendMyBufferMap(const struct nodeID *to_id, ChunkIDSet *bmap, int bmap_len, int trans_id) |
128 |
{ |
129 |
return sendBufferMap(to_id, localID, bmap, bmap_len, trans_id);
|
130 |
} |
131 |
|
132 |
int sigInit(struct nodeID *myID, struct peerset *ps) |
133 |
{ |
134 |
localID = myID; |
135 |
pset = ps; |
136 |
return 1; |
137 |
} |