aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-09-15 09:31:18 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-09-15 09:31:18 +0000
commitc2a2296221c174ae68fb82f3373a5594391474cb (patch)
tree53a284d9e0fcb274712f3d551bcdb00c1223d062 /src
parentd0cdb1cc4a8d030fd106475e1bbc520c7486fc24 (diff)
downloadgnunet-c2a2296221c174ae68fb82f3373a5594391474cb.tar.gz
gnunet-c2a2296221c174ae68fb82f3373a5594391474cb.zip
more functionality
Diffstat (limited to 'src')
-rw-r--r--src/transport/plugin_transport_http.h10
-rw-r--r--src/transport/plugin_transport_http_client.c125
-rw-r--r--src/transport/plugin_transport_http_new.c26
-rw-r--r--src/transport/plugin_transport_http_server.c151
4 files changed, 305 insertions, 7 deletions
diff --git a/src/transport/plugin_transport_http.h b/src/transport/plugin_transport_http.h
index 84af33a59..3cba2ace0 100644
--- a/src/transport/plugin_transport_http.h
+++ b/src/transport/plugin_transport_http.h
@@ -114,13 +114,21 @@ struct Plugin
114 114
115 int max_connections; 115 int max_connections;
116 116
117
118 /* Plugin values */
119
120
121 int cur_connections;
122
117 /* 123 /*
118 * Server handles 124 * Server handles
119 */ 125 */
120 126
121 struct MHD_Daemon *server_v4; 127 struct MHD_Daemon *server_v4;
128 GNUNET_SCHEDULER_TaskIdentifier server_v4_task;
122 129
123 struct MHD_Daemon *server_v6; 130 struct MHD_Daemon *server_v6;
131 GNUNET_SCHEDULER_TaskIdentifier server_v6_task;
124 132
125 char *crypto_init; 133 char *crypto_init;
126 char *key; 134 char *key;
@@ -135,6 +143,8 @@ struct Plugin
135 */ 143 */
136 CURLM *client_mh; 144 CURLM *client_mh;
137 145
146 GNUNET_SCHEDULER_TaskIdentifier client_perform_task;
147
138}; 148};
139 149
140/** 150/**
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c
index 9a5d4b261..41300285a 100644
--- a/src/transport/plugin_transport_http_client.c
+++ b/src/transport/plugin_transport_http_client.c
@@ -96,6 +96,116 @@ client_send (struct Session *s, const char *msgbuf, size_t msgbuf_size)
96 return GNUNET_OK; 96 return GNUNET_OK;
97} 97}
98 98
99/**
100 * Task performing curl operations
101 * @param cls plugin as closure
102 * @param tc gnunet scheduler task context
103 */
104static void
105client_perform (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
106
107/**
108 * Function setting up file descriptors and scheduling task to run
109 *
110 * @param plugin plugin as closure
111 * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok
112 */
113static int
114client_schedule_next_perform (struct Plugin *plugin)
115{
116 fd_set rs;
117 fd_set ws;
118 fd_set es;
119 int max;
120 struct GNUNET_NETWORK_FDSet *grs;
121 struct GNUNET_NETWORK_FDSet *gws;
122 long to;
123 CURLMcode mret;
124 struct GNUNET_TIME_Relative timeout;
125
126 /* Cancel previous scheduled task */
127 if (plugin->client_perform_task!= GNUNET_SCHEDULER_NO_TASK)
128 {
129 GNUNET_SCHEDULER_cancel (plugin->client_perform_task);
130 plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK;
131 }
132
133 max = -1;
134 FD_ZERO (&rs);
135 FD_ZERO (&ws);
136 FD_ZERO (&es);
137 mret = curl_multi_fdset (plugin->client_mh, &rs, &ws, &es, &max);
138 if (mret != CURLM_OK)
139 {
140 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
141 "curl_multi_fdset", __FILE__, __LINE__,
142 curl_multi_strerror (mret));
143 return GNUNET_SYSERR;
144 }
145 mret = curl_multi_timeout (plugin->client_mh, &to);
146 if (to == -1)
147 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5);
148 else
149 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to);
150 if (mret != CURLM_OK)
151 {
152 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
153 "curl_multi_timeout", __FILE__, __LINE__,
154 curl_multi_strerror (mret));
155 return GNUNET_SYSERR;
156 }
157
158 grs = GNUNET_NETWORK_fdset_create ();
159 gws = GNUNET_NETWORK_fdset_create ();
160 GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
161 GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
162 plugin->client_perform_task =
163 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
164 GNUNET_SCHEDULER_NO_TASK,
165 timeout,
166 grs,
167 gws,
168 &client_perform,
169 plugin);
170 GNUNET_NETWORK_fdset_destroy (gws);
171 GNUNET_NETWORK_fdset_destroy (grs);
172 return GNUNET_OK;
173}
174
175
176/**
177 * Task performing curl operations
178 * @param cls plugin as closure
179 * @param tc gnunet scheduler task context
180 */
181static void
182client_perform (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
183{
184 struct Plugin *plugin = cls;
185 static unsigned int handles_last_run;
186 int running;
187 CURLMcode mret;
188
189 GNUNET_assert (cls != NULL);
190
191 plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK;
192 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
193 return;
194 do
195 {
196 running = 0;
197 mret = curl_multi_perform (plugin->client_mh, &running);
198 if ((running < handles_last_run) && (running > 0))
199 {
200
201 }
202 //curl_handle_finished (plugin);
203 handles_last_run = running;
204 }
205 while (mret == CURLM_CALL_MULTI_PERFORM);
206 client_schedule_next_perform (plugin);
207}
208
99int 209int
100client_connect (struct Session *s) 210client_connect (struct Session *s)
101{ 211{
@@ -138,10 +248,10 @@ client_connect (struct Session *s)
138 //curl_easy_setopt (s->client_get, CURLOPT_READDATA, ps); 248 //curl_easy_setopt (s->client_get, CURLOPT_READDATA, ps);
139 //curl_easy_setopt (s->client_get, CURLOPT_WRITEFUNCTION, curl_receive_cb); 249 //curl_easy_setopt (s->client_get, CURLOPT_WRITEFUNCTION, curl_receive_cb);
140 //curl_easy_setopt (s->client_get, CURLOPT_WRITEDATA, ps); 250 //curl_easy_setopt (s->client_get, CURLOPT_WRITEDATA, ps);
141 curl_easy_setopt (s->client_get, CURLOPT_TIMEOUT, 251 curl_easy_setopt (s->client_get, CURLOPT_TIMEOUT_MS,
142 (long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); 252 (long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value);
143 //curl_easy_setopt (s->client_get, CURLOPT_PRIVATE, ps); 253 //curl_easy_setopt (s->client_get, CURLOPT_PRIVATE, ps);
144 curl_easy_setopt (s->client_get, CURLOPT_CONNECTTIMEOUT, 254 curl_easy_setopt (s->client_get, CURLOPT_CONNECTTIMEOUT_MS,
145 (long) HTTP_NOT_VALIDATED_TIMEOUT.rel_value); 255 (long) HTTP_NOT_VALIDATED_TIMEOUT.rel_value);
146 curl_easy_setopt (s->client_get, CURLOPT_BUFFERSIZE, 256 curl_easy_setopt (s->client_get, CURLOPT_BUFFERSIZE,
147 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); 257 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE);
@@ -169,10 +279,10 @@ client_connect (struct Session *s)
169 //curl_easy_setopt (s->client_put, CURLOPT_READDATA, ps); 279 //curl_easy_setopt (s->client_put, CURLOPT_READDATA, ps);
170 //curl_easy_setopt (s->client_put, CURLOPT_WRITEFUNCTION, curl_receive_cb); 280 //curl_easy_setopt (s->client_put, CURLOPT_WRITEFUNCTION, curl_receive_cb);
171 //curl_easy_setopt (s->client_put, CURLOPT_WRITEDATA, ps); 281 //curl_easy_setopt (s->client_put, CURLOPT_WRITEDATA, ps);
172 curl_easy_setopt (s->client_put, CURLOPT_TIMEOUT, 282 curl_easy_setopt (s->client_put, CURLOPT_TIMEOUT_MS,
173 (long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); 283 (long) GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value);
174 //curl_easy_setopt (s->client_put, CURLOPT_PRIVATE, ps); 284 //curl_easy_setopt (s->client_put, CURLOPT_PRIVATE, ps);
175 curl_easy_setopt (s->client_put, CURLOPT_CONNECTTIMEOUT, 285 curl_easy_setopt (s->client_put, CURLOPT_CONNECTTIMEOUT_MS,
176 (long) HTTP_NOT_VALIDATED_TIMEOUT.rel_value); 286 (long) HTTP_NOT_VALIDATED_TIMEOUT.rel_value);
177 curl_easy_setopt (s->client_put, CURLOPT_BUFFERSIZE, 287 curl_easy_setopt (s->client_put, CURLOPT_BUFFERSIZE,
178 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE); 288 2 * GNUNET_SERVER_MAX_MESSAGE_SIZE);
@@ -201,6 +311,7 @@ client_connect (struct Session *s)
201 } 311 }
202 312
203 /* Perform connect */ 313 /* Perform connect */
314 s->plugin->client_perform_task = GNUNET_SCHEDULER_add_now (client_perform, s->plugin);
204 315
205 return res; 316 return res;
206} 317}
@@ -227,6 +338,12 @@ client_start (struct Plugin *plugin)
227void 338void
228client_stop (struct Plugin *plugin) 339client_stop (struct Plugin *plugin)
229{ 340{
341 if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK)
342 {
343 GNUNET_SCHEDULER_cancel (plugin->client_perform_task);
344 plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK;
345 }
346
230 curl_multi_cleanup (plugin->client_mh); 347 curl_multi_cleanup (plugin->client_mh);
231 curl_global_cleanup (); 348 curl_global_cleanup ();
232} 349}
diff --git a/src/transport/plugin_transport_http_new.c b/src/transport/plugin_transport_http_new.c
index 3ad7dbac4..8fdce38e3 100644
--- a/src/transport/plugin_transport_http_new.c
+++ b/src/transport/plugin_transport_http_new.c
@@ -481,9 +481,18 @@ http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
481 /* look for existing connection */ 481 /* look for existing connection */
482 s = lookup_session (plugin, target, addr, addrlen, force_address); 482 s = lookup_session (plugin, target, addr, addrlen, force_address);
483 483
484 /* create new connection */ 484 /* create new outbound connection */
485 if (s == NULL) 485 if (s == NULL)
486 { 486 {
487 if (plugin->max_connections <= plugin->cur_connections)
488 {
489 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name,
490 "Maximum number of connections reached, "
491 "cannot connect to peer `%s'\n",
492 GNUNET_i2s (target));
493 return res;
494 }
495
487#if DEBUG_HTTP 496#if DEBUG_HTTP
488 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, 497 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name,
489 "Initiiating new connection to peer `%s'\n", 498 "Initiiating new connection to peer `%s'\n",
@@ -492,7 +501,12 @@ http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
492 s = create_session (plugin, target, addr, addrlen, cont, cont_cls); 501 s = create_session (plugin, target, addr, addrlen, cont, cont_cls);
493 GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s); 502 GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s);
494 // initiate new connection 503 // initiate new connection
495 client_connect (s); 504 if (GNUNET_SYSERR == (res = client_connect (s)))
505 {
506 GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s);
507 delete_session (s);
508 return GNUNET_SYSERR;
509 }
496 } 510 }
497 else if (s->inbound == GNUNET_NO) 511 else if (s->inbound == GNUNET_NO)
498 res = client_send (s, msgbuf, msgbuf_size); 512 res = client_send (s, msgbuf, msgbuf_size);
@@ -839,6 +853,14 @@ configure_plugin (struct Plugin *plugin)
839 } 853 }
840 plugin->port = port; 854 plugin->port = port;
841 855
856 /* Optional parameters */
857 unsigned long long maxneigh;
858 if (GNUNET_OK !=
859 GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name,
860 "MAX_CONNECTIONS", &maxneigh))
861 maxneigh = 128;
862 plugin->max_connections = maxneigh;
863
842 return res; 864 return res;
843} 865}
844 866
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
index 96d3e27ae..b74f68b96 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -48,7 +48,12 @@ server_log (void *arg, const char *fmt, va_list ap)
48static int 48static int
49server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len) 49server_accept_cb (void *cls, const struct sockaddr *addr, socklen_t addr_len)
50{ 50{
51 return 0; 51 struct Plugin * plugin = cls;
52 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: server_accept_cb\n");
53 if (plugin->cur_connections <= plugin->max_connections)
54 return MHD_YES;
55 else
56 return MHD_NO;
52} 57}
53 58
54 59
@@ -220,6 +225,7 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection,
220 const char *upload_data, size_t * upload_data_size, 225 const char *upload_data, size_t * upload_data_size,
221 void **httpSessionCache) 226 void **httpSessionCache)
222{ 227{
228 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: server_access_cb\n");
223 return 0; 229 return 0;
224} 230}
225 231
@@ -227,6 +233,7 @@ static void
227server_disconnect_cb (void *cls, struct MHD_Connection *connection, 233server_disconnect_cb (void *cls, struct MHD_Connection *connection,
228 void **httpSessionCache) 234 void **httpSessionCache)
229{ 235{
236 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "server: server_disconnect_cb\n");
230} 237}
231 238
232int 239int
@@ -241,6 +248,132 @@ server_send (struct Session *s, const char *msgbuf, size_t msgbuf_size)
241 return GNUNET_OK; 248 return GNUNET_OK;
242} 249}
243 250
251/**
252 * Function that queries MHD's select sets and
253 * starts the task waiting for them.
254 * @param plugin plugin
255 * @param daemon_handle the MHD daemon handle
256 * @return gnunet task identifier
257 */
258static GNUNET_SCHEDULER_TaskIdentifier
259server_schedule_daemon (struct Plugin *plugin, struct MHD_Daemon *daemon_handle);
260
261/**
262 * Call MHD IPv4 to process pending requests and then go back
263 * and schedule the next run.
264 * @param cls plugin as closure
265 * @param tc task context
266 */
267static void
268http_server_daemon_v4_run (void *cls,
269 const struct GNUNET_SCHEDULER_TaskContext *tc)
270{
271 struct Plugin *plugin = cls;
272 GNUNET_assert (cls != NULL);
273
274 plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK;
275
276 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
277 return;
278
279 GNUNET_assert (MHD_YES == MHD_run (plugin->server_v4));
280 plugin->server_v4_task = server_schedule_daemon (plugin, plugin->server_v4);
281}
282
283
284/**
285 * Call MHD IPv6 to process pending requests and then go back
286 * and schedule the next run.
287 * @param cls plugin as closure
288 * @param tc task context
289 */
290static void
291http_server_daemon_v6_run (void *cls,
292 const struct GNUNET_SCHEDULER_TaskContext *tc)
293{
294 struct Plugin *plugin = cls;
295 GNUNET_assert (cls != NULL);
296
297 plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK;
298
299 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
300 return;
301
302 GNUNET_assert (MHD_YES == MHD_run (plugin->server_v6));
303 plugin->server_v6_task = server_schedule_daemon (plugin, plugin->server_v6);
304}
305
306/**
307 * Function that queries MHD's select sets and
308 * starts the task waiting for them.
309 * @param plugin plugin
310 * @param daemon_handle the MHD daemon handle
311 * @return gnunet task identifier
312 */
313static GNUNET_SCHEDULER_TaskIdentifier
314server_schedule_daemon (struct Plugin *plugin, struct MHD_Daemon *daemon_handle)
315{
316 GNUNET_SCHEDULER_TaskIdentifier ret;
317 fd_set rs;
318 fd_set ws;
319 fd_set es;
320 struct GNUNET_NETWORK_FDSet *wrs;
321 struct GNUNET_NETWORK_FDSet *wws;
322 struct GNUNET_NETWORK_FDSet *wes;
323 int max;
324 unsigned long long timeout;
325 int haveto;
326 struct GNUNET_TIME_Relative tv;
327
328 ret = GNUNET_SCHEDULER_NO_TASK;
329 FD_ZERO (&rs);
330 FD_ZERO (&ws);
331 FD_ZERO (&es);
332 wrs = GNUNET_NETWORK_fdset_create ();
333 wes = GNUNET_NETWORK_fdset_create ();
334 wws = GNUNET_NETWORK_fdset_create ();
335 max = -1;
336 GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, &max));
337 haveto = MHD_get_timeout (daemon_handle, &timeout);
338 if (haveto == MHD_YES)
339 tv.rel_value = (uint64_t) timeout;
340 else
341 tv = GNUNET_TIME_UNIT_SECONDS;
342 GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
343 GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
344 GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1);
345 if (daemon_handle == plugin->server_v4)
346 {
347 if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK)
348 {
349 GNUNET_SCHEDULER_cancel (plugin->server_v4_task);
350 plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK;
351 }
352
353 ret =
354 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
355 GNUNET_SCHEDULER_NO_TASK, tv, wrs, wws,
356 &http_server_daemon_v4_run, plugin);
357 }
358 if (daemon_handle == plugin->server_v6)
359 {
360 if (plugin->server_v6_task != GNUNET_SCHEDULER_NO_TASK)
361 {
362 GNUNET_SCHEDULER_cancel (plugin->server_v6_task);
363 plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK;
364 }
365
366 ret =
367 GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
368 GNUNET_SCHEDULER_NO_TASK, tv, wrs, wws,
369 &http_server_daemon_v6_run, plugin);
370 }
371 GNUNET_NETWORK_fdset_destroy (wrs);
372 GNUNET_NETWORK_fdset_destroy (wws);
373 GNUNET_NETWORK_fdset_destroy (wes);
374 return ret;
375}
376
244int 377int
245server_start (struct Plugin *plugin) 378server_start (struct Plugin *plugin)
246{ 379{
@@ -334,6 +467,11 @@ server_start (struct Plugin *plugin)
334 res = GNUNET_SYSERR; 467 res = GNUNET_SYSERR;
335 } 468 }
336 469
470 if (plugin->server_v4 != NULL)
471 plugin->server_v4_task = server_schedule_daemon (plugin, plugin->server_v4);
472 if (plugin->server_v6 != NULL)
473 plugin->server_v6_task = server_schedule_daemon (plugin, plugin->server_v6);
474
337#if DEBUG_HTTP 475#if DEBUG_HTTP
338 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, 476 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
339 "%s server component started on port %u\n", plugin->name, 477 "%s server component started on port %u\n", plugin->name,
@@ -345,6 +483,17 @@ server_start (struct Plugin *plugin)
345void 483void
346server_stop (struct Plugin *plugin) 484server_stop (struct Plugin *plugin)
347{ 485{
486 if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK)
487 {
488 GNUNET_SCHEDULER_cancel (plugin->server_v4_task);
489 plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK;
490 }
491
492 if (plugin->server_v6_task != GNUNET_SCHEDULER_NO_TASK)
493 {
494 GNUNET_SCHEDULER_cancel (plugin->server_v6_task);
495 plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK;
496 }
348 497
349 if (plugin->server_v4 != NULL) 498 if (plugin->server_v4 != NULL)
350 { 499 {