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