aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-xdht_neighbours.c
diff options
context:
space:
mode:
authorSupriti Singh <supritisingh08@gmail.com>2014-03-28 10:24:39 +0000
committerSupriti Singh <supritisingh08@gmail.com>2014-03-28 10:24:39 +0000
commit8b570f0b07ba98e61a2523a4a3be768ba2ad22b5 (patch)
treed74b63d4279a327e6c7e9398ebc4c264e6755a56 /src/dht/gnunet-service-xdht_neighbours.c
parentf21600b4f3adcf4ef00fe4713fd81a8215972121 (diff)
downloadgnunet-8b570f0b07ba98e61a2523a4a3be768ba2ad22b5.tar.gz
gnunet-8b570f0b07ba98e61a2523a4a3be768ba2ad22b5.zip
Framework for put/get/monitor
Diffstat (limited to 'src/dht/gnunet-service-xdht_neighbours.c')
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c774
1 files changed, 578 insertions, 196 deletions
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 607cf3b43..4c290895b 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -51,7 +51,13 @@
51/* TODO: 51/* TODO:
52 1. Use a global array of all known peers in find_successor, Only when 52 1. Use a global array of all known peers in find_successor, Only when
53 a new peer is added in finger or friend peer map, then re calculate 53 a new peer is added in finger or friend peer map, then re calculate
54 the array. Or else use the old one. */ 54 the array. Or else use the old one.
55 2. Should we be using const in all the handle for the message we received
56 * and then copy the fields and make changes to the fields instead of sending
57 * them as they come.
58 * 3. Everywhere you are storing yourself as the first element in the trail.
59 * It is obviously taking too much space. Try to remove it and think of something
60 * better. */
55 61
56/** 62/**
57 * Maximum possible fingers of a peer. 63 * Maximum possible fingers of a peer.
@@ -78,6 +84,20 @@
78 */ 84 */
79#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) 85#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
80 86
87/**
88 * FIXME: Use this variable. Should it be moved to routing.c
89 * Threshold on routing table entries for a peer.
90 */
91#define ROUTING_TABLE_THRESHOLD 64
92
93/**
94 * FIXME: Use this variable. When adding an entry in finger table, check
95 * this threshold value. At the moment, its just a random value. Also,
96 * implement teardown feature from the paper.
97 * Threshold on number of peers in a trail length
98 */
99#define TRAIL_LENGTH_THRESHOLD 64
100
81 101
82GNUNET_NETWORK_STRUCT_BEGIN 102GNUNET_NETWORK_STRUCT_BEGIN
83 103
@@ -115,50 +135,66 @@ struct PeerPutMessage
115 * Length of the PUT path that follows (if tracked). 135 * Length of the PUT path that follows (if tracked).
116 */ 136 */
117 uint32_t put_path_length GNUNET_PACKED; 137 uint32_t put_path_length GNUNET_PACKED;
118 138
119 /** 139 /**
120 * When does the content expire? 140 * Source peer
121 */ 141 */
122 struct GNUNET_TIME_AbsoluteNBO expiration_time; 142 struct GNUNET_PeerIdentity source_peer;
143
144 /**
145 * Current destination
146 */
147 struct GNUNET_PeerIdentity current_destination;
148
149 /**
150 * Current destination type
151 */
152 enum current_destination_type current_destination_type;
123 153
124 /** 154 /**
125 * Bloomfilter (for peer identities) to stop circular routes 155 * When does the content expire?
126 */ 156 */
127 char bloomfilter[DHT_BLOOM_SIZE]; 157 struct GNUNET_TIME_AbsoluteNBO expiration_time;
128 158
129 /** 159 /**
130 * The key we are storing under. 160 * The key to store the value under.
131 */ 161 */
132 struct GNUNET_HashCode key; 162 struct GNUNET_HashCode key GNUNET_PACKED;
163
133 164
134 /* put path (if tracked) */ 165 /* put path (if tracked) */
135 166
136 /* Payload */ 167 /* Payload */
137 168
138}; 169};
139 170
140 171
141/** 172/**
142 * P2P Result message 173 * P2P Result message
143 */ 174 */
144struct PeerResultMessage 175struct PeerGetResultMessage
145{ 176{
146 /** 177 /**
147 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT 178 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT
148 */ 179 */
149 struct GNUNET_MessageHeader header; 180 struct GNUNET_MessageHeader header;
150 181
151 /** 182 /**
152 * Content type. 183 * Peer which is sending get result message.
153 */ 184 */
154 uint32_t type GNUNET_PACKED; 185 struct GNUNET_PeerIdentity source_peer;
155 186
156 /** 187 /**
157 * Length of the PUT path that follows (if tracked). 188 * Peer which will receive the get result message.
158 */ 189 */
159 uint32_t put_path_length GNUNET_PACKED; 190 struct GNUNET_PeerIdentity destination_peer;
160 191
161 /** 192 /**
193 * Current index in get path.
194 */
195 unsigned int current_path_index;
196
197 /**
162 * Length of the GET path that follows (if tracked). 198 * Length of the GET path that follows (if tracked).
163 */ 199 */
164 uint32_t get_path_length GNUNET_PACKED; 200 uint32_t get_path_length GNUNET_PACKED;
@@ -191,65 +227,43 @@ struct PeerGetMessage
191 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET 227 * Type: #GNUNET_MESSAGE_TYPE_DHT_P2P_GET
192 */ 228 */
193 struct GNUNET_MessageHeader header; 229 struct GNUNET_MessageHeader header;
194 230
195 /**
196 * Processing options
197 */
198 uint32_t options GNUNET_PACKED;
199
200 /**
201 * Desired content type.
202 */
203 uint32_t type GNUNET_PACKED;
204
205 /** 231 /**
206 * Hop count 232 * Source peer
207 */ 233 */
208 uint32_t hop_count GNUNET_PACKED; 234 struct GNUNET_PeerIdentity source_peer;
209 235
210 /** 236 /**
211 * Desired replication level for this request. 237 * Total number of peers in get path.
212 */ 238 */
213 uint32_t desired_replication_level GNUNET_PACKED; 239 unsigned int get_path_length;
214 240
215 /** 241 /**
216 * Size of the extended query. 242 *
217 */ 243 */
218 uint32_t xquery_size; 244 struct GNUNET_PeerIdentity current_destination;
219 245
220 /** 246 /**
221 * Bloomfilter mutator. 247 *
222 */ 248 */
223 uint32_t bf_mutator; 249 enum current_destination_type dest_type;
224 250
225 /** 251 /**
226 * Bloomfilter (for peer identities) to stop circular routes 252 * When does the content expire?
227 */ 253 */
228 char bloomfilter[DHT_BLOOM_SIZE]; 254 struct GNUNET_TIME_AbsoluteNBO expiration_time;
229 255
230 /** 256 /**
231 * The key we are looking for. 257 * The key we are looking for.
232 */ 258 */
233 struct GNUNET_HashCode key; 259 struct GNUNET_HashCode key;
260
261 /* Get path. */
234 262
235}; 263};
236 264
237 265
238/** 266/**
239 * FIXME: Change the comment to explain about usage of this in find successor.
240 * Field in trail setup message to understand if the message is sent to an
241 * intermediate finger, friend or me.
242 */
243enum current_destination_type
244{
245 FRIEND ,
246 FINGER ,
247 MY_ID ,
248 VALUE
249};
250
251
252/**
253 * P2P Trail setup message 267 * P2P Trail setup message
254 */ 268 */
255struct PeerTrailSetupMessage 269struct PeerTrailSetupMessage
@@ -1044,93 +1058,6 @@ GDS_NEIGHBOURS_send_notify_new_successor (struct GNUNET_PeerIdentity *source_pee
1044} 1058}
1045 1059
1046 1060
1047/**FIXME: Old implementation just to remove error
1048 * TODO: Modify this function to handle our get request.
1049 * Perform a GET operation. Forwards the given request to other
1050 * peers. Does not lookup the key locally. May do nothing if this is
1051 * the only peer in the network (or if we are the closest peer in the
1052 * network).
1053 *
1054 * @param type type of the block
1055 * @param options routing options
1056 * @param desired_replication_level desired replication count
1057 * @param hop_count how many hops did this request traverse so far?
1058 * @param key key for the content
1059 * @param xquery extended query
1060 * @param xquery_size number of bytes in @a xquery
1061 * @param reply_bf bloomfilter to filter duplicates
1062 * @param reply_bf_mutator mutator for @a reply_bf
1063 * @param peer_bf filter for peers not to select (again)
1064 */
1065void
1066GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type,
1067 enum GNUNET_DHT_RouteOption options,
1068 uint32_t desired_replication_level,
1069 uint32_t hop_count, const struct GNUNET_HashCode * key,
1070 const void *xquery, size_t xquery_size,
1071 const struct GNUNET_CONTAINER_BloomFilter *reply_bf,
1072 uint32_t reply_bf_mutator,
1073 struct GNUNET_CONTAINER_BloomFilter *peer_bf)
1074{
1075
1076 /*
1077 1. take the key, get the 64 bit value of the key.
1078 2. call find_successor to get the successor of the key.
1079 3. successor can be either a friend or finger.
1080 4. update the field in get message to reflect if its a friend or finger table
1081 5. add the put message to pending message and send it.
1082 */
1083
1084}
1085
1086/**FIXME: Old implementation just to remove error.
1087 * TODO: Modify this function to handle our put request.
1088 * Perform a PUT operation. Forwards the given request to other
1089 * peers. Does not store the data locally. Does not give the
1090 * data to local clients. May do nothing if this is the only
1091 * peer in the network (or if we are the closest peer in the
1092 * network).
1093 *
1094 * @param type type of the block
1095 * @param options routing options
1096 * @param desired_replication_level desired replication count
1097 * @param expiration_time when does the content expire
1098 * @param hop_count how many hops has this message traversed so far
1099 * @param bf Bloom filter of peers this PUT has already traversed
1100 * @param key key for the content
1101 * @param put_path_length number of entries in @a put_path
1102 * @param put_path peers this request has traversed so far (if tracked)
1103 * @param data payload to store
1104 * @param data_size number of bytes in @a data
1105 */
1106void
1107GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1108 enum GNUNET_DHT_RouteOption options,
1109 uint32_t desired_replication_level,
1110 struct GNUNET_TIME_Absolute expiration_time,
1111 uint32_t hop_count,
1112 struct GNUNET_CONTAINER_BloomFilter *bf,
1113 const struct GNUNET_HashCode *key,
1114 unsigned int put_path_length,
1115 struct GNUNET_PeerIdentity *put_path,
1116 const void *data, size_t data_size)
1117{
1118
1119 /*
1120 1. take the key, get the 64 bit value of the key.
1121 2. call find_successor to get the successor of the key.
1122 3. successor can be either a friend or finger.
1123 4. update the field in put message to reflect if its a friend or finger table
1124 5. add the put message to pending message and send it.
1125 */
1126 /* SUPU: Call is made to this function from client. It does not seem to be
1127 waiting for a confirmation So, once we got the request, we use the key and
1128 try to find the closest successor, but in this case when we reach to the
1129 closest successor in handle_dht_p2p_put, then just do datacache_put. As the calling
1130 function does not need any confirmation, we don't need the result back. */
1131}
1132
1133
1134/** 1061/**
1135 * Randomly choose one of your friends from the friends_peer map 1062 * Randomly choose one of your friends from the friends_peer map
1136 * @return Friend 1063 * @return Friend
@@ -1468,62 +1395,11 @@ core_init (void *cls,
1468 const struct GNUNET_PeerIdentity *identity) 1395 const struct GNUNET_PeerIdentity *identity)
1469{ 1396{
1470 my_identity = *identity; 1397 my_identity = *identity;
1471 1398
1472} 1399}
1473 1400
1474 1401
1475/**
1476 * Core handler for p2p put requests.
1477 *
1478 * @param cls closure
1479 * @param peer sender of the request
1480 * @param message message
1481 * @param peer peer identity this notification is about
1482 * @return #GNUNET_OK to keep the connection open,
1483 * #GNUNET_SYSERR to close it (signal serious error)
1484 */
1485static int
1486handle_dht_p2p_put (void *cls,
1487 const struct GNUNET_PeerIdentity *peer,
1488 const struct GNUNET_MessageHeader *message)
1489{
1490 /**
1491 1. Check if destination is friend or finger.
1492 2. If finger then get the next hop from routing table and
1493 * call GDS_NEGIHBOURS_handle_get.
1494 3. If friend then call find_successor to get the next hop and again
1495 * call GDS_NEIGHBOURS_handle_get to send to chosen hop.
1496 4. If you are the destination then do datacache_store.
1497 */
1498 return 0;
1499}
1500
1501 1402
1502/**
1503 * Core handler for p2p get requests.
1504 *
1505 * @param cls closure
1506 * @param peer sender of the request
1507 * @param message message
1508 * @return #GNUNET_OK to keep the connection open,
1509 * #GNUNET_SYSERR to close it (signal serious error)
1510 */
1511static int
1512handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
1513 const struct GNUNET_MessageHeader *message)
1514{
1515 /**
1516 1. Check if destination is friend or finger.
1517 2. If finger then get the next hop from routing table and
1518 * call GDS_NEGIHBOURS_handle_get.
1519 3. If friend then call find_successor to get the next hop and again
1520 * call GDS_NEIGHBOURS_handle_get to send to chosen hop.
1521 4. If you are the destination then send the data back to source peer
1522 * Assuming we have trail setup we can
1523 * either store the whole trail or again do the search process..
1524 */
1525 return 0;
1526}
1527 1403
1528 1404
1529/** 1405/**
@@ -1665,7 +1541,7 @@ compare_peer_id (const void *p1, const void *p2)
1665 1541
1666 1542
1667/** 1543/**
1668 * Return the previous element of value in all_known_peers. 1544 * Return the successor of value in all_known_peers.
1669 * @param all_known_peers list of all the peers 1545 * @param all_known_peers list of all the peers
1670 * @param value value we have to search in the all_known_peers. 1546 * @param value value we have to search in the all_known_peers.
1671 * @return 1547 * @return
@@ -1719,7 +1595,7 @@ find_closest_successor(struct Sorting_List *all_known_peers, uint64_t value,
1719 * @return Peer identity of next destination i.e. successor of value. 1595 * @return Peer identity of next destination i.e. successor of value.
1720 */ 1596 */
1721static struct GNUNET_PeerIdentity * 1597static struct GNUNET_PeerIdentity *
1722find_successor(uint64_t value, struct GNUNET_PeerIdentity *current_destination, 1598find_successor (uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1723 enum current_destination_type *type) 1599 enum current_destination_type *type)
1724{ 1600{
1725 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter; 1601 struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter;
@@ -1825,6 +1701,511 @@ find_successor(uint64_t value, struct GNUNET_PeerIdentity *current_destination,
1825 } 1701 }
1826} 1702}
1827 1703
1704#if 0
1705static void
1706replicate_put()
1707{
1708 /* In this function, you should find 'r' (r = desired replication level) successors
1709 and send put message to all of these r successors. Now, I really don't know
1710 if in case of node failure it will be able to find data. Or if we start with
1711 a random peer id, do we even reach to correct successor ever in case of
1712 get. */
1713}
1714#endif
1715
1716/**
1717 *
1718 * @param source_peer
1719 * @param get_path
1720 * @param get_path_length
1721 * @param key
1722 */
1723void
1724GDS_NEIGHBOURS_handle_get (struct GNUNET_PeerIdentity *source_peer,
1725 struct GNUNET_PeerIdentity *get_path,
1726 unsigned int get_path_length,
1727 struct GNUNET_HashCode *key,
1728 struct GNUNET_PeerIdentity *target_peer,
1729 struct GNUNET_PeerIdentity *current_destination,
1730 enum current_destination_type *type)
1731{
1732 struct PeerGetMessage *get_msg;
1733 struct P2PPendingMessage *pending;
1734 struct GNUNET_PeerIdentity *gp;
1735 struct FriendInfo *target_friend;
1736 uint64_t key_value;
1737 size_t msize;
1738
1739 msize = sizeof (struct PeerGetMessage) +
1740 (get_path_length * sizeof (struct GNUNET_PeerIdentity));
1741
1742 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1743 {
1744 GNUNET_break (0);
1745 return;
1746 }
1747
1748 memcpy (&key_value, key, sizeof (uint64_t));
1749
1750 if (NULL == target_peer)
1751 {
1752 /* This is the first call made from client file. */
1753 struct GNUNET_PeerIdentity *next_hop;
1754 next_hop = find_successor (key_value, current_destination, type);
1755
1756 if (*type == MY_ID)
1757 {
1758 struct GNUNET_PeerIdentity *destination_peer;
1759 int current_path_index;
1760
1761 /* FIXME: You enter in this part of code only if the call is made from the
1762 client file. And in client file you already have done the datacache_get.
1763 So, ideally you don't need it. Remove it after checking. */
1764 if (get_path_length != 1)
1765 current_path_index = get_path_length - 2;
1766 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
1767 memcpy (destination_peer, source_peer, sizeof (struct GNUNET_PeerIdentity));
1768 /* I am the final destination, then call GDS_NEIGHBOURS_send_get_result.*/
1769 GDS_NEIGHBOURS_send_get_result (&my_identity,get_path, get_path_length,
1770 destination_peer, current_path_index);
1771 return;
1772 }
1773 else
1774 {
1775 /* Find the friend corresponding to next_hop */
1776 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1777 }
1778 }
1779 else
1780 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, target_peer);
1781
1782 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1783 pending->importance = 0; /* FIXME */
1784 /* FIXME: Do we have an expiration time for get request */
1785 get_msg = (struct PeerGetMessage *) &pending[1];
1786 pending->msg = &get_msg->header;
1787 get_msg->header.size = htons (msize);
1788 get_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_GET);
1789 get_msg->get_path_length = htonl (get_path_length);
1790 get_msg->key = *key;
1791 memcpy (&(get_msg->source_peer), source_peer, sizeof (struct GNUNET_PeerIdentity));
1792 memcpy (&(get_msg->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
1793 get_msg->dest_type = htonl (*type);
1794
1795 gp = (struct GNUNET_PeerIdentity *) &get_msg[1];
1796 memcpy (gp, get_path, get_path_length * sizeof (struct GNUNET_PeerIdentity));
1797 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1798 target_friend->pending_count++;
1799 process_friend_queue (target_friend);
1800
1801}
1802
1803
1804/**
1805 * FIXME: In this function, you just find the target friend and send the message
1806 * to next peer. In handle_dht_p2p_put, you should check the options and type
1807 * and check if you are final destination or not. if not then find the next
1808 * destination and send the message forward.
1809 * @param type type of the block
1810 * @param options routing options
1811 * @param desired_replication_level desired replication count
1812 * @param expiration_time when does the content expire
1813 * @param hop_count how many hops has this message traversed so far
1814 * @param key key for the content
1815 * @param put_path_length number of entries in @a put_path
1816 * @param put_path peers this request has traversed so far (if tracked)
1817 * @param data payload to store
1818 * @param data_size number of bytes in @a data
1819 * @param current_destination
1820 * @param dest_type
1821 * @param target_peer_id
1822 */
1823void
1824GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1825 enum GNUNET_DHT_RouteOption options,
1826 uint32_t desired_replication_level,
1827 struct GNUNET_TIME_Absolute expiration_time,
1828 uint32_t hop_count,
1829 struct GNUNET_HashCode *key,
1830 unsigned int put_path_length,
1831 struct GNUNET_PeerIdentity *put_path,
1832 const void *data, size_t data_size,
1833 struct GNUNET_PeerIdentity *current_destination,
1834 enum current_destination_type *dest_type,
1835 struct GNUNET_PeerIdentity *target_peer)
1836{
1837 struct PeerPutMessage *ppm;
1838 struct P2PPendingMessage *pending;
1839 struct FriendInfo *target_friend;
1840 struct GNUNET_PeerIdentity *pp;
1841 size_t msize;
1842 uint64_t key_value;
1843
1844 msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size +
1845 sizeof (struct PeerPutMessage);
1846
1847 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1848 {
1849 put_path_length = 0;
1850 msize = data_size + sizeof (struct PeerPutMessage);
1851 }
1852
1853 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1854 {
1855 GNUNET_break (0);
1856 return;
1857 }
1858
1859 memcpy (&key_value, key, sizeof (uint64_t));
1860 if (target_peer == NULL)
1861 {
1862 /* This is the first time the call has been made from handle_dht_local_put.
1863 So, you need to search for the next peer to send this message to. */
1864 struct GNUNET_PeerIdentity *next_hop;
1865 next_hop = find_successor (key_value, current_destination, dest_type);
1866
1867 if (*dest_type == MY_ID)
1868 {
1869 /* FIXME: How do we handle different block types? */
1870 /* FIXME: Here depending on the replication level choose 'r' successors
1871 to this peer and send put to all of these peers. */
1872 //replicate_put();
1873 GDS_DATACACHE_handle_put (expiration_time, key, put_path_length, put_path,
1874 type, data_size, data);
1875 return;
1876 }
1877 else
1878 {
1879 /* Find the friend corresponding to next_hop */
1880 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop);
1881 }
1882 }
1883 else
1884 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, target_peer);
1885
1886 pending = GNUNET_malloc (sizeof (struct P2PPendingMessage) + msize);
1887 pending->importance = 0; /* FIXME */
1888 pending->timeout = expiration_time;
1889 ppm = (struct PeerPutMessage *) &pending[1];
1890 pending->msg = &ppm->header;
1891 ppm->header.size = htons (msize);
1892 ppm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_PUT);
1893 ppm->options = htonl (options);
1894 ppm->type = htonl (type);
1895 ppm->hop_count = htonl (hop_count + 1);
1896 ppm->desired_replication_level = htonl (desired_replication_level);
1897 ppm->put_path_length = htonl (put_path_length);
1898 ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time);
1899 memcpy (&(ppm->current_destination), current_destination, sizeof (struct GNUNET_PeerIdentity));
1900 ppm->current_destination_type = htonl (*dest_type);
1901 ppm->key = *key;
1902
1903 pp = (struct GNUNET_PeerIdentity *) &ppm[1];
1904 memcpy (pp, put_path,
1905 sizeof (struct GNUNET_PeerIdentity) * put_path_length);
1906 memcpy (&pp[put_path_length], data, data_size);
1907 GNUNET_CONTAINER_DLL_insert_tail (target_friend->head, target_friend->tail, pending);
1908 target_friend->pending_count++;
1909 process_friend_queue (target_friend);
1910}
1911
1912
1913/**
1914 *
1915 * @param source_peer
1916 * @param get_path
1917 * @param get_path_length
1918 * @param destination_peer
1919 */
1920void
1921GDS_NEIGHBOURS_send_get_result (struct GNUNET_PeerIdentity *source_peer,
1922 struct GNUNET_PeerIdentity *get_path,
1923 unsigned int get_path_length,
1924 struct GNUNET_PeerIdentity *destination_peer,
1925 unsigned int current_path_index)
1926{
1927 /* Add get_result into pending message and send the data to target friend. */
1928#if 0
1929 struct PeerGetResultMessage *get_result;
1930 struct P2PPendingMessage *pending;
1931 size_t msize;
1932
1933 msize = (get_path_length * sizeof (struct GNUNET_PeerIdentity)) +
1934 sizeof (struct PeerGetResultMessage);
1935
1936 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1937 {
1938 GNUNET_break (0);
1939 return;
1940 }
1941
1942#endif
1943}
1944
1945
1946/**
1947 *
1948 * @return
1949 */
1950static int
1951handle_dht_p2p_get_result ()
1952{
1953 /* If you are the source, go back to the client file and there search for
1954 the requesting client and send back the result. */
1955 return GNUNET_YES;
1956}
1957
1958
1959
1960/**
1961 * Core handler for p2p put requests.
1962 *
1963 * @param cls closure
1964 * @param peer sender of the request
1965 * @param message message
1966 * @param peer peer identity this notification is about
1967 * @return #GNUNET_OK to keep the connection open,
1968 * #GNUNET_SYSERR to close it (signal serious error)
1969 */
1970static int
1971handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer,
1972 const struct GNUNET_MessageHeader *message)
1973{
1974 struct PeerPutMessage *put;
1975 struct GNUNET_PeerIdentity *put_path;
1976 enum GNUNET_DHT_RouteOption options;
1977 enum current_destination_type current_dst_type;
1978 struct GNUNET_PeerIdentity *current_destination;
1979 struct GNUNET_PeerIdentity *source_peer;
1980 struct GNUNET_PeerIdentity *next_hop;
1981 struct GNUNET_HashCode test_key;
1982 uint64_t key_value;
1983 void *payload;
1984 size_t payload_size;
1985 size_t msize;
1986 uint32_t putlen;
1987
1988 msize = ntohs (message->size);
1989 if (msize < sizeof (struct PeerPutMessage))
1990 {
1991 GNUNET_break_op (0);
1992 return GNUNET_YES;
1993 }
1994
1995 put = (struct PeerPutMessage *) message;
1996 putlen = ntohl (put->put_path_length);
1997 if ((msize <
1998 sizeof (struct PeerPutMessage) +
1999 putlen * sizeof (struct GNUNET_PeerIdentity)) ||
2000 (putlen >
2001 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2002 {
2003 GNUNET_break_op (0);
2004 return GNUNET_YES;
2005 }
2006
2007 put_path = (struct GNUNET_PeerIdentity *) &put[1];
2008 payload = &put_path[putlen];
2009 options = ntohl (put->options);
2010 payload_size = msize - (sizeof (struct PeerPutMessage) +
2011 putlen * sizeof (struct GNUNET_PeerIdentity));
2012
2013 /* FIXME: I don't understand what exactly are we doing here. */
2014 switch (GNUNET_BLOCK_get_key
2015 (GDS_block_context, ntohl (put->type), payload, payload_size,
2016 &test_key))
2017 {
2018 case GNUNET_YES:
2019 if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode)))
2020 {
2021 char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key));
2022 GNUNET_break_op (0);
2023 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2024 "PUT with key `%s' for block with key %s\n",
2025 put_s, GNUNET_h2s_full (&test_key));
2026 GNUNET_free (put_s);
2027 return GNUNET_YES;
2028 }
2029 break;
2030 case GNUNET_NO:
2031 GNUNET_break_op (0);
2032 return GNUNET_YES;
2033 case GNUNET_SYSERR:
2034 /* cannot verify, good luck */
2035 break;
2036 }
2037
2038 /* FIXME: This part is also not clear to me.*/
2039 if (ntohl (put->type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */
2040 {
2041 switch (GNUNET_BLOCK_evaluate (GDS_block_context,
2042 ntohl (put->type),
2043 NULL, /* query */
2044 NULL, 0, /* bloom filer */
2045 NULL, 0, /* xquery */
2046 payload, payload_size))
2047 {
2048 case GNUNET_BLOCK_EVALUATION_OK_MORE:
2049 case GNUNET_BLOCK_EVALUATION_OK_LAST:
2050 break;
2051
2052 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
2053 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
2054 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
2055 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
2056 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
2057 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
2058 default:
2059 GNUNET_break_op (0);
2060 return GNUNET_OK;
2061 }
2062 }
2063
2064 struct GNUNET_PeerIdentity pp[putlen + 1];
2065
2066 /* extend 'put path' by sender */
2067 if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE))
2068 {
2069 memcpy (pp, put_path, putlen * sizeof (struct GNUNET_PeerIdentity));
2070 pp[putlen] = *peer;
2071 putlen++;
2072 }
2073 else
2074 putlen = 0;
2075
2076 /* Copy the fields of message, call find successor or gds_routing_search,
2077 depending on the destination_type and if you are the final destination,
2078 do a datache put or if option is. else call gds_neighbours_handle_get with
2079 correct parameters. */
2080 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2081 memcpy (current_destination, &(put->current_destination), sizeof (struct GNUNET_PeerIdentity));
2082 current_dst_type = ntohl (put->current_destination_type);
2083 memcpy (&key_value, &(put->key), sizeof (uint64_t));
2084 source_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2085 memcpy (source_peer, &(put->source_peer), sizeof (struct GNUNET_PeerIdentity));
2086
2087 if (current_dst_type == FRIEND)
2088 {
2089 next_hop = find_successor (key_value, current_destination, &current_dst_type);
2090 }
2091 else if (current_dst_type == FINGER)
2092 {
2093 next_hop = GDS_ROUTING_search (source_peer, current_destination);
2094 }
2095
2096 if (current_dst_type == MY_ID)
2097 {
2098 /* Here datacache_put*/
2099 /* FIXME: Here depending on replication, call replicate_put() to do the
2100 put operation on 'r' successors. */
2101 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
2102 &(put->key),putlen, pp, ntohl (put->type), payload_size,
2103 payload);
2104 return GNUNET_YES;
2105 }
2106 else
2107 {
2108 /* here call gds_neighbours*/
2109 GDS_NEIGHBOURS_handle_put (ntohl (put->type),ntohl (put->options),
2110 ntohl (put->desired_replication_level),
2111 GNUNET_TIME_absolute_ntoh (put->expiration_time),
2112 ntohl (put->hop_count),&put->key, putlen,
2113 pp, payload, payload_size,
2114 current_destination, &current_dst_type, next_hop);
2115 return GNUNET_YES;
2116 }
2117 return GNUNET_SYSERR;
2118}
2119
2120
2121/**
2122 * FIXME: Handle expiration, options, block type, replication
2123 * referring the old code.
2124 * Core handler for p2p get requests.
2125 *
2126 * @param cls closure
2127 * @param peer sender of the request
2128 * @param message message
2129 * @return #GNUNET_OK to keep the connection open,
2130 * #GNUNET_SYSERR to close it (signal serious error)
2131 */
2132static int
2133handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer,
2134 const struct GNUNET_MessageHeader *message)
2135{
2136 struct PeerGetMessage *get;
2137 struct GNUNET_PeerIdentity *current_destination;
2138 uint64_t key_value;
2139 enum current_destination_type dest_type;
2140 struct GNUNET_PeerIdentity *next_hop;
2141 struct GNUNET_PeerIdentity *get_path;
2142 size_t msize;
2143 unsigned int get_length;
2144
2145 msize = ntohs (message->size);
2146 if (msize < sizeof (struct PeerGetMessage))
2147 {
2148 GNUNET_break_op (0);
2149 return GNUNET_YES;
2150 }
2151
2152 get = (struct PeerGetMessage *)message;
2153 get_length = ntohl (get->get_path_length);
2154 get_path = (struct GNUNET_PeerIdentity *)&get[1];
2155
2156 if ((msize <
2157 sizeof (struct PeerGetMessage) +
2158 get_length * sizeof (struct GNUNET_PeerIdentity)) ||
2159 (get_length >
2160 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))
2161 {
2162 GNUNET_break_op (0);
2163 return GNUNET_YES;
2164 }
2165
2166 get = (struct PeerGetMessage *) message;
2167 current_destination = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2168 memcpy (current_destination, &(get->current_destination), sizeof (struct GNUNET_PeerIdentity));
2169 memcpy (&key_value, &(get->key), sizeof (uint64_t));
2170 dest_type = ntohl (get->dest_type);
2171
2172 if (dest_type == FRIEND)
2173 {
2174 next_hop = find_successor (key_value, current_destination, &dest_type);
2175 }
2176 else if (dest_type == FINGER)
2177 {
2178 next_hop = GDS_ROUTING_search (&(get->source_peer), current_destination);
2179 }
2180
2181 if (dest_type == MY_ID)
2182 {
2183 struct GNUNET_PeerIdentity *destination_peer;
2184 int current_path_index;
2185
2186 /* Add yourself to the get path, increment the get length. */
2187 destination_peer = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
2188 memcpy (destination_peer, &(get->source_peer), sizeof (struct GNUNET_PeerIdentity));
2189 current_path_index = get_length - 2;
2190
2191 /* I am the final destination. Call GDS_NEIGHBOURS_send_get_result. */
2192 GDS_NEIGHBOURS_send_get_result (&my_identity, get_path, get_length,
2193 destination_peer, current_path_index);
2194 return GNUNET_YES;
2195 }
2196 else
2197 {
2198 /* FIXME: Add your self to the get path and increment the get length. */
2199
2200 /* FIXME: Does it matter if the dest_type is friend or finger. */
2201 GDS_NEIGHBOURS_handle_get (&(get->source_peer), get_path, get_length, &(get->key),
2202 next_hop, current_destination,&dest_type);
2203
2204 return GNUNET_YES;
2205 }
2206 return GNUNET_SYSERR;
2207}
2208
1828 2209
1829/** 2210/**
1830 * Handle a PeerTrailSetupMessage. 2211 * Handle a PeerTrailSetupMessage.
@@ -2434,6 +2815,7 @@ GDS_NEIGHBOURS_init()
2434{ 2815{
2435 static struct GNUNET_CORE_MessageHandler core_handlers[] = { 2816 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
2436 {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0}, 2817 {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_P2P_GET, 0},
2818 {&handle_dht_p2p_get_result, GNUNET_MESSAGE_TYPE_DHT_P2P_GET_RESULT, 0},
2437 {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0}, 2819 {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_P2P_PUT, 0},
2438 {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0}, 2820 {&handle_dht_p2p_trail_setup, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP, 0},
2439 {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0}, 2821 {&handle_dht_p2p_trail_setup_result, GNUNET_MESSAGE_TYPE_DHT_P2P_TRAIL_SETUP_RESULT, 0},