aboutsummaryrefslogtreecommitdiff
path: root/src/testbed
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-06-13 10:56:34 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-06-13 10:56:34 +0000
commitec56f91ac361b2a95d78e7529ed60549b7e9ddf3 (patch)
treeb0855ec7e121253457c980d2d91b4a56c6e5b34e /src/testbed
parentbd6e734d7d2a5472c959611d8aa452613f4f696b (diff)
downloadgnunet-ec56f91ac361b2a95d78e7529ed60549b7e9ddf3.tar.gz
gnunet-ec56f91ac361b2a95d78e7529ed60549b7e9ddf3.zip
-testbed controller startup
Diffstat (limited to 'src/testbed')
-rw-r--r--src/testbed/testbed_api.c236
-rw-r--r--src/testbed/testbed_api_hosts.c2
-rw-r--r--src/testbed/testbed_api_hosts.h2
3 files changed, 236 insertions, 4 deletions
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c
index 51680812b..f12ed64fc 100644
--- a/src/testbed/testbed_api.c
+++ b/src/testbed/testbed_api.c
@@ -32,8 +32,224 @@
32#include "gnunet_transport_service.h" 32#include "gnunet_transport_service.h"
33#include "gnunet_hello_lib.h" 33#include "gnunet_hello_lib.h"
34 34
35#include "testbed.h"
36#include "testbed_api_hosts.h"
35 37
36 38
39#define LOG(kind, ...) \
40 GNUNET_log_from (kind, "testbed-api", __VA_ARGS__);
41
42
43/**
44 * The message queue for sending messages to the controller service
45 */
46struct MessageQueue
47{
48 /**
49 * The message to be sent
50 */
51 struct GNUNET_MessageHeader *msg;
52
53 /**
54 * next pointer for DLL
55 */
56 struct MessageQueue *next;
57
58 /**
59 * prev pointer for DLL
60 */
61 struct MessageQueue *prev;
62};
63
64
65/**
66 * Handle to interact with a GNUnet testbed controller. Each
67 * controller has at least one master handle which is created when the
68 * controller is created; this master handle interacts with the
69 * controller process, destroying it destroys the controller (by
70 * closing stdin of the controller process). Additionally,
71 * controllers can interact with each other (in a P2P fashion); those
72 * links are established via TCP/IP on the controller's service port.
73 */
74struct GNUNET_TESTBED_Controller
75{
76
77 /**
78 * The host where the controller is running
79 */
80 const struct GNUNET_TESTBED_Host *host;
81
82 /**
83 * The helper handle
84 */
85 struct GNUNET_HELPER_Handle *h;
86
87 /**
88 * The controller callback
89 */
90 GNUNET_TESTBED_ControllerCallback cc;
91
92 /**
93 * The closure for controller callback
94 */
95 void *cc_cls;
96
97 /**
98 * The configuration to use while connecting to controller
99 */
100 struct GNUNET_CONFIGURATION_Handle *cfg;
101
102 /**
103 * The client connection handle to the controller service
104 */
105 struct GNUNET_CLIENT_Connection *client;
106
107 /**
108 * The head of the message queue
109 */
110 struct MessageQueue *mq_head;
111
112 /**
113 * The tail of the message queue
114 */
115 struct MessageQueue *mq_tail;
116
117 /**
118 * The client transmit handle
119 */
120 struct GNUNET_CLIENT_TransmitHandle *th;
121
122 /**
123 * The controller event mask
124 */
125 uint64_t event_mask;
126};
127
128
129/**
130 * Function called to notify a client about the connection begin ready to queue
131 * more data. "buf" will be NULL and "size" zero if the connection was closed
132 * for writing in the meantime.
133 *
134 * @param cls closure
135 * @param size number of bytes available in buf
136 * @param buf where the callee should write the message
137 * @return number of bytes written to buf
138 */
139static size_t
140transmit_ready_notify (void *cls, size_t size, void *buf)
141{
142 struct GNUNET_TESTBED_Controller *c = cls;
143 struct MessageQueue *mq_entry;
144
145 mq_entry = c->mq_head;
146 GNUNET_assert (NULL != mq_entry);
147 GNUNET_assert (ntohs (mq_entry->msg->size) <= size);
148 size = ntohs (mq_entry->msg->size);
149 memcpy (buf, mq_entry->msg, size);
150 GNUNET_free (mq_entry->msg);
151 GNUNET_CONTAINER_DLL_remove (c->mq_head, c->mq_tail, mq_entry);
152 GNUNET_free (mq_entry);
153 mq_entry = c->mq_head;
154 if (NULL != mq_entry)
155 c->th =
156 GNUNET_CLIENT_notify_transmit_ready (c->client,
157 ntohs (mq_entry->msg->size),
158 GNUNET_TIME_UNIT_FOREVER_REL,
159 GNUNET_NO, &transmit_ready_notify,
160 c);
161 return size;
162}
163
164
165/**
166 * Queues a message in send queue for sending to the service
167 *
168 * @param controller the handle to the controller
169 * @param msg the message to queue
170 */
171static void
172queue_message (struct GNUNET_TESTBED_Controller *controller,
173 struct GNUNET_MessageHeader *msg)
174{
175 struct MessageQueue *mq_entry;
176 uint16_t type;
177 uint16_t size;
178
179 type = ntohs (msg->type);
180 size = ntohs (msg->size);
181 GNUNET_assert ((GNUNET_MESSAGE_TYPE_TESTBED_INIT <= type) &&
182 (GNUNET_MESSAGE_TYPE_TESTBED_MAX > type));
183 mq_entry = GNUNET_malloc (sizeof (struct MessageQueue));
184 mq_entry->msg = msg;
185 LOG (GNUNET_ERROR_TYPE_DEBUG,
186 "Queueing message of type %u, size %u for sending\n", type,
187 ntohs (msg->size));
188 GNUNET_CONTAINER_DLL_insert_tail (controller->mq_head, controller->mq_tail,
189 mq_entry);
190 if (NULL == controller->th)
191 controller->th =
192 GNUNET_CLIENT_notify_transmit_ready (controller->client, size,
193 GNUNET_TIME_UNIT_FOREVER_REL,
194 GNUNET_NO, &transmit_ready_notify,
195 controller);
196 }
197
198
199/**
200 * Handler for messages from controller (testbed service)
201 *
202 * @param cls the controller handler
203 * @param msg message received, NULL on timeout or fatal error
204 */
205static void
206message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
207{
208 struct GNUNET_TESTBED_Controller *c = cls;
209
210 /* FIXME: Add checks for message integrity */
211 switch (ntohs (msg->type))
212 {
213 default:
214 GNUNET_break (0);
215 }
216 GNUNET_CLIENT_receive (c->client, &message_handler, c,
217 GNUNET_TIME_UNIT_FOREVER_REL);
218}
219
220
221/**
222 * ?Callback for messages recevied from server?
223 *
224 * Do not call GNUNET_SERVER_mst_destroy in callback
225 *
226 * @param cls closure
227 * @param client identification of the client
228 * @param message the actual message
229 *
230 * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
231 */
232static int
233server_mst_cb (void *cls, void *client,
234 const struct GNUNET_MessageHeader *message)
235{
236 struct GNUNET_TESTBED_Controller *c = cls;
237 struct GNUNET_TESTBED_Message *msg;
238
239 c->client = GNUNET_CLIENT_connect ("testbed", c->cfg);
240 if (NULL == c->client)
241 return GNUNET_SYSERR; /* FIXME: Call controller startup_cb ? */
242 GNUNET_CLIENT_receive (c->client, &message_handler, c,
243 GNUNET_TIME_UNIT_FOREVER_REL);
244 msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Message));
245 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_INIT);
246 msg->header.size = htons (sizeof (struct GNUNET_TESTBED_Message));
247 msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (c->host));
248 msg->event_mask = GNUNET_htonll (c->event_mask);
249 queue_message (c, (struct GNUNET_MessageHeader *) msg);
250 return GNUNET_OK;
251}
252
37 253
38/** 254/**
39 * Start a controller process using the given configuration at the 255 * Start a controller process using the given configuration at the
@@ -56,8 +272,24 @@ GNUNET_TESTBED_controller_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
56 GNUNET_TESTBED_ControllerCallback cc, 272 GNUNET_TESTBED_ControllerCallback cc,
57 void *cc_cls) 273 void *cc_cls)
58{ 274{
59 GNUNET_break (0); 275 struct GNUNET_TESTBED_Controller *controller;
60 return NULL; 276 char * binary_argv[] = {"gnunet-service-testbed",
277 "gnunet-service-testbed",
278 NULL};
279 controller = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Controller));
280 controller->h = GNUNET_TESTBED_host_run_ (host, binary_argv,
281 &server_mst_cb, controller);
282 if (NULL == controller->h)
283 {
284 GNUNET_free (controller);
285 return NULL;
286 }
287 controller->host = host;
288 controller->cc = cc;
289 controller->cc_cls = cc_cls;
290 controller->event_mask = event_mask;
291 controller->cfg = GNUNET_CONFIGURATION_dup (cfg);
292 return controller;
61} 293}
62 294
63 295
diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c
index 58866a45c..4af409af0 100644
--- a/src/testbed/testbed_api_hosts.c
+++ b/src/testbed/testbed_api_hosts.c
@@ -130,7 +130,7 @@ GNUNET_TESTBED_host_create_by_id_ (uint32_t id)
130 * 'localhost', but then obviously not globally unique) 130 * 'localhost', but then obviously not globally unique)
131 */ 131 */
132uint32_t 132uint32_t
133GNUNET_TESTBED_host_get_id_ (struct GNUNET_TESTBED_Host *host) 133GNUNET_TESTBED_host_get_id_ (const struct GNUNET_TESTBED_Host *host)
134{ 134{
135 return host->unique_id; 135 return host->unique_id;
136} 136}
diff --git a/src/testbed/testbed_api_hosts.h b/src/testbed/testbed_api_hosts.h
index 401d4e0d7..835866653 100644
--- a/src/testbed/testbed_api_hosts.h
+++ b/src/testbed/testbed_api_hosts.h
@@ -81,7 +81,7 @@ GNUNET_TESTBED_host_create_with_id_ (uint32_t id,
81 * 'localhost', but then obviously not globally unique) 81 * 'localhost', but then obviously not globally unique)
82 */ 82 */
83uint32_t 83uint32_t
84GNUNET_TESTBED_host_get_id_ (struct GNUNET_TESTBED_Host *host); 84GNUNET_TESTBED_host_get_id_ (const struct GNUNET_TESTBED_Host *host);
85 85
86 86
87/** 87/**