Statistics
| Branch: | Revision:

grapes / som / ChunkTrading / chunk_signalling.c @ a2859bcd

History | View | Annotate | Download (9.54 KB)

1
/*
2
 *  Copyright (c) 2009 Alessandro Russo.
3
 *
4
 *  This is free software;
5
 *  see lgpl-2.1.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 <stdio.h>
15
#include <stdint.h>
16
#include <string.h>
17
#include <stdlib.h>
18
#include "chunk.h"
19
#include "chunkidset.h"
20
#include "msg_types.h"
21
#include "trade_sig_la.h"
22
#include "trade_sig_ha.h"
23

    
24
//Type of signaling message
25
//Request a ChunkIDSet
26
#define MSG_SIG_REQ 0
27
//Diliver a ChunkIDSet (reply to a request)
28
#define MSG_SIG_DEL 1
29
//Offer a ChunkIDSet
30
#define MSG_SIG_OFF 2
31
//Accept a ChunkIDSet (reply to an offer)
32
#define MSG_SIG_ACC 3
33
//Receive the BufferMap
34
#define MSG_SIG_BMOFF 4
35
//Request the BufferMap
36
#define MSG_SIG_BMREQ 5
37

    
38
struct sig_nal {
39
    uint8_t type;//type of signal.
40
    uint8_t max_deliver;//Max number of chunks to deliver.
41
    uint16_t cb_size;
42
    uint16_t trans_id;//future use...
43
    uint8_t third_peer;//for buffer map exchange from other peers, just the first byte!
44
} __attribute__((packed));
45

    
46
//set the local node ID
47
static struct nodeID *localID;
48

    
49
int chunkSignalingInit(struct nodeID *myID) {
50
    if(!myID)
51
        return -1;
52
    localID = myID;
53
    return 1;
54
}
55

    
56
int sendSignalling(int type, struct nodeID *to_id, const struct nodeID *owner_id, struct chunkID_set *cset, int max_deliver, int cb_size, int trans_id)
57
{
58
    int buff_len, meta_len, msg_len, ret;
59
    uint8_t *buff;
60
    struct sig_nal *sigmex;
61
    uint8_t *meta;
62
    ret = 1;
63
    meta = malloc(1024);
64

    
65
    sigmex = (struct sig_nal*) meta;
66
    sigmex->type = type;
67
    sigmex->max_deliver = max_deliver;
68
    sigmex->cb_size = cb_size;
69
    sigmex->trans_id = trans_id;
70
    meta_len = sizeof(*sigmex)-1;
71
      sigmex->third_peer = 0;
72
    if (owner_id) {
73
      meta_len += nodeid_dump(&sigmex->third_peer, owner_id);
74
    }
75

    
76
    buff_len = 1 + chunkID_set_size(cset) * 4 + 16 + meta_len; // this should be enough
77
    buff = malloc(buff_len);
78
    if (!buff) {
79
      fprintf(stderr, "Error allocating buffer\n");
80
      return -1;
81
    }
82

    
83
    buff[0] = MSG_TYPE_SIGNALLING;
84
    msg_len = 1 + encodeChunkSignaling(cset, meta, meta_len, buff+1, buff_len-1);
85
    free(meta);
86
    if (msg_len <= 0) {
87
      fprintf(stderr, "Error in encoding chunk set for sending a buffermap\n");
88
      ret = -1;
89
    } else {
90
      send_to_peer(localID, to_id, buff, msg_len);
91
    }    
92
    free(buff);
93
    return ret;
94
}
95

    
96
/**
97
 * Request a (sub)set of chunks from a Peer.
98
 *
99
 * Initiate a request for a set of Chunks towards a Peer, and specify the  maximum number of Chunks attempted to deliver
100
 * (attempted to deliver: i.e. the destination peer would like to receive at most this number of Chunks from the set)
101
 *
102
 * @param[in] to target peer to request the ChunkIDs from
103
 * @param[in] cset array of ChunkIDs
104
 * @param[in] cset_len length of the ChunkID set
105
 * @param[in] max_deliver deliver at most this number of Chunks
106
 * @param[in] trans_id transaction number associated with this request
107
 * @return 1 on success, 0 no chunks, <0 on error,
108
 *//*
109
int requestChunks(const struct nodeID *to, const ChunkIDSet *cset, int cset_len, int max_deliver, int trans_id) {
110
    int buff_len;
111
    int res;
112
    uint8_t *buff;
113
    struct sig_nal *sigmex;
114
    sigmex = malloc(sizeof(struct sig_nal));
115
    sigmex->type = MSG_SIG_REQ;
116
    sigmex->max_deliver = max_deliver;
117
    sigmex->trans_id = trans_id;
118
    fprintf(stdout, "SIG_HEADER: Type %d Tx %d PP %d\n", sigmex->type, sigmex->trans_id, sigmex->third_peer);
119
    buff_len = cset_len * 4 + 12 + sizeof(struct sig_nal); // Signaling type + set len
120
    buff = malloc(buff_len + 1);    
121
    res = encodeChunkSignaling(cset, sigmex, sizeof(struct sig_nal), buff+1, buff_len);
122
    if (res < 0) {
123
        fprintf(stderr, "Error in encoding chunk set for chunks request\n");
124
        return -1;
125
    } else {
126
        buff[0] = MSG_TYPE_SIGNALLING; //the message type is CHUNK
127
        res = send_to_peer(localID, to, buff, buff_len + 1); //actual send chunk
128
        free(buff); //free memory allocated for the buffer
129
        free(sigmex);
130
    }
131
    return (1);
132
}
133

134
*/
135
/**
136
 * Deliver a set of Chunks to a Peer as a reply of its previous request of Chunks
137
 *
138
 * Announce to the Peer which sent a request of a set of Chunks, that we have these chunks (sub)set available
139
 * among all those requested and willing to deliver them.
140
 *
141
 * @param[in] to target peer to which deliver the ChunkIDs
142
 * @param[in] cset array of ChunkIDs
143
 * @param[in] cset_len length of the ChunkID set
144
 * @param[in] max_deliver we are able to deliver at most this many from the set
145
 * @param[in] trans_id transaction number associated with this request
146
 * @return 1 on success, <0 on error
147
 *//*
148

149
int deliverChunks(const struct nodeID *to, ChunkIDSet *cset, int cset_len, int max_deliver, int trans_id) {
150
    int buff_len;
151
    int res;
152
    uint8_t *buff;
153
    struct sig_nal *sigmex;
154
    sigmex = malloc(sizeof(struct sig_nal));
155
    sigmex->type = MSG_SIG_DEL;
156
    sigmex->max_deliver = max_deliver;
157
    sigmex->trans_id = trans_id;
158
    fprintf(stdout, "SIG_HEADER: Type %d Tx %d PP %d\n", sigmex->type, sigmex->trans_id, sigmex->third_peer);
159
    buff_len = cset_len * 4 + 12 + sizeof(struct sig_nal); // Signaling type + set len
160
    buff = malloc(buff_len + 1);
161
    res = encodeChunkSignaling(cset, sigmex, sizeof(struct sig_nal), buff+1, buff_len);
162
    if (res < 0) {
163
        fprintf(stderr, "Error in encoding chunk set for chunks request\n");
164
        return -1;
165
    } else {
166
        buff[0] = MSG_TYPE_SIGNALLING; //the message type is CHUNK
167
        res = send_to_peer(localID, to, buff, buff_len + 1); //actual send chunk
168
        free(buff); //free memory allocated for the buffer
169
        free(sigmex);
170
    }
171
    return 1;
172
}
173
*/
174

    
175
/**
176
 * Offer a (sub)set of chunks to a Peer.
177
 *
178
 * Initiate a offer for a set of Chunks towards a Peer, and specify the  maximum number of Chunks attempted to deliver
179
 * (attempted to deliver: i.e. the sender peer should try to send at most this number of Chunks from the set)
180
 *
181
 * @param[in] to target peer to offer the ChunkIDs
182
 * @param[in] cset array of ChunkIDs
183
 * @param[in] cset_len length of the ChunkID set
184
 * @param[in] max_deliver deliver at most this number of Chunks
185
 * @param[in] trans_id transaction number associated with this request
186
 * @return 1 on success, <0 on error
187
 */
