more work on peer and paths structures
[oweals/gnunet.git] / src / cadet / gnunet-service-cadet-new_paths.c
1
2 /*
3      This file is part of GNUnet.
4      Copyright (C) 2001-2017 GNUnet e.V.
5
6      GNUnet is free software; you can redistribute it and/or modify
7      it under the terms of the GNU General Public License as published
8      by the Free Software Foundation; either version 3, or (at your
9      option) any later version.
10
11      GNUnet is distributed in the hope that it will be useful, but
12      WITHOUT ANY WARRANTY; without even the implied warranty of
13      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14      General Public License for more details.
15
16      You should have received a copy of the GNU General Public License
17      along with GNUnet; see the file COPYING.  If not, write to the
18      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19      Boston, MA 02110-1301, USA.
20 */
21
22 /**
23  * @file cadet/gnunet-service-cadet-new_paths.c
24  * @brief Information we track per path.
25  * @author Bartlomiej Polot
26  * @author Christian Grothoff
27  */
28 #include "platform.h"
29 #include "gnunet-service-cadet-new_peer.h"
30 #include "gnunet-service-cadet-new_paths.h"
31
32
33 /**
34  * Information regarding a possible path to reach a peer.
35  */
36 struct CadetPeerPath
37 {
38
39   /**
40    * Array of all the peers on the path.  If @e hn is non-NULL, the
41    * last one is our owner.
42    */
43   struct CadetPeerPathEntry *entries;
44
45   /**
46    * Node of this path in the owner's heap.  Used to update our position
47    * in the heap whenever our @e desirability changes.
48    */
49   struct GNUNET_CONTAINER_HeapNode *hn;
50
51   /**
52    * Connections using this path, by destination peer
53    * (each hop of the path could correspond to an
54    * active connection).
55    */
56   struct GNUNET_CONTAINER_MultiPeerMap *connections;
57
58   /**
59    * Desirability of the path. How unique is it for the various peers
60    * on it?
61    */
62   GNUNET_CONTAINER_HeapCostType desirability;
63
64   /**
65    * Length of the @e entries array.
66    */
67   unsigned int entries_length;
68
69 };
70
71
72
73 /**
74  * Return how much we like keeping the path.  This is an aggregate
75  * score based on various factors, including the age of the path
76  * (older == better), and the value of this path to all of its ajacent
77  * peers.  For example, long paths that end at a peer that we have no
78  * shorter way to reach are very desirable, while long paths that end
79  * at a peer for which we have a shorter way as well are much less
80  * desirable.  Higher values indicate more valuable paths.  The
81  * returned value should be used to decide which paths to remember.
82  *
83  * @param path path to return the length for
84  * @return desirability of the path, larger is more desirable
85  */
86 GNUNET_CONTAINER_HeapCostType
87 GCPP_get_desirability (const struct CadetPeerPath *path)
88 {
89   GNUNET_assert (0);
90   return 0;
91 }
92
93
94 /**
95  * The given peer @a cp used to own this @a path.  However, it is no
96  * longer interested in maintaining it, so the path should be
97  * discarded or shortened (in case a previous peer on the path finds
98  * the path desirable).
99  *
100  * @param path the path that is being released
101  * @param cp original final destination of @a path
102  * @param node entry in the heap of @a cp where this path is anchored
103  *             should be used for updates to the desirability of this path
104  */
105 void
106 GCPP_acquire (struct CadetPeerPath *path,
107               struct CadetPeer *cp,
108               struct GNUNET_CONTAINER_HeapNode *node)
109 {
110   GNUNET_assert (0);
111 }
112
113
114 /**
115  * The owning peer of this path is no longer interested in maintaining
116  * it, so the path should be discarded or shortened (in case a
117  * previous peer on the path finds the path desirable).
118  *
119  * @param path the path that is being released
120  */
121 void
122 GCPP_release (struct CadetPeerPath *path)
123 {
124   GNUNET_assert (0);
125 }
126
127
128 /**
129  * Updates the score for an entry on the path based
130  * on our experiences with using @a path.
131  *
132  * @param path the path to update
133  * @param off offset of the entry to update
134  * @param delta change in the score to apply
135  */
136 void
137 GCPP_update_score (struct CadetPeerPath *path,
138                    unsigned int off,
139                    int delta)
140 {
141   struct CadetPeerPathEntry *entry;
142
143   GNUNET_assert (off < path->entries_length);
144   entry = &path->entries[off];
145
146   /* Add delta, with checks for overflows */
147   if (delta >= 0)
148   {
149     if (delta + entry->score < entry->score)
150       entry->score = INT_MAX;
151     else
152       entry->score += delta;
153   }
154   else
155   {
156     if (delta + entry->score > entry->score)
157       entry->score = INT_MIN;
158     else
159       entry->score += delta;
160   }
161
162   /* FIXME: update path desirability! */
163 }
164
165
166 /**
167  * Create a peer path based on the result of a DHT lookup.
168  *
169  * @param get_path path of the get request
170  * @param get_path_length lenght of @a get_path
171  * @param put_path path of the put request
172  * @param put_path_length length of the @a put_path
173  * @return a path through the network
174  */
175 struct CadetPeerPath *
176 GCPP_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
177                     unsigned int get_path_length,
178                     const struct GNUNET_PeerIdentity *put_path,
179                     unsigned int put_path_length)
180 {
181   struct CadetPeerPath *path;
182
183   path = GNUNET_new (struct CadetPeerPath);
184   path->entries_length = get_path_length + put_path_length;
185   path->entries = GNUNET_new_array (path->entries_length,
186                                     struct CadetPeerPathEntry);
187   for (unsigned int i=0;i<get_path_length + put_path_length;i++)
188   {
189     struct CadetPeerPathEntry *entry = &path->entries[i];
190     const struct GNUNET_PeerIdentity *pid;
191
192     pid = (i < get_path_length) ? &get_path[get_path_length - i] : &put_path[path->entries_length - i];
193     entry->peer = GCP_get (pid,
194                            GNUNET_YES);
195     entry->path = path;
196     GCP_path_entry_add (entry->peer,
197                         entry,
198                         i);
199   }
200   GNUNET_break (0);
201   return NULL;
202 }
203
204
205 /**
206  * Destroy a path, we no longer need it.
207  *
208  * @param p path to destroy.
209  */
210 void
211 GCPP_path_destroy (struct CadetPeerPath *p)
212 {
213   GNUNET_assert (0);
214 }
215
216
217 /**
218  * Return the length of the path.  Excludes one end of the
219  * path, so the loopback path has length 0.
220  *
221  * @param path path to return the length for
222  * @return number of peers on the path
223  */
224 unsigned int
225 GCPP_get_length (struct CadetPeerPath *path)
226 {
227   GNUNET_assert (0);
228   return -1;
229 }
230
231
232 /**
233  * Obtain the identity of the peer at offset @a off in @a path.
234  *
235  * @param path peer path to inspect
236  * @param off offset to return, must be smaller than path length
237  * @param[out] pid where to write the pid, must not be NULL
238  */
239 void
240 GCPP_get_pid_at_offset (struct CadetPeerPath *path,
241                         unsigned int off,
242                         struct GNUNET_PeerIdentity *pid)
243 {
244   GNUNET_assert (0);
245 }
246
247
248 /* end of gnunet-service-cadet-new_paths.c */