glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / testbed / testbed_api_underlay.c
1 /*
2   This file is part of GNUnet.
3   Copyright (C) 2008--2013 GNUnet e.V.
4
5   GNUnet is free software: you can redistribute it and/or modify it
6   under the terms of the GNU Affero General Public License as published
7   by the Free Software Foundation, either version 3 of the License,
8   or (at your option) any later version.
9
10   GNUnet is distributed in the hope that it will be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Affero General Public License for more details.
14 */
15
16 /**
17  * @file testbed/testbed_api_underlay.c
18  * @brief testbed underlay API implementation
19  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
20  */
21
22 #include "testbed_api_peers.h"
23
24
25 /**
26  * An underlay link
27  */
28 struct LinkProperty
29 {
30   /**
31    * next pointer for list
32    */
33   struct LinkProperty *next;
34
35   /**
36    * the peer whose link is defined by these properties
37    */
38   struct GNUNET_TESTBED_Peer *peer;
39
40   /**
41    * latency of the link in microseconds
42    */
43   uint32_t latency;
44
45   /**
46    * data loss on the link expressed as percentage
47    */
48   uint32_t loss;
49
50   /**
51    * bandwidth of the link in kilobytes per second
52    */
53   uint32_t bandwidth;
54 };
55
56
57 /**
58  * Container for holding a peer in whitelist/blacklist
59  */
60 struct ListEntry
61 {
62   /**
63    * the next pointer
64    */
65   struct ListEntry *next;
66
67   /**
68    * the peer
69    */
70   struct GNUNET_TESTBED_Peer *peer;
71 };
72
73
74 /**
75  * Model for configuring underlay links of a peer
76  * @ingroup underlay
77  */
78 struct GNUNET_TESTBED_UnderlayLinkModel
79 {
80   /**
81    * The peer associated with this model
82    */
83   struct GNUNET_TESTBED_Peer *peer;
84
85   /**
86    * List of peers in the list
87    */
88   struct ListEntry *entries;
89
90   /**
91    * list of link properties
92    */
93   struct LinkProperty *props;
94
95   /**
96    * the type of this model
97    */
98   enum GNUNET_TESTBED_UnderlayLinkModelType type;
99 }
100
101
102 /**
103  * Function to free resources of list entries
104  *
105  * @param model the model
106  */
107 static void
108 free_entries (struct GNUNET_TESTBED_UnderlayLinkModel *model)
109 {
110   struct ListEntry *e;
111
112   while (NULL != (e = model->entries))
113   {
114     model->entries = e->next;
115     GNUNET_free (e);
116   }
117 }
118
119
120 /**
121  * Function to free resources of link properties added to the given model
122  *
123  * @param model the model
124  */
125 static void
126 free_link_properties (struct GNUNET_TESTBED_UnderlayLinkModel *model)
127 {
128   struct LinkProperty *p;
129
130   while (NULL != (p = model->props))
131   {
132     model->props = p->next;
133     GNUNET_free (p);
134   }
135 }
136
137
138 /**
139  * Create a GNUNET_TESTBED_UnderlayLinkModel for the given peer.  A peer can
140  * have ONLY ONE model and it can be either a blacklist or whitelist based one.
141  *
142  * @ingroup underlay
143  * @param peer the peer for which the model has to be created
144  * @param type the type of the model
145  * @return the model
146  */
147 struct GNUNET_TESTBED_UnderlayLinkModel *
148 GNUNET_TESTBED_underlaylinkmodel_create (struct GNUNET_TESTBED_Peer *peer,
149                                          enum GNUNET_TESTBED_UnderlayLinkModelType type)
150 {
151   struct GNUNET_TESTBED_UnderlayLinkModel *m;
152
153   GNUNET_assert (0 == peer->underlay_model_exists);
154   m = GNUNET_new (struct GNUNET_TESTBED_UnderlayLinkModel);
155   peer->underlay_model_exists = 1;
156   m->type = type;
157   return m;
158 }
159
160
161 /**
162  * Add a peer to the given model.  Underlay connections to the given peer will
163  * be permitted if the model is whitelist based; otherwise they will not be
164  * permitted.
165  *
166  * @ingroup underlay
167  * @param model the model
168  * @param peer the peer to add
169  */
170 void
171 GNUNET_TESTBED_underlaylinkmodel_add_peer (struct GNUNET_TESTBED_UnderlayLinkModel *model,
172                                            struct GNUNET_TESTBED_Peer *peer)
173 {
174   struct ListEntry *entry;
175
176   entry = GNUNET_new (struct ListEntry);
177   entry->peer = peer;
178   entry->next = model->entries;
179   model->entries = entry;
180 }
181
182
183 /**
184  * Set the metrics for a link to the given peer in the underlay model.  The link
185  * SHOULD be permittable according to the given model.
186  *
187  * @ingroup underlay
188  * @param model the model
189  * @param peer the other end peer of the link
190  * @param latency latency of the link in microseconds
191  * @param loss data loss of the link expressed as a percentage
192  * @param bandwidth bandwidth of the link in kilobytes per second [kB/s]
193  */
194 void
195 GNUNET_TESTBED_underlaylinkmodel_set_link (struct GNUNET_TESTBED_UnderlayLinkModel *model,
196                                            struct GNUNET_TESTBED_Peer *peer,
197                                            uint32_t latency,
198                                            uint32_t loss,
199                                            uint32_t bandwidth)
200 {
201   struct LinkProperty *prop;
202
203   prop = GNUNET_new (struct LinkProperty);
204   prop->peer = peer;
205   prop->latency = latency;
206   prop->loss = loss;
207   prop->bandwidth = bandwidth;
208   prop->next = model->props;
209   model->props = prop;
210 }
211
212
213 /**
214  * Free the resources of the model.  Use this function only if the model has not
215  * be committed and has to be unallocated.  The peer can then have another model
216  * created.
217  *
218  * @ingroup underlay
219  * @param model the model to unallocate
220  */
221 void
222 GNUNET_TESTBED_underlaylinkmodel_free (struct GNUNET_TESTBED_UnderlayLinkModel *model)
223 {
224   model->peer->underlay_model_exists = 0;
225   free_entries (model);
226   free_link_properties (model);
227   gnunet_free (model);
228 }
229
230
231 /**
232  * Commit the model.  The model is freed in this function(!).
233  *
234  * @ingroup underlay
235  * @param model the model to commit
236  */
237 void
238 GNUNET_TESTBED_underlaylinkmodel_commit (struct GNUNET_TESTBED_UnderlayLinkModel *model)
239 {
240   /* FIXME: Marshal the model into a message */
241   GNUNET_break (0);
242   /* do not reset the value of model->peer->underlay_model_exists */
243   free_entries (model);
244   free_link_properties (model);
245   GNUNET_free (model);
246 }