188

    
189
int offerChunks(struct nodeID *to, struct chunkID_set *cset, int max_deliver, int trans_id)
190
{
191
  return sendSignalling(MSG_SIG_OFF, to, NULL, cset, max_deliver, -1, trans_id);
192
}
193

    
194
/**
195
 * Accept a (sub)set of chunks from a Peer.
196
 *
197
 * Announce to accept a (sub)set of Chunks from a Peer which sent a offer before, and specify the  maximum number of Chunks attempted to receive
198
 * (attempted to receive: i.e. the receiver peer would like to receive at most this number of Chunks from the set offerd before)
199
 *
200
 * @param[in] to target peer to accept the ChunkIDs
201
 * @param[in] cset array of ChunkIDs
202
 * @param[in] max_deliver accept at most this number of Chunks
203
 * @param[in] trans_id transaction number associated with this request
204
 * @return 1 on success, <0 on error
205
 */
206
int acceptChunks(struct nodeID *to, struct chunkID_set *cset, int max_deliver, int trans_id) {
207
  return sendSignalling(MSG_SIG_ACC, to, NULL, cset, max_deliver, -1, trans_id);
208
}
209

    
210
/**
211
 * Send a BufferMap to a Peer.
212
 *
213
 * Send (our own or some other peer's) BufferMap to a third Peer.
214
 *
215
 * @param[in] to PeerID.
216
 * @param[in] owner Owner of the BufferMap to send.
217
 * @param[in] bmap the BufferMap to send.
218
 * @param[in] bmap_len length of the buffer map
219
 * @param[in] trans_id transaction number associated with this send
220
 * @return 1 on success, <0 on error
221
 */
