test_plugin_transport_http.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2010 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file transport/test_plugin_transport_http.c
  19. * @brief testcase for plugin_transport_http.c
  20. * @author Matthias Wachs
  21. */
  22. #include "platform.h"
  23. #include "gnunet_constants.h"
  24. #include "gnunet_common.h"
  25. #include "gnunet_getopt_lib.h"
  26. #include "gnunet_hello_lib.h"
  27. #include "gnunet_os_lib.h"
  28. #include "gnunet_peerinfo_service.h"
  29. #include "gnunet_plugin_lib.h"
  30. #include "gnunet_protocols.h"
  31. #include "gnunet_program_lib.h"
  32. #include "gnunet_signatures.h"
  33. #include "gnunet_service_lib.h"
  34. #include "gnunet_crypto_lib.h"
  35. #include "gnunet_transport_plugin.h"
  36. #include "gnunet_statistics_service.h"
  37. #include "transport.h"
  38. #include <curl/curl.h>
  39. #define VERBOSE GNUNET_NO
  40. #define DEBUG_CURL GNUNET_NO
  41. #define HTTP_BUFFER_SIZE 2048
  42. #define PROTOCOL_PREFIX "http"
  43. #define PLUGIN libgnunet_plugin_transport_template
  44. /**
  45. * How long until we give up on transmitting the message?
  46. */
  47. #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
  48. /**
  49. * Testcase timeout
  50. */
  51. #define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20)
  52. /**
  53. * How long between recieve and send?
  54. */
  55. #define WAIT_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
  56. /**
  57. * Struct for plugin addresses
  58. */
  59. struct Plugin_Address
  60. {
  61. /**
  62. * Next field for linked list
  63. */
  64. struct Plugin_Address * next;
  65. /**
  66. * buffer containing data to send
  67. */
  68. void * addr;
  69. /**
  70. * amount of data to sent
  71. */
  72. size_t addrlen;
  73. };
  74. /**
  75. * Message to send using http
  76. */
  77. struct HTTP_Message
  78. {
  79. /**
  80. * buffer
  81. */
  82. unsigned char buf[HTTP_BUFFER_SIZE];
  83. /**
  84. * current position in buffer
  85. */
  86. size_t pos;
  87. /**
  88. * buffer size
  89. */
  90. size_t size;
  91. /**
  92. * data size
  93. */
  94. size_t len;
  95. };
  96. /**
  97. * Struct for plugin addresses
  98. */
  99. struct HTTP_Transfer
  100. {
  101. /**
  102. * amount of bytes we recieved
  103. */
  104. size_t data_size;
  105. /**
  106. * buffer for http transfers
  107. */
  108. unsigned char buf[HTTP_BUFFER_SIZE];
  109. /**
  110. * buffer size this transfer
  111. */
  112. size_t size;
  113. /**
  114. * amount of bytes we recieved
  115. */
  116. size_t pos;
  117. /**
  118. * HTTP Header result for transfer
  119. */
  120. unsigned int http_result_code;
  121. /**
  122. * did the test fail?
  123. */
  124. unsigned int test_failed;
  125. /**
  126. * was this test already executed?
  127. */
  128. unsigned int test_executed;
  129. };
  130. /**
  131. * Network format for IPv4 addresses.
  132. */
  133. struct IPv4HttpAddress
  134. {
  135. struct IPv4HttpAddress * next;
  136. struct IPv4HttpAddress * prev;
  137. /**
  138. * IPv4 address, in network byte order.
  139. */
  140. uint32_t ipv4_addr GNUNET_PACKED;
  141. /**
  142. * Port number, in network byte order.
  143. */
  144. uint16_t u_port GNUNET_PACKED;
  145. };
  146. /**
  147. * Network format for IPv6 addresses.
  148. */
  149. struct IPv6HttpAddress
  150. {
  151. struct IPv6HttpAddress * next;
  152. struct IPv6HttpAddress * prev;
  153. /**
  154. * IPv6 address.
  155. */
  156. struct in6_addr ipv6_addr GNUNET_PACKED;
  157. /**
  158. * Port number, in network byte order.
  159. */
  160. uint16_t u6_port GNUNET_PACKED;
  161. };
  162. /**
  163. * Our public key.
  164. */
  165. /* static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; */
  166. /**
  167. * Our public key.
  168. */
  169. static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
  170. /**
  171. * Our identity.
  172. */
  173. static struct GNUNET_PeerIdentity my_identity;
  174. /**
  175. * Our private key.
  176. */
  177. static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
  178. /**
  179. * Peer's port
  180. */
  181. static long long unsigned int port;
  182. /**
  183. * Peer's addr
  184. */
  185. static char * test_addr;
  186. /**
  187. * Our statistics handle.
  188. */
  189. struct GNUNET_STATISTICS_Handle *stats;
  190. /**
  191. * Our configuration.
  192. */
  193. const struct GNUNET_CONFIGURATION_Handle *cfg;
  194. /**
  195. * Number of neighbours we'd like to have.
  196. */
  197. static uint32_t max_connect_per_transport;
  198. /**
  199. * Environment for this plugin.
  200. */
  201. static struct GNUNET_TRANSPORT_PluginEnvironment env;
  202. /**
  203. *handle for the api provided by this plugin
  204. */
  205. static struct GNUNET_TRANSPORT_PluginFunctions *api;
  206. /**
  207. * ID of the task controlling the testcase timeout
  208. */
  209. static GNUNET_SCHEDULER_TaskIdentifier ti_timeout;
  210. static GNUNET_SCHEDULER_TaskIdentifier ti_send;
  211. //const struct GNUNET_PeerIdentity * p;
  212. /**
  213. * buffer for data to send
  214. */
  215. static struct HTTP_Message buffer_out;
  216. /**
  217. * buffer for data to recieve
  218. */
  219. static struct HTTP_Message buffer_in;
  220. struct Plugin_Address * addr_head;
  221. /**
  222. * Did the test pass or fail?
  223. */
  224. static int fail_notify_address;
  225. /**
  226. * Did the test pass or fail?
  227. */
  228. static int fail_notify_address_count;
  229. /**
  230. * Did the test pass or fail?
  231. */
  232. static int fail_pretty_printer;
  233. /**
  234. * Did the test pass or fail?
  235. */
  236. static int fail_pretty_printer_count;
  237. /**
  238. * Did the test pass or fail?
  239. */
  240. static int fail_addr_to_str;
  241. /**
  242. * No. of msgs transmitted successfully to local addresses
  243. */
  244. static int fail_msgs_transmited_to_local_addrs;
  245. /**
  246. * Test: transmit msg of max. size
  247. */
  248. static int fail_msg_transmited_bigger_max_size;
  249. /**
  250. * Test: transmit msg of max. size
  251. */
  252. static int fail_msg_transmited_max_size;
  253. /**
  254. * Test: transmit 2 msgs. in in send operation
  255. */
  256. static int fail_multiple_msgs_in_transmission;
  257. /**
  258. * Test: connect to peer without peer identification
  259. */
  260. static struct HTTP_Transfer test_no_ident;
  261. /**
  262. * Test: connect to peer without peer identification
  263. */
  264. static struct HTTP_Transfer test_too_short_ident;
  265. /**
  266. * Test: connect to peer without peer identification
  267. */
  268. static struct HTTP_Transfer test_too_long_ident;
  269. /**
  270. * Test: connect to peer with valid peer identification
  271. */
  272. static struct HTTP_Transfer test_valid_ident;
  273. /**
  274. * Test: session selection, use any existing
  275. */
  276. static int fail_session_selection_any;
  277. /**
  278. * Test: session selection, use existing inbound session
  279. */
  280. static int fail_session_selection_session;
  281. /**
  282. * Test: session selection, use existing inbound session
  283. * max message, not fitting in send & recv buffers at one time
  284. */
  285. static int fail_session_selection_session_big;
  286. /**
  287. * Test: session selection, use reliable existing
  288. */
  289. static int fail_session_selection_reliable;
  290. /**
  291. * Did the test pass or fail?
  292. */
  293. static int fail;
  294. /**
  295. * Number of local addresses
  296. */
  297. static unsigned int count_str_addr;
  298. CURL *curl_handle;
  299. /**
  300. * cURL Multihandle
  301. */
  302. static CURLM *multi_handle;
  303. /**
  304. * The task sending data
  305. */
  306. static GNUNET_SCHEDULER_TaskIdentifier http_task_send;
  307. static char * servicehome;
  308. /**
  309. * Shutdown testcase
  310. */
  311. static void
  312. shutdown_clean ()
  313. {
  314. struct Plugin_Address * tmp;
  315. /* Evaluate results */
  316. fail = 0;
  317. if ( (fail_notify_address == GNUNET_YES) ||
  318. (fail_pretty_printer == GNUNET_YES) ||
  319. (fail_addr_to_str == GNUNET_YES))
  320. {
  321. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  322. "Phase 0: Test plugin functions failed\n");
  323. fail = 1;
  324. }
  325. if ( (test_no_ident.test_failed == GNUNET_YES) ||
  326. (test_too_short_ident.test_failed == GNUNET_YES) ||
  327. (test_too_long_ident.test_failed == GNUNET_YES) ||
  328. (test_valid_ident.test_failed == GNUNET_YES) )
  329. {
  330. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  331. "Phase 1: Test connect with wrong data failed\n");
  332. fail = 1;
  333. }
  334. if ( (fail_session_selection_any != GNUNET_NO) ||
  335. (fail_session_selection_reliable != GNUNET_NO) ||
  336. (fail_session_selection_session != GNUNET_NO) ||
  337. (fail_session_selection_session_big != GNUNET_NO) )
  338. {
  339. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  340. "Phase 2: Test session selection failed\n");
  341. fail = 1;
  342. }
  343. if ( (fail_msgs_transmited_to_local_addrs != count_str_addr) ||
  344. (fail_multiple_msgs_in_transmission != 2) ||
  345. (fail_msg_transmited_max_size == GNUNET_YES) )
  346. {
  347. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  348. "Phase 3: Test sending with plugin failed\n");
  349. fail = 1;
  350. }
  351. if (fail != 1)
  352. {
  353. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  354. "All tests successful\n");
  355. }
  356. api->disconnect(api->cls,&my_identity);
  357. curl_multi_cleanup(multi_handle);
  358. if (NULL != curl_handle)
  359. curl_easy_cleanup (curl_handle);
  360. /* cleaning addresses */
  361. while (addr_head != NULL)
  362. {
  363. tmp = addr_head->next;
  364. GNUNET_free (addr_head->addr);
  365. GNUNET_free (addr_head);
  366. addr_head=tmp;
  367. }
  368. if (ti_send != GNUNET_SCHEDULER_NO_TASK)
  369. {
  370. GNUNET_SCHEDULER_cancel(ti_send);
  371. ti_send = GNUNET_SCHEDULER_NO_TASK;
  372. }
  373. if (http_task_send != GNUNET_SCHEDULER_NO_TASK)
  374. {
  375. GNUNET_SCHEDULER_cancel(http_task_send);
  376. http_task_send = GNUNET_SCHEDULER_NO_TASK;
  377. }
  378. if (ti_timeout != GNUNET_SCHEDULER_NO_TASK)
  379. {
  380. GNUNET_SCHEDULER_cancel(ti_timeout);
  381. ti_timeout = GNUNET_SCHEDULER_NO_TASK;
  382. }
  383. GNUNET_free(test_addr);
  384. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  385. "Unloading http plugin\n");
  386. GNUNET_assert (NULL == GNUNET_PLUGIN_unload ("libgnunet_gnunet_transport_plugin_http", api));
  387. GNUNET_SCHEDULER_shutdown();
  388. GNUNET_DISK_directory_remove ("/tmp/test_gnunet_transport_plugin_http");
  389. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  390. "Exiting testcase\n");
  391. if (servicehome != NULL)
  392. {
  393. GNUNET_DISK_directory_remove (servicehome);
  394. GNUNET_free (servicehome);
  395. }
  396. exit(fail);
  397. return;
  398. }
  399. /**
  400. * Continuation called after plugin send message
  401. * @cls closure
  402. * @target target
  403. * @result GNUNET_OK or GNUNET_SYSERR
  404. */
  405. static void
  406. task_send_cont (void *cls,
  407. const struct GNUNET_PeerIdentity * target,
  408. int result)
  409. {
  410. if ((cls == &fail_msg_transmited_bigger_max_size) && (result == GNUNET_SYSERR))
  411. {
  412. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  413. "Message bigger max msg size was not sent!\n");
  414. fail_msg_transmited_bigger_max_size = GNUNET_NO;
  415. return;
  416. }
  417. if ((cls == &fail_msg_transmited_max_size) && (result == GNUNET_OK))
  418. {
  419. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  420. "Message with max msg size succesfully sent!\n",
  421. fail_msgs_transmited_to_local_addrs);
  422. fail_msg_transmited_max_size = GNUNET_NO;
  423. }
  424. }
  425. static void run_connection_tests( int phase , void * cls);
  426. /**
  427. * Recieves messages from plugin, in real world transport
  428. */
  429. static struct GNUNET_TIME_Relative
  430. receive (void *cls, const struct GNUNET_PeerIdentity *peer,
  431. const struct GNUNET_MessageHeader *message,
  432. const struct GNUNET_TRANSPORT_ATS_Information *ats,
  433. uint32_t ats_count,
  434. struct Session *session,
  435. const char *sender_address,
  436. uint16_t sender_address_len)
  437. {
  438. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  439. "Testcase recieved new message from peer `%s' with type %u and length %u, session %X\n",
  440. GNUNET_i2s(peer),
  441. ntohs(message->type),
  442. ntohs(message->size),
  443. session);
  444. if ( (ntohs(message->type)>=10) &&
  445. (ntohs(message->type)<20) )
  446. {
  447. fail_msgs_transmited_to_local_addrs++;
  448. if (fail_msgs_transmited_to_local_addrs == count_str_addr)
  449. run_connection_tests(2, session);
  450. }
  451. if ((ntohs(message->type)==20))
  452. {
  453. fail_session_selection_reliable = GNUNET_NO;
  454. }
  455. if ((ntohs(message->type)==21))
  456. {
  457. fail_session_selection_any = GNUNET_NO;
  458. }
  459. if ((ntohs(message->type)==22))
  460. {
  461. fail_session_selection_session = GNUNET_NO;
  462. }
  463. if ((ntohs(message->type)==23))
  464. {
  465. fail_session_selection_session_big = GNUNET_NO;
  466. run_connection_tests(3, NULL);
  467. }
  468. if ((ntohs(message->type)==30) || (ntohs(message->type)==31))
  469. {
  470. fail_multiple_msgs_in_transmission ++;
  471. }
  472. if ((ntohs(message->type)==32) && (ntohs(message->size) == GNUNET_SERVER_MAX_MESSAGE_SIZE-1))
  473. {
  474. fail_msg_transmited_max_size = GNUNET_NO;
  475. shutdown_clean();
  476. }
  477. return GNUNET_TIME_UNIT_ZERO;
  478. }
  479. static size_t
  480. send_function (void *stream, size_t size, size_t nmemb, void *ptr)
  481. {
  482. unsigned int len;
  483. len = buffer_out.len;
  484. if (( buffer_out.pos == len) || (len > (size * nmemb)))
  485. return 0;
  486. memcpy(stream, buffer_out.buf, len);
  487. buffer_out.pos = len;
  488. return len;
  489. }
  490. static size_t
  491. recv_function (void *ptr, size_t size, size_t nmemb, void *ctx)
  492. {
  493. if (buffer_in.pos + size * nmemb > buffer_in.size)
  494. return 0; /* overflow */
  495. buffer_in.len = size * nmemb;
  496. memcpy (&buffer_in.buf[buffer_in.pos], ptr, size * nmemb);
  497. buffer_in.pos += size * nmemb;
  498. buffer_in.len = buffer_in.pos;
  499. buffer_in.buf[buffer_in.pos] = '\0';
  500. return buffer_in.pos;
  501. }
  502. static size_t
  503. header_function( void *ptr, size_t size, size_t nmemb, void *stream)
  504. {
  505. struct HTTP_Transfer * res = stream;
  506. char * tmp;
  507. unsigned int len = size * nmemb;
  508. tmp = GNUNET_malloc ( len+1 );
  509. memcpy(tmp,ptr,len);
  510. if (tmp[len-2] == 13)
  511. tmp[len-2]= '\0';
  512. #if DEBUG_CURL
  513. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  514. "Header: `%s'\n",
  515. tmp);
  516. #endif
  517. if (0==strcmp (tmp,"HTTP/1.1 100 Continue"))
  518. {
  519. res->http_result_code=100;
  520. }
  521. if (0==strcmp (tmp,"HTTP/1.1 200 OK"))
  522. {
  523. res->http_result_code=200;
  524. }
  525. if (0==strcmp (tmp,"HTTP/1.1 400 Bad Request"))
  526. {
  527. res->http_result_code=400;
  528. }
  529. if (0==strcmp (tmp,"HTTP/1.1 404 Not Found"))
  530. {
  531. res->http_result_code=404;
  532. }
  533. if (0==strcmp (tmp,"HTTP/1.1 413 Request entity too large"))
  534. {
  535. res->http_result_code=413;
  536. }
  537. GNUNET_free (tmp);
  538. return size * nmemb;
  539. }
  540. static size_t
  541. send_prepare( struct HTTP_Transfer * result);
  542. static void
  543. send_execute (void *cls,
  544. const struct GNUNET_SCHEDULER_TaskContext *tc)
  545. {
  546. struct HTTP_Transfer *res;
  547. int running;
  548. struct CURLMsg *msg;
  549. CURLMcode mret;
  550. res = (struct HTTP_Transfer *) cls;
  551. http_task_send = GNUNET_SCHEDULER_NO_TASK;
  552. if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
  553. return;
  554. do
  555. {
  556. running = 0;
  557. mret = curl_multi_perform (multi_handle, &running);
  558. if (running == 0)
  559. {
  560. do
  561. {
  562. msg = curl_multi_info_read (multi_handle, &running);
  563. if (msg == NULL)
  564. break;
  565. /* get session for affected curl handle */
  566. //cs = find_session_by_curlhandle (msg->easy_handle);
  567. //GNUNET_assert ( cs != NULL );
  568. switch (msg->msg)
  569. {
  570. case CURLMSG_DONE:
  571. if ( (msg->data.result != CURLE_OK) &&
  572. (msg->data.result != CURLE_GOT_NOTHING) )
  573. {
  574. GNUNET_log(GNUNET_ERROR_TYPE_INFO,
  575. _("curl failed for `%s' at %s:%d: `%s'\n"),
  576. "curl_multi_perform",
  577. __FILE__,
  578. __LINE__,
  579. curl_easy_strerror (msg->data.result));
  580. /* sending msg failed*/
  581. curl_easy_cleanup(curl_handle);
  582. curl_handle=NULL;
  583. run_connection_tests(0, NULL);
  584. }
  585. if (res == &test_no_ident)
  586. {
  587. if ((res->http_result_code==404) && (buffer_in.len==208))
  588. {
  589. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  590. "Connecting to peer without any peer identification: test passed\n");
  591. res->test_failed = GNUNET_NO;
  592. }
  593. else
  594. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  595. _("Connecting to peer without any peer identification: test failed\n"));
  596. }
  597. if (res == &test_too_short_ident)
  598. {
  599. if ((res->http_result_code==404) && (buffer_in.len==208))
  600. {
  601. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  602. "Connecting to peer with too short peer identification: test passed\n");
  603. res->test_failed = GNUNET_NO;
  604. }
  605. else
  606. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  607. _("Connecting to peer with too short peer identification: test failed\n"));
  608. }
  609. if (res == &test_too_long_ident)
  610. {
  611. if ((res->http_result_code==404) && (buffer_in.len==208))
  612. {
  613. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  614. "Connecting to peer with too long peer identification: test passed\n");
  615. res->test_failed = GNUNET_NO;
  616. }
  617. else
  618. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  619. _("Connecting to peer with too long peer identification: test failed\n"));
  620. }
  621. if (res == &test_valid_ident)
  622. {
  623. if ((res->http_result_code==200))
  624. {
  625. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  626. "Connecting to peer with valid peer identification: test passed\n");
  627. res->test_failed = GNUNET_NO;
  628. }
  629. else
  630. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  631. "Connecting to peer with valid peer identification: test failed\n");
  632. }
  633. curl_easy_cleanup(curl_handle);
  634. curl_handle=NULL;
  635. if ((res == &test_valid_ident) && (res->test_failed == GNUNET_NO))
  636. run_connection_tests(1, NULL);
  637. run_connection_tests(0, NULL);
  638. return;
  639. default:
  640. break;
  641. }
  642. }
  643. while ( (running > 0) );
  644. }
  645. }
  646. while (mret == CURLM_CALL_MULTI_PERFORM);
  647. send_prepare(cls);
  648. }
  649. /**
  650. * Function setting up file descriptors and scheduling task to run
  651. * @param ses session to send data to
  652. * @return bytes sent to peer
  653. */
  654. static size_t
  655. send_prepare( struct HTTP_Transfer * result)
  656. {
  657. fd_set rs;
  658. fd_set ws;
  659. fd_set es;
  660. int max;
  661. struct GNUNET_NETWORK_FDSet *grs;
  662. struct GNUNET_NETWORK_FDSet *gws;
  663. long to;
  664. CURLMcode mret;
  665. max = -1;
  666. FD_ZERO (&rs);
  667. FD_ZERO (&ws);
  668. FD_ZERO (&es);
  669. mret = curl_multi_fdset (multi_handle, &rs, &ws, &es, &max);
  670. if (mret != CURLM_OK)
  671. {
  672. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  673. _("%s failed at %s:%d: `%s'\n"),
  674. "curl_multi_fdset", __FILE__, __LINE__,
  675. curl_multi_strerror (mret));
  676. return -1;
  677. }
  678. mret = curl_multi_timeout (multi_handle, &to);
  679. if (mret != CURLM_OK)
  680. {
  681. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  682. _("%s failed at %s:%d: `%s'\n"),
  683. "curl_multi_timeout", __FILE__, __LINE__,
  684. curl_multi_strerror (mret));
  685. return -1;
  686. }
  687. grs = GNUNET_NETWORK_fdset_create ();
  688. gws = GNUNET_NETWORK_fdset_create ();
  689. GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
  690. GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
  691. http_task_send = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
  692. GNUNET_SCHEDULER_NO_TASK,
  693. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 0),
  694. grs,
  695. gws,
  696. &send_execute,
  697. result);
  698. GNUNET_NETWORK_fdset_destroy (gws);
  699. GNUNET_NETWORK_fdset_destroy (grs);
  700. /* FIXME: return bytes REALLY sent */
  701. return 0;
  702. }
  703. /**
  704. * function to send data to server
  705. */
  706. static int
  707. send_data(struct HTTP_Transfer * result,
  708. char * url)
  709. {
  710. curl_handle = curl_easy_init();
  711. if( NULL == curl_handle)
  712. {
  713. printf("easy_init failed \n");
  714. return GNUNET_SYSERR;
  715. }
  716. #if DEBUG_CURL
  717. curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
  718. #endif
  719. curl_easy_setopt(curl_handle, CURLOPT_URL, url);
  720. curl_easy_setopt(curl_handle, CURLOPT_PUT, 1L);
  721. curl_easy_setopt (curl_handle, CURLOPT_HEADERFUNCTION, &header_function);
  722. curl_easy_setopt (curl_handle, CURLOPT_WRITEHEADER, result);
  723. curl_easy_setopt (curl_handle, CURLOPT_WRITEFUNCTION, &recv_function);
  724. curl_easy_setopt (curl_handle, CURLOPT_WRITEDATA, result);
  725. curl_easy_setopt (curl_handle, CURLOPT_READFUNCTION, &send_function);
  726. curl_easy_setopt (curl_handle, CURLOPT_READDATA, result);
  727. curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t) buffer_out.len);
  728. curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 30);
  729. curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 20);
  730. curl_multi_add_handle(multi_handle, curl_handle);
  731. send_prepare(result);
  732. return GNUNET_OK;
  733. }
  734. /**
  735. * Plugin notifies transport (aka testcase) about its addresses
  736. */
  737. static void
  738. notify_address (void *cls,
  739. int add_remove,
  740. const void *addr,
  741. size_t addrlen)
  742. {
  743. char address[INET6_ADDRSTRLEN];
  744. unsigned int port;
  745. struct Plugin_Address * pl_addr;
  746. struct Plugin_Address * cur;
  747. if (addrlen == (sizeof (struct IPv4HttpAddress)))
  748. {
  749. inet_ntop(AF_INET, (struct in_addr *) addr,address,INET_ADDRSTRLEN);
  750. port = ntohs(((struct IPv4HttpAddress *) addr)->u_port);
  751. }
  752. else if (addrlen == (sizeof (struct IPv6HttpAddress)))
  753. {
  754. inet_ntop(AF_INET6, (struct in6_addr *) addr,address,INET6_ADDRSTRLEN);
  755. port = ntohs(((struct IPv6HttpAddress *) addr)->u6_port);
  756. }
  757. else
  758. {
  759. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  760. _("Unknown address size: ipv6 has %u ipv4 has %u but this has %u\n"),
  761. sizeof (struct IPv6HttpAddress),
  762. sizeof (struct IPv4HttpAddress),
  763. addrlen);
  764. return;
  765. }
  766. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  767. _("Transport plugin notification for address: `%s':%u\n"),
  768. address,
  769. port);
  770. pl_addr = GNUNET_malloc (sizeof (struct Plugin_Address) );
  771. pl_addr->addrlen = addrlen;
  772. pl_addr->addr = GNUNET_malloc(addrlen);
  773. memcpy(pl_addr->addr,addr,addrlen);
  774. pl_addr->next = NULL;
  775. if ( NULL == addr_head)
  776. {
  777. addr_head = pl_addr;
  778. }
  779. else
  780. {
  781. cur = addr_head;
  782. while (NULL != cur->next)
  783. {
  784. cur = cur->next;
  785. }
  786. cur->next = pl_addr;
  787. }
  788. fail_notify_address_count++;
  789. fail_notify_address = GNUNET_NO;
  790. }
  791. static void
  792. plugin_env_session_end (void *cls,
  793. const struct GNUNET_PeerIdentity *peer,
  794. struct Session *session)
  795. {
  796. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  797. "Pluging tells me: session %X to peer `%s' ended\n",
  798. session,
  799. GNUNET_i2s(peer));
  800. }
  801. /**
  802. * Setup plugin environment
  803. */
  804. static void
  805. setup_plugin_environment ()
  806. {
  807. env.cfg = cfg;
  808. env.stats = stats;
  809. env.my_identity = &my_identity;
  810. env.cls = &env;
  811. env.receive = &receive;
  812. env.notify_address = &notify_address;
  813. env.max_connections = max_connect_per_transport;
  814. env.session_end = &plugin_env_session_end;
  815. }
  816. /**
  817. * Task shutting down testcase if it a timeout occurs
  818. */
  819. static void
  820. task_timeout (void *cls,
  821. const struct GNUNET_SCHEDULER_TaskContext *tc)
  822. {
  823. ti_timeout = GNUNET_SCHEDULER_NO_TASK;
  824. if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
  825. return;
  826. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testcase timeout\n");
  827. fail = GNUNET_YES;
  828. shutdown_clean();
  829. return;
  830. }
  831. static void
  832. pretty_printer_cb (void *cls,
  833. const char *address)
  834. {
  835. if (NULL==address)
  836. return;
  837. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  838. "Plugin returned pretty address: `%s'\n",
  839. address);
  840. fail_pretty_printer_count++;
  841. }
  842. /**
  843. * Runs every single test to test the plugin
  844. */
  845. static void
  846. run_connection_tests( int phase , void * cls)
  847. {
  848. struct GNUNET_MessageHeader * msg;
  849. unsigned int size;
  850. if (phase==0)
  851. {
  852. char * host_str = NULL;
  853. /* resetting buffers */
  854. buffer_in.size = HTTP_BUFFER_SIZE;
  855. buffer_in.pos = 0;
  856. buffer_in.len = 0;
  857. buffer_out.size = HTTP_BUFFER_SIZE;
  858. buffer_out.pos = 0;
  859. buffer_out.len = 0;
  860. if (test_no_ident.test_executed == GNUNET_NO)
  861. {
  862. /* Connecting to peer without identification */
  863. const char * ident = "";
  864. GNUNET_asprintf (&host_str,
  865. "%s://%s/%s",
  866. PROTOCOL_PREFIX,
  867. test_addr,ident);
  868. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  869. _("Connecting to peer without any peer identification.\n"));
  870. test_no_ident.test_executed = GNUNET_YES;
  871. send_data ( &test_no_ident, host_str);
  872. GNUNET_free (host_str);
  873. return;
  874. }
  875. if (test_too_short_ident.test_executed == GNUNET_NO)
  876. {
  877. const char * ident = "AAAAAAAAAA";
  878. /* Connecting to peer with too short identification */
  879. GNUNET_asprintf (&host_str,
  880. "%s://%s/%s",
  881. PROTOCOL_PREFIX,
  882. test_addr,
  883. ident);
  884. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  885. _("Connecting to peer with too short peer identification.\n"));
  886. test_too_short_ident.test_executed = GNUNET_YES;
  887. send_data ( &test_too_short_ident, host_str);
  888. GNUNET_free (host_str);
  889. return;
  890. }
  891. if (test_too_long_ident.test_executed == GNUNET_NO)
  892. {
  893. const char * ident = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
  894. /* Connecting to peer with too long identification */
  895. GNUNET_asprintf (&host_str, "%s://%s/%s",PROTOCOL_PREFIX, test_addr,ident);
  896. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  897. _("Connecting to peer with too long peer identification.\n"));
  898. test_too_long_ident.test_executed = GNUNET_YES;
  899. send_data ( &test_too_long_ident, host_str);
  900. GNUNET_free (host_str);
  901. return;
  902. }
  903. if (test_valid_ident.test_executed == GNUNET_NO)
  904. {
  905. struct GNUNET_CRYPTO_HashAsciiEncoded ident;
  906. GNUNET_CRYPTO_hash_to_enc(&my_identity.hashPubKey,&ident);
  907. GNUNET_asprintf (&host_str,
  908. "%s://%s/%s%s",
  909. PROTOCOL_PREFIX,
  910. test_addr,
  911. (char *) &ident,
  912. ";0");
  913. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  914. _("Connecting to peer with valid peer identification.\n"));
  915. test_valid_ident.test_executed = GNUNET_YES;
  916. send_data ( &test_valid_ident, host_str);
  917. GNUNET_free (host_str);
  918. return;
  919. }
  920. }
  921. if (phase==1)
  922. {
  923. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  924. "\nPhase 1: transmit data to all suggested addresses\n\n");
  925. /* Using one of the addresses the plugin proposed */
  926. GNUNET_assert (addr_head->addr != NULL);
  927. struct Plugin_Address * tmp_addr;
  928. struct GNUNET_MessageHeader msg;
  929. char * tmp = GNUNET_malloc(sizeof(struct GNUNET_MessageHeader));
  930. char address[INET6_ADDRSTRLEN];
  931. unsigned int port;
  932. unsigned int type = 10;
  933. msg.size=htons(sizeof(struct GNUNET_MessageHeader));
  934. tmp_addr = addr_head;
  935. /* send a message to all addresses advertised by plugin */
  936. int count = 0;
  937. while (tmp_addr != NULL)
  938. {
  939. if (tmp_addr->addrlen == (sizeof (struct IPv4HttpAddress)))
  940. {
  941. inet_ntop(AF_INET, (struct in_addr *) tmp_addr->addr,address,INET_ADDRSTRLEN);
  942. port = ntohs(((struct IPv4HttpAddress *) tmp_addr->addr)->u_port);
  943. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  944. "Sending message to addres no. %u: `%s':%u\n",
  945. count,
  946. address,
  947. port);
  948. }
  949. if (tmp_addr->addrlen == (sizeof (struct IPv6HttpAddress)))
  950. {
  951. inet_ntop(AF_INET6, (struct in6_addr *) tmp_addr->addr,address,INET6_ADDRSTRLEN);
  952. port = ntohs(((struct IPv6HttpAddress *) tmp_addr->addr)->u6_port);
  953. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  954. "Sending message to addres no. %u: `%s':%u\n",
  955. count,
  956. address,
  957. port);
  958. }
  959. msg.type=htons(type);
  960. memcpy(tmp,&msg,sizeof(struct GNUNET_MessageHeader));
  961. api->send(api->cls,
  962. &my_identity,
  963. tmp, sizeof(struct GNUNET_MessageHeader),
  964. 0, TIMEOUT,
  965. NULL,
  966. tmp_addr->addr, tmp_addr->addrlen,
  967. GNUNET_YES,
  968. &task_send_cont, &fail_msgs_transmited_to_local_addrs);
  969. tmp_addr = tmp_addr->next;
  970. count++;
  971. type++;
  972. }
  973. GNUNET_free(tmp);
  974. return;
  975. }
  976. if (phase==2)
  977. {
  978. struct Session * session = cls;
  979. msg = GNUNET_malloc (sizeof(struct GNUNET_MessageHeader));
  980. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  981. "Phase 2: session selection\n\n");
  982. size = sizeof(struct GNUNET_MessageHeader);
  983. msg->size=htons(size);
  984. msg->type = htons(20);
  985. api->send(api->cls,
  986. &my_identity,
  987. (const char *) msg, size,
  988. 0, TIMEOUT, NULL, NULL, 0, GNUNET_NO,
  989. &task_send_cont, NULL);
  990. msg->type = htons(21);
  991. api->send(api->cls,
  992. &my_identity,
  993. (const char *) msg, size,
  994. 0, TIMEOUT, NULL, NULL, 0, GNUNET_SYSERR,
  995. &task_send_cont, NULL);
  996. /* answer on session*/
  997. size = sizeof( struct GNUNET_MessageHeader);
  998. msg->size = htons(size);
  999. msg->type = htons(22);
  1000. api->send(api->cls,
  1001. &my_identity,
  1002. (const char *) msg, size,
  1003. 0, TIMEOUT, session, NULL, 0, GNUNET_SYSERR,
  1004. &task_send_cont, NULL);
  1005. GNUNET_free(msg);
  1006. /* answer on session with big message not fitting in mhd send buffer*/
  1007. size = GNUNET_SERVER_MAX_MESSAGE_SIZE-1;
  1008. msg = GNUNET_malloc (size);
  1009. msg->size=htons(size);
  1010. msg->type = htons(23);
  1011. api->send(api->cls,
  1012. &my_identity,
  1013. (const char *) msg, size,
  1014. 0, TIMEOUT, session, NULL, 0, GNUNET_NO,
  1015. &task_send_cont, NULL);
  1016. GNUNET_free(msg);
  1017. return;
  1018. }
  1019. if (phase==3)
  1020. {
  1021. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  1022. "Phase 3: send multiple or big messages after disconnect\n\n");
  1023. /* disconnect from peer, so new connections are created */
  1024. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Disconnect from peer: `%s'\n", GNUNET_i2s(&my_identity));
  1025. api->disconnect(api->cls, &my_identity);
  1026. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Phase 3: sending messages\n");
  1027. /* send a multiple GNUNET_messages at a time*/
  1028. size = 2 * sizeof(struct GNUNET_MessageHeader);
  1029. msg = GNUNET_malloc( 2* size);
  1030. msg->size = htons(size);
  1031. msg->type = htons(30);
  1032. struct GNUNET_MessageHeader * msg2 = &msg[2];
  1033. msg2->size = htons(2 * sizeof(struct GNUNET_MessageHeader));
  1034. msg2->type = htons(31);
  1035. api->send(api->cls,
  1036. &my_identity,
  1037. (const char *) msg, 4 * sizeof(struct GNUNET_MessageHeader),
  1038. 0, TIMEOUT, NULL,
  1039. addr_head->addr, addr_head->addrlen,
  1040. GNUNET_NO,
  1041. &task_send_cont, &fail_multiple_msgs_in_transmission);
  1042. GNUNET_free(msg);
  1043. /* send a message with size GNUNET_SERVER_MAX_MESSAGE_SIZE-1 */
  1044. size = GNUNET_SERVER_MAX_MESSAGE_SIZE-1;
  1045. msg = GNUNET_malloc(size);
  1046. msg->size = htons(size);
  1047. msg->type = htons(32);
  1048. api->send(api->cls,
  1049. &my_identity,
  1050. (const char *) msg, size,
  1051. 0, TIMEOUT, NULL,
  1052. addr_head->addr, addr_head->addrlen,
  1053. GNUNET_NO,
  1054. &task_send_cont, &fail_msg_transmited_max_size);
  1055. GNUNET_free(msg);
  1056. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  1057. "No more tests to run\n");
  1058. }
  1059. }
  1060. /**
  1061. * Runs the test.
  1062. *
  1063. * @param cls closure
  1064. * @param c configuration to use
  1065. */
  1066. static void
  1067. run (void *cls,
  1068. char *const *args,
  1069. const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
  1070. {
  1071. char * libname;
  1072. cfg = c;
  1073. char *keyfile;
  1074. unsigned long long tneigh;
  1075. struct Plugin_Address * cur;
  1076. const char * addr_str;
  1077. unsigned int suggest_res;
  1078. fail_pretty_printer = GNUNET_YES;
  1079. fail_notify_address = GNUNET_YES;
  1080. fail_addr_to_str = GNUNET_YES;
  1081. fail_msgs_transmited_to_local_addrs = 0;
  1082. fail_msg_transmited_max_size = GNUNET_YES;
  1083. fail_multiple_msgs_in_transmission = 0;
  1084. fail_session_selection_reliable = GNUNET_YES;
  1085. fail_session_selection_reliable = GNUNET_YES;
  1086. fail_session_selection_session = GNUNET_YES;
  1087. fail_session_selection_session_big = GNUNET_YES;
  1088. addr_head = NULL;
  1089. count_str_addr = 0;
  1090. /* parse configuration */
  1091. if (GNUNET_CONFIGURATION_have_value (c,"PATHS", "SERVICEHOME"))
  1092. GNUNET_CONFIGURATION_get_value_string (c, "PATHS", "SERVICEHOME", &servicehome);
  1093. if ((GNUNET_OK !=
  1094. GNUNET_CONFIGURATION_get_value_number (c,
  1095. "TRANSPORT",
  1096. "NEIGHBOUR_LIMIT",
  1097. &tneigh)) ||
  1098. (GNUNET_OK !=
  1099. GNUNET_CONFIGURATION_get_value_filename (c,
  1100. "GNUNETD",
  1101. "HOSTKEY", &keyfile)))
  1102. {
  1103. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  1104. _("Transport service is lacking key configuration settings. Exiting.\n"));
  1105. GNUNET_SCHEDULER_shutdown ();
  1106. fail = 1;
  1107. return;
  1108. }
  1109. if ((GNUNET_OK !=
  1110. GNUNET_CONFIGURATION_get_value_number (cfg,
  1111. "transport-http",
  1112. "PORT",
  1113. &port)) ||
  1114. (port > 65535) || (port == 0))
  1115. {
  1116. GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
  1117. "http",
  1118. _
  1119. ("Require valid port number for transport plugin `%s' in configuration!\n"),
  1120. "transport-http");
  1121. }
  1122. max_connect_per_transport = (uint32_t) tneigh;
  1123. my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
  1124. GNUNET_free (keyfile);
  1125. if (my_private_key == NULL)
  1126. {
  1127. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  1128. _("Transport service could not access hostkey. Exiting.\n"));
  1129. GNUNET_SCHEDULER_shutdown ();
  1130. fail = 1;
  1131. return;
  1132. }
  1133. GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
  1134. GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), &my_identity.hashPubKey);
  1135. /* assertions before start */
  1136. GNUNET_assert ((port > 0) && (port <= 65535));
  1137. /* load plugins... */
  1138. setup_plugin_environment ();
  1139. GNUNET_asprintf (&libname, "libgnunet_plugin_transport_http");
  1140. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  1141. _("Loading HTTP transport plugin `%s'\n"),
  1142. libname);
  1143. api = GNUNET_PLUGIN_load (libname, &env);
  1144. GNUNET_free (libname);
  1145. if (api == NULL)
  1146. {
  1147. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  1148. _("Failed to load transport plugin for http\n"));
  1149. fail = 1;
  1150. return;
  1151. }
  1152. ti_timeout = GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, &task_timeout, NULL);
  1153. /* testing plugin functionality */
  1154. GNUNET_assert (0!=fail_notify_address_count);
  1155. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  1156. "Transport plugin returned %u addresses to connect to\n",
  1157. fail_notify_address_count);
  1158. /* testing pretty printer with all addresses obtained from the plugin*/
  1159. cur = addr_head;
  1160. while (cur != NULL)
  1161. {
  1162. api->address_pretty_printer (api->cls, "http",
  1163. cur->addr,cur->addrlen, GNUNET_NO,TEST_TIMEOUT,
  1164. &pretty_printer_cb, NULL);
  1165. addr_str = api->address_to_string (api->cls, cur->addr, cur->addrlen);
  1166. suggest_res = api->check_address (api->cls, cur->addr, cur->addrlen);
  1167. GNUNET_assert (GNUNET_OK == suggest_res);
  1168. GNUNET_assert (NULL != addr_str);
  1169. count_str_addr++;
  1170. GNUNET_free ( (char *) addr_str);
  1171. cur = cur->next;
  1172. }
  1173. GNUNET_assert (fail_pretty_printer_count > 0);
  1174. GNUNET_assert (fail_pretty_printer_count==fail_notify_address_count);
  1175. GNUNET_assert (fail_pretty_printer_count==count_str_addr);
  1176. fail_pretty_printer=GNUNET_NO;
  1177. fail_addr_to_str=GNUNET_NO;
  1178. struct IPv4HttpAddress failing_addr;
  1179. /* Suggesting addresses with wrong size*/
  1180. failing_addr.ipv4_addr = htonl(INADDR_LOOPBACK);
  1181. failing_addr.u_port = htons(0);
  1182. suggest_res = api->check_address (api->cls,&failing_addr,sizeof (struct IPv6HttpAddress));
  1183. GNUNET_assert (GNUNET_SYSERR == suggest_res);
  1184. /* Suggesting addresses with wrong address*/
  1185. failing_addr.ipv4_addr = htonl(0xffc00000);
  1186. failing_addr.u_port = htons(12389);
  1187. suggest_res = api->check_address (api->cls,&failing_addr,100);
  1188. GNUNET_assert (GNUNET_SYSERR == suggest_res);
  1189. /* test sending to client */
  1190. multi_handle = curl_multi_init();
  1191. /* Setting up buffers */
  1192. buffer_in.size = HTTP_BUFFER_SIZE;
  1193. buffer_in.pos = 0;
  1194. buffer_in.len = 0;
  1195. buffer_out.size = HTTP_BUFFER_SIZE;
  1196. buffer_out.pos = 0;
  1197. buffer_out.len = 0;
  1198. /* Setting up connection tests */
  1199. /* Test: connecting without a peer identification */
  1200. test_no_ident.test_executed = GNUNET_NO;
  1201. test_no_ident.test_failed = GNUNET_YES;
  1202. /* Test: connecting with too short peer identification */
  1203. test_too_short_ident.test_executed = GNUNET_NO;
  1204. test_too_short_ident.test_failed = GNUNET_YES;
  1205. /* Test: connecting with too long peer identification */
  1206. test_too_long_ident.test_executed = GNUNET_NO;
  1207. test_too_long_ident.test_failed = GNUNET_YES;
  1208. /* Test: connecting with valid identification */
  1209. test_valid_ident.test_executed = GNUNET_NO;
  1210. test_valid_ident.test_failed = GNUNET_YES;
  1211. test_addr = (char *) api->address_to_string (api->cls,addr_head->addr,addr_head->addrlen);
  1212. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Phase 0\n\n"));
  1213. run_connection_tests(0, NULL);
  1214. /* testing finished */
  1215. }
  1216. /**
  1217. * The main function for the transport service.
  1218. *
  1219. * @param argc number of arguments from the command line
  1220. * @param argv command line arguments
  1221. * @return 0 ok, 1 on error
  1222. */
  1223. int
  1224. main (int argc, char *const *argv)
  1225. {
  1226. static struct GNUNET_GETOPT_CommandLineOption options[] = {
  1227. GNUNET_GETOPT_OPTION_END
  1228. };
  1229. int ret;
  1230. char *const argv_prog[] = {
  1231. "test_gnunet_transport_plugin_http",
  1232. "-c",
  1233. "test_plugin_transport_data_http.conf",
  1234. "-L",
  1235. #if VERBOSE
  1236. "DEBUG",
  1237. #else
  1238. "WARNING",
  1239. #endif
  1240. NULL
  1241. };
  1242. GNUNET_log_setup ("test_gnunet_transport_plugin_http",
  1243. #if VERBOSE
  1244. "DEBUG",
  1245. #else
  1246. "WARNING",
  1247. #endif
  1248. NULL);
  1249. struct GNUNET_CONFIGURATION_Handle *cfg;
  1250. cfg = GNUNET_CONFIGURATION_create ();
  1251. GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (cfg, "test_plugin_transport_data_http.conf"));
  1252. if (GNUNET_CONFIGURATION_have_value (cfg,"PATHS", "SERVICEHOME"))
  1253. GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", "SERVICEHOME", &servicehome);
  1254. GNUNET_DISK_directory_remove (servicehome);
  1255. GNUNET_CONFIGURATION_destroy (cfg);
  1256. ret = (GNUNET_OK ==
  1257. GNUNET_PROGRAM_run (5,
  1258. argv_prog,
  1259. "test_gnunet_transport_plugin_http",
  1260. "testcase", options, &run, NULL)) ? GNUNET_NO : GNUNET_YES;
  1261. if (servicehome != NULL)
  1262. {
  1263. GNUNET_DISK_directory_remove (servicehome);
  1264. GNUNET_free (servicehome);
  1265. }
  1266. if (ret != GNUNET_OK)
  1267. return 1;
  1268. return fail;
  1269. }
  1270. /* end of test_gnunet_transport_plugin_http.c */