222
int sendBufferMap(struct nodeID *to, const struct nodeID *owner_id, struct chunkID_set *bmap, int bmap_len, int trans_id) {
223
  return sendSignalling(MSG_SIG_BMOFF, to, (!owner_id?localID:owner_id), bmap, 0, bmap_len, trans_id);//owner NULL -> my buffermap
224
}
225

    
226

    
227
/**
228
 * Request a BufferMap to a Peer.
229
 *
230
 * Request (target peer or some other peer's) BufferMap to target Peer.
231
 *
232
 * @param[in] to PeerID.
233
 * @param[in] owner Owner of the BufferMap to request.
234
 * @param[in] trans_id transaction number associated with this request
235
 * @return 1 on success, <0 on error
236
 */
237
//TODO Receive would require a buffer map from a given chunk, with a given length
238
/*
239
int requestBufferMap(const struct nodeID *to, const struct nodeID *owner, int trans_id) {
240
    int buff_len;
241
    int res;
242
    uint8_t *buff;
243
    struct sig_nal *sigmex;
244
    sigmex = malloc(sizeof(struct sig_nal));
245
    sigmex->type = MSG_SIG_BMREQ;
246
    sigmex->trans_id = trans_id;         
247
    //sigmex->third_peer->fd = owner->fd ;
248
    //sigmex->third_peer->refcnt = owner->refcnt ;
249
    //socklen_t raddr_size = sizeof(struct sockaddr_in);
250
    //memcpy(&sigmex->third_peer->addr,&owner->addr, raddr_size);
251
     
252
    fprintf(stdout, "SIG_HEADER: Type %d Tx %d\n", sigmex->type, sigmex->trans_id);
253
    buff_len = 12 + sizeof(struct sig_nal);
254
    buff = malloc(buff_len + 1);
255
    ChunkIDSet *bmap;
256
    bmap = chunkID_set_init(0);
257
    res = encodeChunkSignaling(bmap, sigmex, sizeof(struct sig_nal), buff, buff_len);
258
    if (res < 0) {
259
        fprintf(stderr, "Error in encoding chunk set for chunks request\n");
260
        return -1;
261
    } else {
262
        buff[0] = MSG_TYPE_SIGNALLING; //the message type is CHUNK
263
        res = send_to_peer(localID, to, buff, buff_len + 1); //actual send chunk
264
        free(buff); //free memory allocated for the buffer
265
        free(sigmex);
266
    }
267
    return 1;
268
}*/