tcp_connection_legacy.c 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2009-2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your 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. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file util/connection.c
  18. * @brief TCP connection management
  19. * @author Christian Grothoff
  20. *
  21. * This code is rather complex. Only modify it if you
  22. * 1) Have a NEW testcase showing that the new code
  23. * is needed and correct
  24. * 2) All EXISTING testcases pass with the new code
  25. * These rules should apply in general, but for this
  26. * module they are VERY, VERY important.
  27. */
  28. #include "platform.h"
  29. #include "gnunet_util_lib.h"
  30. #include "gnunet_resolver_service.h"
  31. /**
  32. * Timeout we use on TCP connect before trying another
  33. * result from the DNS resolver. Actual value used
  34. * is this value divided by the number of address families.
  35. * Default is 5s.
  36. */
  37. #define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
  38. #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall)
  39. /**
  40. * Transmission handle. There can only be one for each connection.
  41. */
  42. struct GNUNET_CONNECTION_TransmitHandle
  43. {
  44. /**
  45. * Function to call if the send buffer has notify_size
  46. * bytes available.
  47. */
  48. GNUNET_CONNECTION_TransmitReadyNotify notify_ready;
  49. /**
  50. * Closure for notify_ready.
  51. */
  52. void *notify_ready_cls;
  53. /**
  54. * Our connection handle.
  55. */
  56. struct GNUNET_CONNECTION_Handle *connection;
  57. /**
  58. * Timeout for receiving (in absolute time).
  59. */
  60. struct GNUNET_TIME_Absolute transmit_timeout;
  61. /**
  62. * Task called on timeout.
  63. */
  64. struct GNUNET_SCHEDULER_Task * timeout_task;
  65. /**
  66. * At what number of bytes available in the
  67. * write buffer should the notify method be called?
  68. */
  69. size_t notify_size;
  70. };
  71. /**
  72. * During connect, we try multiple possible IP addresses
  73. * to find out which one might work.
  74. */
  75. struct AddressProbe
  76. {
  77. /**
  78. * This is a linked list.
  79. */
  80. struct AddressProbe *next;
  81. /**
  82. * This is a doubly-linked list.
  83. */
  84. struct AddressProbe *prev;
  85. /**
  86. * The address; do not free (allocated at the end of this struct).
  87. */
  88. const struct sockaddr *addr;
  89. /**
  90. * Underlying OS's socket.
  91. */
  92. struct GNUNET_NETWORK_Handle *sock;
  93. /**
  94. * Connection for which we are probing.
  95. */
  96. struct GNUNET_CONNECTION_Handle *connection;
  97. /**
  98. * Lenth of addr.
  99. */
  100. socklen_t addrlen;
  101. /**
  102. * Task waiting for the connection to finish connecting.
  103. */
  104. struct GNUNET_SCHEDULER_Task * task;
  105. };
  106. /**
  107. * @brief handle for a network connection
  108. */
  109. struct GNUNET_CONNECTION_Handle
  110. {
  111. /**
  112. * Configuration to use.
  113. */
  114. const struct GNUNET_CONFIGURATION_Handle *cfg;
  115. /**
  116. * Linked list of sockets we are currently trying out
  117. * (during connect).
  118. */
  119. struct AddressProbe *ap_head;
  120. /**
  121. * Linked list of sockets we are currently trying out
  122. * (during connect).
  123. */
  124. struct AddressProbe *ap_tail;
  125. /**
  126. * Network address of the other end-point, may be NULL.
  127. */
  128. struct sockaddr *addr;
  129. /**
  130. * Pointer to the hostname if connection was
  131. * created using DNS lookup, otherwise NULL.
  132. */
  133. char *hostname;
  134. /**
  135. * Underlying OS's socket, set to NULL after fatal errors.
  136. */
  137. struct GNUNET_NETWORK_Handle *sock;
  138. /**
  139. * Function to call on data received, NULL if no receive is pending.
  140. */
  141. GNUNET_CONNECTION_Receiver receiver;
  142. /**
  143. * Closure for @e receiver.
  144. */
  145. void *receiver_cls;
  146. /**
  147. * Pointer to our write buffer.
  148. */
  149. char *write_buffer;
  150. /**
  151. * Current size of our @e write_buffer.
  152. */
  153. size_t write_buffer_size;
  154. /**
  155. * Current write-offset in @e write_buffer (where
  156. * would we write next).
  157. */
  158. size_t write_buffer_off;
  159. /**
  160. * Current read-offset in @e write_buffer (how many
  161. * bytes have already been sent).
  162. */
  163. size_t write_buffer_pos;
  164. /**
  165. * Length of @e addr.
  166. */
  167. socklen_t addrlen;
  168. /**
  169. * Read task that we may need to wait for.
  170. */
  171. struct GNUNET_SCHEDULER_Task *read_task;
  172. /**
  173. * Write task that we may need to wait for.
  174. */
  175. struct GNUNET_SCHEDULER_Task *write_task;
  176. /**
  177. * Handle to a pending DNS lookup request.
  178. */
  179. struct GNUNET_RESOLVER_RequestHandle *dns_active;
  180. /**
  181. * The handle we return for #GNUNET_CONNECTION_notify_transmit_ready().
  182. */
  183. struct GNUNET_CONNECTION_TransmitHandle nth;
  184. /**
  185. * Timeout for receiving (in absolute time).
  186. */
  187. struct GNUNET_TIME_Absolute receive_timeout;
  188. /**
  189. * Maximum number of bytes to read (for receiving).
  190. */
  191. size_t max;
  192. /**
  193. * Port to connect to.
  194. */
  195. uint16_t port;
  196. /**
  197. * When shutdown, do not ever actually close the socket, but
  198. * free resources. Only should ever be set if using program
  199. * termination as a signal (because only then will the leaked
  200. * socket be freed!)
  201. */
  202. int8_t persist;
  203. /**
  204. * Usually 0. Set to 1 if this handle is in use, and should
  205. * #GNUNET_CONNECTION_destroy() be called right now, the action needs
  206. * to be deferred by setting it to -1.
  207. */
  208. int8_t destroy_later;
  209. /**
  210. * Handle to subsequent connection after proxy handshake completes,
  211. */
  212. struct GNUNET_CONNECTION_Handle *proxy_handshake;
  213. };
  214. /**
  215. * Set the persist option on this connection handle. Indicates
  216. * that the underlying socket or fd should never really be closed.
  217. * Used for indicating process death.
  218. *
  219. * @param connection the connection to set persistent
  220. */
  221. void
  222. GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection)
  223. {
  224. connection->persist = GNUNET_YES;
  225. }
  226. /**
  227. * Disable the "CORK" feature for communication with the given connection,
  228. * forcing the OS to immediately flush the buffer on transmission
  229. * instead of potentially buffering multiple messages. Essentially
  230. * reduces the OS send buffers to zero.
  231. * Used to make sure that the last messages sent through the connection
  232. * reach the other side before the process is terminated.
  233. *
  234. * @param connection the connection to make flushing and blocking
  235. * @return #GNUNET_OK on success
  236. */
  237. int
  238. GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection)
  239. {
  240. return GNUNET_NETWORK_socket_disable_corking (connection->sock);
  241. }
  242. /**
  243. * Create a connection handle by boxing an existing OS socket. The OS
  244. * socket should henceforth be no longer used directly.
  245. * #GNUNET_connection_destroy() will close it.
  246. *
  247. * @param osSocket existing socket to box
  248. * @return the boxed connection handle
  249. */
  250. struct GNUNET_CONNECTION_Handle *
  251. GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket)
  252. {
  253. struct GNUNET_CONNECTION_Handle *connection;
  254. connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
  255. connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
  256. connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
  257. connection->sock = osSocket;
  258. return connection;
  259. }
  260. /**
  261. * Create a connection handle by accepting on a listen socket. This
  262. * function may block if the listen socket has no connection ready.
  263. *
  264. * @param access_cb function to use to check if access is allowed
  265. * @param access_cb_cls closure for @a access_cb
  266. * @param lsock listen socket
  267. * @return the connection handle, NULL on error
  268. */
  269. struct GNUNET_CONNECTION_Handle *
  270. GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb,
  271. void *access_cb_cls,
  272. struct GNUNET_NETWORK_Handle *lsock)
  273. {
  274. struct GNUNET_CONNECTION_Handle *connection;
  275. char addr[128];
  276. socklen_t addrlen;
  277. struct GNUNET_NETWORK_Handle *sock;
  278. int aret;
  279. struct sockaddr_in *v4;
  280. struct sockaddr_in6 *v6;
  281. struct sockaddr *sa;
  282. void *uaddr;
  283. #ifdef SO_PEERCRED
  284. struct ucred uc;
  285. socklen_t olen;
  286. #endif
  287. struct GNUNET_CONNECTION_Credentials *gcp;
  288. #if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED
  289. struct GNUNET_CONNECTION_Credentials gc;
  290. gc.uid = 0;
  291. gc.gid = 0;
  292. #endif
  293. addrlen = sizeof (addr);
  294. sock =
  295. GNUNET_NETWORK_socket_accept (lsock,
  296. (struct sockaddr *) &addr,
  297. &addrlen);
  298. if (NULL == sock)
  299. {
  300. if (EAGAIN != errno)
  301. LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept");
  302. return NULL;
  303. }
  304. if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t)))
  305. {
  306. GNUNET_break (0);
  307. GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
  308. return NULL;
  309. }
  310. sa = (struct sockaddr *) addr;
  311. v6 = (struct sockaddr_in6 *) addr;
  312. if ( (AF_INET6 == sa->sa_family) &&
  313. (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)) )
  314. {
  315. /* convert to V4 address */
  316. v4 = GNUNET_new (struct sockaddr_in);
  317. memset (v4, 0, sizeof (struct sockaddr_in));
  318. v4->sin_family = AF_INET;
  319. #if HAVE_SOCKADDR_IN_SIN_LEN
  320. v4->sin_len = (u_char) sizeof (struct sockaddr_in);
  321. #endif
  322. GNUNET_memcpy (&v4->sin_addr,
  323. &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) -
  324. sizeof (struct in_addr)],
  325. sizeof (struct in_addr));
  326. v4->sin_port = v6->sin6_port;
  327. uaddr = v4;
  328. addrlen = sizeof (struct sockaddr_in);
  329. }
  330. else
  331. {
  332. uaddr = GNUNET_malloc (addrlen);
  333. GNUNET_memcpy (uaddr, addr, addrlen);
  334. }
  335. gcp = NULL;
  336. if (AF_UNIX == sa->sa_family)
  337. {
  338. #if HAVE_GETPEEREID
  339. /* most BSDs */
  340. if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock),
  341. &gc.uid,
  342. &gc.gid))
  343. gcp = &gc;
  344. #else
  345. #ifdef SO_PEERCRED
  346. /* largely traditional GNU/Linux */
  347. olen = sizeof (uc);
  348. if ( (0 ==
  349. getsockopt (GNUNET_NETWORK_get_fd (sock),
  350. SOL_SOCKET,
  351. SO_PEERCRED,
  352. &uc,
  353. &olen)) &&
  354. (olen == sizeof (uc)) )
  355. {
  356. gc.uid = uc.uid;
  357. gc.gid = uc.gid;
  358. gcp = &gc;
  359. }
  360. #else
  361. #if HAVE_GETPEERUCRED
  362. /* this is for Solaris 10 */
  363. ucred_t *uc;
  364. uc = NULL;
  365. if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc))
  366. {
  367. gc.uid = ucred_geteuid (uc);
  368. gc.gid = ucred_getegid (uc);
  369. gcp = &gc;
  370. }
  371. ucred_free (uc);
  372. #endif
  373. #endif
  374. #endif
  375. }
  376. if ( (NULL != access_cb) &&
  377. (GNUNET_YES != (aret = access_cb (access_cb_cls,
  378. gcp,
  379. uaddr,
  380. addrlen))) )
  381. {
  382. if (GNUNET_NO == aret)
  383. LOG (GNUNET_ERROR_TYPE_INFO,
  384. _("Access denied to `%s'\n"),
  385. GNUNET_a2s (uaddr,
  386. addrlen));
  387. GNUNET_break (GNUNET_OK ==
  388. GNUNET_NETWORK_socket_shutdown (sock,
  389. SHUT_RDWR));
  390. GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
  391. GNUNET_free (uaddr);
  392. return NULL;
  393. }
  394. connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
  395. connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
  396. connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
  397. connection->addr = uaddr;
  398. connection->addrlen = addrlen;
  399. connection->sock = sock;
  400. LOG (GNUNET_ERROR_TYPE_INFO,
  401. _("Accepting connection from `%s': %p\n"),
  402. GNUNET_a2s (uaddr,
  403. addrlen),
  404. connection);
  405. return connection;
  406. }
  407. /**
  408. * Obtain the network address of the other party.
  409. *
  410. * @param connection the client to get the address for
  411. * @param addr where to store the address
  412. * @param addrlen where to store the length of the @a addr
  413. * @return #GNUNET_OK on success
  414. */
  415. int
  416. GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
  417. void **addr,
  418. size_t *addrlen)
  419. {
  420. if ((NULL == connection->addr) || (0 == connection->addrlen))
  421. return GNUNET_NO;
  422. *addr = GNUNET_malloc (connection->addrlen);
  423. GNUNET_memcpy (*addr, connection->addr, connection->addrlen);
  424. *addrlen = connection->addrlen;
  425. return GNUNET_OK;
  426. }
  427. /**
  428. * Tell the receiver callback that we had an IO error.
  429. *
  430. * @param connection connection to signal error
  431. * @param errcode error code to send
  432. */
  433. static void
  434. signal_receive_error (struct GNUNET_CONNECTION_Handle *connection,
  435. int errcode)
  436. {
  437. GNUNET_CONNECTION_Receiver receiver;
  438. LOG (GNUNET_ERROR_TYPE_DEBUG,
  439. "Receive encounters error (%s), connection closed (%p)\n",
  440. STRERROR (errcode),
  441. connection);
  442. GNUNET_assert (NULL != (receiver = connection->receiver));
  443. connection->receiver = NULL;
  444. receiver (connection->receiver_cls,
  445. NULL,
  446. 0,
  447. connection->addr,
  448. connection->addrlen,
  449. errcode);
  450. }
  451. /**
  452. * Tell the receiver callback that a timeout was reached.
  453. *
  454. * @param connection connection to signal for
  455. */
  456. static void
  457. signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection)
  458. {
  459. GNUNET_CONNECTION_Receiver receiver;
  460. LOG (GNUNET_ERROR_TYPE_DEBUG,
  461. "Connection signals timeout to receiver (%p)!\n",
  462. connection);
  463. GNUNET_assert (NULL != (receiver = connection->receiver));
  464. connection->receiver = NULL;
  465. receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
  466. }
  467. /**
  468. * We failed to transmit data to the service, signal the error.
  469. *
  470. * @param connection handle that had trouble
  471. * @param ecode error code (errno)
  472. */
  473. static void
  474. signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection,
  475. int ecode)
  476. {
  477. GNUNET_CONNECTION_TransmitReadyNotify notify;
  478. LOG (GNUNET_ERROR_TYPE_DEBUG,
  479. "Transmission encounterd error (%s), connection closed (%p)\n",
  480. STRERROR (ecode),
  481. connection);
  482. if (NULL != connection->sock)
  483. {
  484. (void) GNUNET_NETWORK_socket_shutdown (connection->sock,
  485. SHUT_RDWR);
  486. GNUNET_break (GNUNET_OK ==
  487. GNUNET_NETWORK_socket_close (connection->sock));
  488. connection->sock = NULL;
  489. GNUNET_assert (NULL == connection->write_task);
  490. }
  491. if (NULL != connection->read_task)
  492. {
  493. /* send errors trigger read errors... */
  494. GNUNET_SCHEDULER_cancel (connection->read_task);
  495. connection->read_task = NULL;
  496. signal_receive_timeout (connection);
  497. return;
  498. }
  499. if (NULL == connection->nth.notify_ready)
  500. return; /* nobody to tell about it */
  501. notify = connection->nth.notify_ready;
  502. connection->nth.notify_ready = NULL;
  503. notify (connection->nth.notify_ready_cls,
  504. 0,
  505. NULL);
  506. }
  507. /**
  508. * We've failed for good to establish a connection (timeout or
  509. * no more addresses to try).
  510. *
  511. * @param connection the connection we tried to establish
  512. */
  513. static void
  514. connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
  515. {
  516. LOG (GNUNET_ERROR_TYPE_INFO,
  517. "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n",
  518. connection->hostname,
  519. connection->port);
  520. GNUNET_break (NULL == connection->ap_head);
  521. GNUNET_break (NULL == connection->ap_tail);
  522. GNUNET_break (GNUNET_NO == connection->dns_active);
  523. GNUNET_break (NULL == connection->sock);
  524. GNUNET_assert (NULL == connection->write_task);
  525. GNUNET_assert (NULL == connection->proxy_handshake);
  526. /* signal errors for jobs that used to wait on the connection */
  527. connection->destroy_later = 1;
  528. if (NULL != connection->receiver)
  529. signal_receive_error (connection,
  530. ECONNREFUSED);
  531. if (NULL != connection->nth.notify_ready)
  532. {
  533. GNUNET_assert (NULL != connection->nth.timeout_task);
  534. GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
  535. connection->nth.timeout_task = NULL;
  536. signal_transmit_error (connection,
  537. ECONNREFUSED);
  538. }
  539. if (-1 == connection->destroy_later)
  540. {
  541. /* do it now */
  542. connection->destroy_later = 0;
  543. GNUNET_CONNECTION_destroy (connection);
  544. return;
  545. }
  546. connection->destroy_later = 0;
  547. }
  548. /**
  549. * We are ready to transmit (or got a timeout).
  550. *
  551. * @param cls our connection handle
  552. */
  553. static void
  554. transmit_ready (void *cls);
  555. /**
  556. * This function is called once we either timeout or have data ready
  557. * to read.
  558. *
  559. * @param cls connection to read from
  560. */
  561. static void
  562. receive_ready (void *cls);
  563. /**
  564. * We've succeeded in establishing a connection.
  565. *
  566. * @param connection the connection we tried to establish
  567. */
  568. static void
  569. connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection)
  570. {
  571. LOG (GNUNET_ERROR_TYPE_DEBUG,
  572. "Connection to `%s' succeeded! (%p)\n",
  573. GNUNET_a2s (connection->addr,
  574. connection->addrlen),
  575. connection);
  576. /* trigger jobs that waited for the connection */
  577. if (NULL != connection->receiver)
  578. {
  579. LOG (GNUNET_ERROR_TYPE_DEBUG,
  580. "Connection succeeded, starting with receiving data (%p)\n",
  581. connection);
  582. GNUNET_assert (NULL == connection->read_task);
  583. connection->read_task =
  584. GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
  585. (connection->receive_timeout),
  586. connection->sock,
  587. &receive_ready, connection);
  588. }
  589. if (NULL != connection->nth.notify_ready)
  590. {
  591. LOG (GNUNET_ERROR_TYPE_DEBUG,
  592. "Connection succeeded, starting with sending data (%p)\n",
  593. connection);
  594. GNUNET_assert (connection->nth.timeout_task != NULL);
  595. GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
  596. connection->nth.timeout_task = NULL;
  597. GNUNET_assert (connection->write_task == NULL);
  598. connection->write_task =
  599. GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
  600. (connection->nth.transmit_timeout), connection->sock,
  601. &transmit_ready, connection);
  602. }
  603. }
  604. /**
  605. * Scheduler let us know that we're either ready to write on the
  606. * socket OR connect timed out. Do the right thing.
  607. *
  608. * @param cls the `struct AddressProbe *` with the address that we are probing
  609. */
  610. static void
  611. connect_probe_continuation (void *cls)
  612. {
  613. struct AddressProbe *ap = cls;
  614. struct GNUNET_CONNECTION_Handle *connection = ap->connection;
  615. const struct GNUNET_SCHEDULER_TaskContext *tc;
  616. struct AddressProbe *pos;
  617. int error;
  618. socklen_t len;
  619. GNUNET_assert (NULL != ap->sock);
  620. GNUNET_CONTAINER_DLL_remove (connection->ap_head,
  621. connection->ap_tail,
  622. ap);
  623. len = sizeof (error);
  624. errno = 0;
  625. error = 0;
  626. tc = GNUNET_SCHEDULER_get_task_context ();
  627. if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
  628. (GNUNET_OK !=
  629. GNUNET_NETWORK_socket_getsockopt (ap->sock,
  630. SOL_SOCKET,
  631. SO_ERROR,
  632. &error,
  633. &len)) ||
  634. (0 != error) )
  635. {
  636. GNUNET_break (GNUNET_OK ==
  637. GNUNET_NETWORK_socket_close (ap->sock));
  638. GNUNET_free (ap);
  639. if ( (NULL == connection->ap_head) &&
  640. (GNUNET_NO == connection->dns_active) &&
  641. (NULL == connection->proxy_handshake) )
  642. connect_fail_continuation (connection);
  643. return;
  644. }
  645. GNUNET_assert (NULL == connection->sock);
  646. connection->sock = ap->sock;
  647. GNUNET_assert (NULL == connection->addr);
  648. connection->addr = GNUNET_malloc (ap->addrlen);
  649. GNUNET_memcpy (connection->addr, ap->addr, ap->addrlen);
  650. connection->addrlen = ap->addrlen;
  651. GNUNET_free (ap);
  652. /* cancel all other attempts */
  653. while (NULL != (pos = connection->ap_head))
  654. {
  655. GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
  656. GNUNET_SCHEDULER_cancel (pos->task);
  657. GNUNET_CONTAINER_DLL_remove (connection->ap_head,
  658. connection->ap_tail,
  659. pos);
  660. GNUNET_free (pos);
  661. }
  662. connect_success_continuation (connection);
  663. }
  664. /**
  665. * Try to establish a connection given the specified address.
  666. * This function is called by the resolver once we have a DNS reply.
  667. *
  668. * @param cls our `struct GNUNET_CONNECTION_Handle *`
  669. * @param addr address to try, NULL for "last call"
  670. * @param addrlen length of @a addr
  671. */
  672. static void
  673. try_connect_using_address (void *cls,
  674. const struct sockaddr *addr,
  675. socklen_t addrlen)
  676. {
  677. struct GNUNET_CONNECTION_Handle *connection = cls;
  678. struct AddressProbe *ap;
  679. struct GNUNET_TIME_Relative delay;
  680. if (NULL == addr)
  681. {
  682. connection->dns_active = NULL;
  683. if ((NULL == connection->ap_head) &&
  684. (NULL == connection->sock) &&
  685. (NULL == connection->proxy_handshake))
  686. connect_fail_continuation (connection);
  687. return;
  688. }
  689. if (NULL != connection->sock)
  690. return; /* already connected */
  691. GNUNET_assert (NULL == connection->addr);
  692. /* try to connect */
  693. LOG (GNUNET_ERROR_TYPE_DEBUG,
  694. "Trying to connect using address `%s:%u/%s:%u'\n",
  695. connection->hostname,
  696. connection->port,
  697. GNUNET_a2s (addr, addrlen),
  698. connection->port);
  699. ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen);
  700. ap->addr = (const struct sockaddr *) &ap[1];
  701. GNUNET_memcpy (&ap[1], addr, addrlen);
  702. ap->addrlen = addrlen;
  703. ap->connection = connection;
  704. switch (ap->addr->sa_family)
  705. {
  706. case AF_INET:
  707. ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port);
  708. break;
  709. case AF_INET6:
  710. ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port);
  711. break;
  712. default:
  713. GNUNET_break (0);
  714. GNUNET_free (ap);
  715. return; /* not supported by us */
  716. }
  717. ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
  718. SOCK_STREAM, 0);
  719. if (NULL == ap->sock)
  720. {
  721. GNUNET_free (ap);
  722. return; /* not supported by OS */
  723. }
  724. LOG (GNUNET_ERROR_TYPE_INFO,
  725. "Trying to connect to `%s' (%p)\n",
  726. GNUNET_a2s (ap->addr, ap->addrlen),
  727. connection);
  728. if ((GNUNET_OK !=
  729. GNUNET_NETWORK_socket_connect (ap->sock,
  730. ap->addr,
  731. ap->addrlen)) &&
  732. (EINPROGRESS != errno))
  733. {
  734. /* maybe refused / unsupported address, try next */
  735. LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect");
  736. GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
  737. GNUNET_free (ap);
  738. return;
  739. }
  740. GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap);
  741. delay = CONNECT_RETRY_TIMEOUT;
  742. if (NULL != connection->nth.notify_ready)
  743. delay = GNUNET_TIME_relative_min (delay,
  744. GNUNET_TIME_absolute_get_remaining (connection->nth.transmit_timeout));
  745. if (NULL != connection->receiver)
  746. delay = GNUNET_TIME_relative_min (delay,
  747. GNUNET_TIME_absolute_get_remaining (connection->receive_timeout));
  748. ap->task = GNUNET_SCHEDULER_add_write_net (delay,
  749. ap->sock,
  750. &connect_probe_continuation,
  751. ap);
  752. }
  753. /**
  754. * Create a connection handle by (asynchronously) connecting to a host.
  755. * This function returns immediately, even if the connection has not
  756. * yet been established. This function only creates TCP connections.
  757. *
  758. * @param cfg configuration to use
  759. * @param hostname name of the host to connect to
  760. * @param port port to connect to
  761. * @return the connection handle
  762. */
  763. struct GNUNET_CONNECTION_Handle *
  764. GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
  765. const char *hostname,
  766. uint16_t port)
  767. {
  768. struct GNUNET_CONNECTION_Handle *connection;
  769. GNUNET_assert (0 < strlen (hostname)); /* sanity check */
  770. connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
  771. connection->cfg = cfg;
  772. connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
  773. connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
  774. connection->port = port;
  775. connection->hostname = GNUNET_strdup (hostname);
  776. connection->dns_active =
  777. GNUNET_RESOLVER_ip_get (connection->hostname,
  778. AF_UNSPEC,
  779. CONNECT_RETRY_TIMEOUT,
  780. &try_connect_using_address,
  781. connection);
  782. return connection;
  783. }
  784. /**
  785. * Create a connection handle by connecting to a UNIX domain service.
  786. * This function returns immediately, even if the connection has not
  787. * yet been established. This function only creates UNIX connections.
  788. *
  789. * @param cfg configuration to use
  790. * @param unixpath path to connect to
  791. * @return the connection handle, NULL on systems without UNIX support
  792. */
  793. struct GNUNET_CONNECTION_Handle *
  794. GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct GNUNET_CONFIGURATION_Handle *cfg,
  795. const char *unixpath)
  796. {
  797. #ifdef AF_UNIX
  798. struct GNUNET_CONNECTION_Handle *connection;
  799. struct sockaddr_un *un;
  800. GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
  801. un = GNUNET_new (struct sockaddr_un);
  802. un->sun_family = AF_UNIX;
  803. strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
  804. #ifdef LINUX
  805. {
  806. int abstract;
  807. abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
  808. "TESTING",
  809. "USE_ABSTRACT_SOCKETS");
  810. if (GNUNET_YES == abstract)
  811. un->sun_path[0] = '\0';
  812. }
  813. #endif
  814. #if HAVE_SOCKADDR_UN_SUN_LEN
  815. un->sun_len = (u_char) sizeof (struct sockaddr_un);
  816. #endif
  817. connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
  818. connection->cfg = cfg;
  819. connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
  820. connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
  821. connection->port = 0;
  822. connection->hostname = NULL;
  823. connection->addr = (struct sockaddr *) un;
  824. connection->addrlen = sizeof (struct sockaddr_un);
  825. connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX,
  826. SOCK_STREAM,
  827. 0);
  828. if (NULL == connection->sock)
  829. {
  830. GNUNET_free (connection->addr);
  831. GNUNET_free (connection->write_buffer);
  832. GNUNET_free (connection);
  833. return NULL;
  834. }
  835. if ( (GNUNET_OK !=
  836. GNUNET_NETWORK_socket_connect (connection->sock,
  837. connection->addr,
  838. connection->addrlen)) &&
  839. (EINPROGRESS != errno) )
  840. {
  841. /* Just return; we expect everything to work eventually so don't fail HARD */
  842. GNUNET_break (GNUNET_OK ==
  843. GNUNET_NETWORK_socket_close (connection->sock));
  844. connection->sock = NULL;
  845. return connection;
  846. }
  847. connect_success_continuation (connection);
  848. return connection;
  849. #else
  850. return NULL;
  851. #endif
  852. }
  853. /**
  854. * Create a connection handle by (asynchronously) connecting to a host.
  855. * This function returns immediately, even if the connection has not
  856. * yet been established. This function only creates TCP connections.
  857. *
  858. * @param s socket to connect
  859. * @param serv_addr server address
  860. * @param addrlen length of @a serv_addr
  861. * @return the connection handle
  862. */
  863. struct GNUNET_CONNECTION_Handle *
  864. GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s,
  865. const struct sockaddr *serv_addr,
  866. socklen_t addrlen)
  867. {
  868. struct GNUNET_CONNECTION_Handle *connection;
  869. if ( (GNUNET_OK !=
  870. GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) &&
  871. (EINPROGRESS != errno) )
  872. {
  873. /* maybe refused / unsupported address, try next */
  874. LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
  875. "connect");
  876. LOG (GNUNET_ERROR_TYPE_DEBUG,
  877. "Attempt to connect to `%s' failed\n",
  878. GNUNET_a2s (serv_addr,
  879. addrlen));
  880. GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s));
  881. return NULL;
  882. }
  883. connection = GNUNET_CONNECTION_create_from_existing (s);
  884. connection->addr = GNUNET_malloc (addrlen);
  885. GNUNET_memcpy (connection->addr, serv_addr, addrlen);
  886. connection->addrlen = addrlen;
  887. LOG (GNUNET_ERROR_TYPE_INFO,
  888. "Trying to connect to `%s' (%p)\n",
  889. GNUNET_a2s (serv_addr, addrlen),
  890. connection);
  891. return connection;
  892. }
  893. /**
  894. * Create a connection handle by creating a socket and
  895. * (asynchronously) connecting to a host. This function returns
  896. * immediately, even if the connection has not yet been established.
  897. * This function only creates TCP connections.
  898. *
  899. * @param af_family address family to use
  900. * @param serv_addr server address
  901. * @param addrlen length of @a serv_addr
  902. * @return the connection handle
  903. */
  904. struct GNUNET_CONNECTION_Handle *
  905. GNUNET_CONNECTION_create_from_sockaddr (int af_family,
  906. const struct sockaddr *serv_addr,
  907. socklen_t addrlen)
  908. {
  909. struct GNUNET_NETWORK_Handle *s;
  910. s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
  911. if (NULL == s)
  912. {
  913. LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
  914. "socket");
  915. return NULL;
  916. }
  917. return GNUNET_CONNECTION_connect_socket (s,
  918. serv_addr,
  919. addrlen);
  920. }
  921. /**
  922. * Check if connection is valid (no fatal errors have happened so far).
  923. * Note that a connection that is still trying to connect is considered
  924. * valid.
  925. *
  926. * @param connection connection to check
  927. * @return #GNUNET_YES if valid, #GNUNET_NO otherwise
  928. */
  929. int
  930. GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection)
  931. {
  932. if ((NULL != connection->ap_head) ||
  933. (NULL != connection->dns_active) ||
  934. (NULL != connection->proxy_handshake))
  935. return GNUNET_YES; /* still trying to connect */
  936. if ( (0 != connection->destroy_later) ||
  937. (NULL == connection->sock) )
  938. return GNUNET_NO;
  939. return GNUNET_YES;
  940. }
  941. /**
  942. * Close the connection and free associated resources. There must
  943. * not be any pending requests for reading or writing to the
  944. * connection at this time.
  945. *
  946. * @param connection connection to destroy
  947. */
  948. void
  949. GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
  950. {
  951. struct AddressProbe *pos;
  952. if (0 != connection->destroy_later)
  953. {
  954. connection->destroy_later = -1;
  955. return;
  956. }
  957. LOG (GNUNET_ERROR_TYPE_DEBUG,
  958. "Shutting down connection (%p)\n",
  959. connection);
  960. GNUNET_assert (NULL == connection->nth.notify_ready);
  961. GNUNET_assert (NULL == connection->receiver);
  962. if (NULL != connection->write_task)
  963. {
  964. GNUNET_SCHEDULER_cancel (connection->write_task);
  965. connection->write_task = NULL;
  966. connection->write_buffer_off = 0;
  967. }
  968. if (NULL != connection->read_task)
  969. {
  970. GNUNET_SCHEDULER_cancel (connection->read_task);
  971. connection->read_task = NULL;
  972. }
  973. if (NULL != connection->nth.timeout_task)
  974. {
  975. GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
  976. connection->nth.timeout_task = NULL;
  977. }
  978. connection->nth.notify_ready = NULL;
  979. if (NULL != connection->dns_active)
  980. {
  981. GNUNET_RESOLVER_request_cancel (connection->dns_active);
  982. connection->dns_active = NULL;
  983. }
  984. if (NULL != connection->proxy_handshake)
  985. {
  986. /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
  987. connection->proxy_handshake->destroy_later = -1;
  988. connection->proxy_handshake = NULL; /* Not leaked ??? */
  989. }
  990. while (NULL != (pos = connection->ap_head))
  991. {
  992. GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
  993. GNUNET_SCHEDULER_cancel (pos->task);
  994. GNUNET_CONTAINER_DLL_remove (connection->ap_head,
  995. connection->ap_tail,
  996. pos);
  997. GNUNET_free (pos);
  998. }
  999. if ( (NULL != connection->sock) &&
  1000. (GNUNET_YES != connection->persist) )
  1001. {
  1002. if ((GNUNET_OK !=
  1003. GNUNET_NETWORK_socket_shutdown (connection->sock,
  1004. SHUT_RDWR)) &&
  1005. (ENOTCONN != errno) &&
  1006. (ECONNRESET != errno) )
  1007. LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
  1008. "shutdown");
  1009. }
  1010. if (NULL != connection->sock)
  1011. {
  1012. if (GNUNET_YES != connection->persist)
  1013. {
  1014. GNUNET_break (GNUNET_OK ==
  1015. GNUNET_NETWORK_socket_close (connection->sock));
  1016. }
  1017. else
  1018. {
  1019. GNUNET_NETWORK_socket_free_memory_only_ (connection->sock); /* at least no memory leak (we deliberately
  1020. * leak the socket in this special case) ... */
  1021. }
  1022. }
  1023. GNUNET_free_non_null (connection->addr);
  1024. GNUNET_free_non_null (connection->hostname);
  1025. GNUNET_free (connection->write_buffer);
  1026. GNUNET_free (connection);
  1027. }
  1028. /**
  1029. * This function is called once we either timeout
  1030. * or have data ready to read.
  1031. *
  1032. * @param cls connection to read from
  1033. */
  1034. static void
  1035. receive_ready (void *cls)
  1036. {
  1037. struct GNUNET_CONNECTION_Handle *connection = cls;
  1038. const struct GNUNET_SCHEDULER_TaskContext *tc;
  1039. char buffer[connection->max];
  1040. ssize_t ret;
  1041. GNUNET_CONNECTION_Receiver receiver;
  1042. connection->read_task = NULL;
  1043. tc = GNUNET_SCHEDULER_get_task_context ();
  1044. if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
  1045. {
  1046. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1047. "Receive from `%s' encounters error: timeout (%s, %p)\n",
  1048. GNUNET_a2s (connection->addr,
  1049. connection->addrlen),
  1050. GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (connection->receive_timeout),
  1051. GNUNET_YES),
  1052. connection);
  1053. signal_receive_timeout (connection);
  1054. return;
  1055. }
  1056. if (NULL == connection->sock)
  1057. {
  1058. /* connect failed for good */
  1059. signal_receive_error (connection, ECONNREFUSED);
  1060. return;
  1061. }
  1062. GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready,
  1063. connection->sock));
  1064. RETRY:
  1065. ret = GNUNET_NETWORK_socket_recv (connection->sock,
  1066. buffer,
  1067. connection->max);
  1068. if (-1 == ret)
  1069. {
  1070. if (EINTR == errno)
  1071. goto RETRY;
  1072. signal_receive_error (connection, errno);
  1073. return;
  1074. }
  1075. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1076. "receive_ready read %u/%u bytes from `%s' (%p)!\n",
  1077. (unsigned int) ret,
  1078. connection->max,
  1079. GNUNET_a2s (connection->addr,
  1080. connection->addrlen),
  1081. connection);
  1082. GNUNET_assert (NULL != (receiver = connection->receiver));
  1083. connection->receiver = NULL;
  1084. receiver (connection->receiver_cls,
  1085. buffer,
  1086. ret,
  1087. connection->addr,
  1088. connection->addrlen,
  1089. 0);
  1090. }
  1091. /**
  1092. * Receive data from the given connection. Note that this function
  1093. * will call @a receiver asynchronously using the scheduler. It will
  1094. * "immediately" return. Note that there MUST only be one active
  1095. * receive call per connection at any given point in time (so do not
  1096. * call receive again until the receiver callback has been invoked).
  1097. *
  1098. * @param connection connection handle
  1099. * @param max maximum number of bytes to read
  1100. * @param timeout maximum amount of time to wait
  1101. * @param receiver function to call with received data
  1102. * @param receiver_cls closure for @a receiver
  1103. * @return #GNUNET_SYSERR if @a connection died (receiver was
  1104. * called with error)
  1105. */
  1106. int
  1107. GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection,
  1108. size_t max,
  1109. struct GNUNET_TIME_Relative timeout,
  1110. GNUNET_CONNECTION_Receiver receiver,
  1111. void *receiver_cls)
  1112. {
  1113. GNUNET_assert ((NULL == connection->read_task) &&
  1114. (NULL == connection->receiver));
  1115. GNUNET_assert (NULL != receiver);
  1116. connection->receiver = receiver;
  1117. connection->receiver_cls = receiver_cls;
  1118. connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
  1119. connection->max = max;
  1120. if (NULL != connection->sock)
  1121. {
  1122. connection->read_task =
  1123. GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
  1124. (connection->receive_timeout),
  1125. connection->sock,
  1126. &receive_ready,
  1127. connection);
  1128. return GNUNET_OK;
  1129. }
  1130. if ((NULL == connection->dns_active) &&
  1131. (NULL == connection->ap_head) &&
  1132. (NULL == connection->proxy_handshake))
  1133. {
  1134. connection->receiver = NULL;
  1135. receiver (receiver_cls,
  1136. NULL, 0,
  1137. NULL, 0,
  1138. ETIMEDOUT);
  1139. return GNUNET_SYSERR;
  1140. }
  1141. return GNUNET_OK;
  1142. }
  1143. /**
  1144. * Cancel receive job on the given connection. Note that the
  1145. * receiver callback must not have been called yet in order
  1146. * for the cancellation to be valid.
  1147. *
  1148. * @param connection connection handle
  1149. * @return closure of the original receiver callback closure
  1150. */
  1151. void *
  1152. GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection)
  1153. {
  1154. if (NULL != connection->read_task)
  1155. {
  1156. GNUNET_assert (connection ==
  1157. GNUNET_SCHEDULER_cancel (connection->read_task));
  1158. connection->read_task = NULL;
  1159. }
  1160. connection->receiver = NULL;
  1161. return connection->receiver_cls;
  1162. }
  1163. /**
  1164. * Try to call the transmit notify method (check if we do
  1165. * have enough space available first)!
  1166. *
  1167. * @param connection connection for which we should do this processing
  1168. * @return #GNUNET_YES if we were able to call notify
  1169. */
  1170. static int
  1171. process_notify (struct GNUNET_CONNECTION_Handle *connection)
  1172. {
  1173. size_t used;
  1174. size_t avail;
  1175. size_t size;
  1176. GNUNET_CONNECTION_TransmitReadyNotify notify;
  1177. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1178. "process_notify is running\n");
  1179. GNUNET_assert (NULL == connection->write_task);
  1180. if (NULL == (notify = connection->nth.notify_ready))
  1181. {
  1182. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1183. "No one to notify\n");
  1184. return GNUNET_NO;
  1185. }
  1186. used = connection->write_buffer_off - connection->write_buffer_pos;
  1187. avail = connection->write_buffer_size - used;
  1188. size = connection->nth.notify_size;
  1189. if (size > avail)
  1190. {
  1191. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1192. "Not enough buffer\n");
  1193. return GNUNET_NO;
  1194. }
  1195. connection->nth.notify_ready = NULL;
  1196. if (connection->write_buffer_size - connection->write_buffer_off < size)
  1197. {
  1198. /* need to compact */
  1199. memmove (connection->write_buffer,
  1200. &connection->write_buffer[connection->write_buffer_pos],
  1201. used);
  1202. connection->write_buffer_off -= connection->write_buffer_pos;
  1203. connection->write_buffer_pos = 0;
  1204. }
  1205. avail = connection->write_buffer_size - connection->write_buffer_off;
  1206. GNUNET_assert (avail >= size);
  1207. size =
  1208. notify (connection->nth.notify_ready_cls, avail,
  1209. &connection->write_buffer[connection->write_buffer_off]);
  1210. GNUNET_assert (size <= avail);
  1211. if (0 != size)
  1212. connection->write_buffer_off += size;
  1213. return GNUNET_YES;
  1214. }
  1215. /**
  1216. * Task invoked by the scheduler when a call to transmit
  1217. * is timing out (we never got enough buffer space to call
  1218. * the callback function before the specified timeout
  1219. * expired).
  1220. *
  1221. * This task notifies the client about the timeout.
  1222. *
  1223. * @param cls the `struct GNUNET_CONNECTION_Handle`
  1224. */
  1225. static void
  1226. transmit_timeout (void *cls)
  1227. {
  1228. struct GNUNET_CONNECTION_Handle *connection = cls;
  1229. GNUNET_CONNECTION_TransmitReadyNotify notify;
  1230. connection->nth.timeout_task = NULL;
  1231. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1232. "Transmit to `%s:%u/%s' fails, time out reached (%p).\n",
  1233. connection->hostname,
  1234. connection->port,
  1235. GNUNET_a2s (connection->addr,
  1236. connection->addrlen),
  1237. connection);
  1238. notify = connection->nth.notify_ready;
  1239. GNUNET_assert (NULL != notify);
  1240. connection->nth.notify_ready = NULL;
  1241. notify (connection->nth.notify_ready_cls,
  1242. 0,
  1243. NULL);
  1244. }
  1245. /**
  1246. * Task invoked by the scheduler when we failed to connect
  1247. * at the time of being asked to transmit.
  1248. *
  1249. * This task notifies the client about the error.
  1250. *
  1251. * @param cls the `struct GNUNET_CONNECTION_Handle`
  1252. */
  1253. static void
  1254. connect_error (void *cls)
  1255. {
  1256. struct GNUNET_CONNECTION_Handle *connection = cls;
  1257. GNUNET_CONNECTION_TransmitReadyNotify notify;
  1258. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1259. "Transmission request of size %u fails (%s/%u), connection failed (%p).\n",
  1260. connection->nth.notify_size,
  1261. connection->hostname,
  1262. connection->port,
  1263. connection);
  1264. connection->write_task = NULL;
  1265. notify = connection->nth.notify_ready;
  1266. connection->nth.notify_ready = NULL;
  1267. notify (connection->nth.notify_ready_cls,
  1268. 0,
  1269. NULL);
  1270. }
  1271. /**
  1272. * We are ready to transmit (or got a timeout).
  1273. *
  1274. * @param cls our connection handle
  1275. */
  1276. static void
  1277. transmit_ready (void *cls)
  1278. {
  1279. struct GNUNET_CONNECTION_Handle *connection = cls;
  1280. GNUNET_CONNECTION_TransmitReadyNotify notify;
  1281. const struct GNUNET_SCHEDULER_TaskContext *tc;
  1282. ssize_t ret;
  1283. size_t have;
  1284. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1285. "transmit_ready running (%p).\n",
  1286. connection);
  1287. GNUNET_assert (NULL != connection->write_task);
  1288. connection->write_task = NULL;
  1289. GNUNET_assert (NULL == connection->nth.timeout_task);
  1290. tc = GNUNET_SCHEDULER_get_task_context ();
  1291. if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
  1292. {
  1293. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1294. "Transmit to `%s' fails, time out reached (%p).\n",
  1295. GNUNET_a2s (connection->addr,
  1296. connection->addrlen),
  1297. connection);
  1298. notify = connection->nth.notify_ready;
  1299. GNUNET_assert (NULL != notify);
  1300. connection->nth.notify_ready = NULL;
  1301. notify (connection->nth.notify_ready_cls, 0, NULL);
  1302. return;
  1303. }
  1304. GNUNET_assert (NULL != connection->sock);
  1305. if (NULL == tc->write_ready)
  1306. {
  1307. /* special circumstances (in particular, PREREQ_DONE after
  1308. * connect): not yet ready to write, but no "fatal" error either.
  1309. * Hence retry. */
  1310. goto SCHEDULE_WRITE;
  1311. }
  1312. if (! GNUNET_NETWORK_fdset_isset (tc->write_ready,
  1313. connection->sock))
  1314. {
  1315. GNUNET_assert (NULL == connection->write_task);
  1316. /* special circumstances (in particular, shutdown): not yet ready
  1317. * to write, but no "fatal" error either. Hence retry. */
  1318. goto SCHEDULE_WRITE;
  1319. }
  1320. GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos);
  1321. if ((NULL != connection->nth.notify_ready) &&
  1322. (connection->write_buffer_size < connection->nth.notify_size))
  1323. {
  1324. connection->write_buffer =
  1325. GNUNET_realloc (connection->write_buffer, connection->nth.notify_size);
  1326. connection->write_buffer_size = connection->nth.notify_size;
  1327. }
  1328. process_notify (connection);
  1329. have = connection->write_buffer_off - connection->write_buffer_pos;
  1330. if (0 == have)
  1331. {
  1332. /* no data ready for writing, terminate write loop */
  1333. return;
  1334. }
  1335. GNUNET_assert (have <= connection->write_buffer_size);
  1336. GNUNET_assert (have + connection->write_buffer_pos <= connection->write_buffer_size);
  1337. GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
  1338. RETRY:
  1339. ret =
  1340. GNUNET_NETWORK_socket_send (connection->sock,
  1341. &connection->write_buffer[connection->write_buffer_pos],
  1342. have);
  1343. if (-1 == ret)
  1344. {
  1345. if (EINTR == errno)
  1346. goto RETRY;
  1347. if (NULL != connection->write_task)
  1348. {
  1349. GNUNET_SCHEDULER_cancel (connection->write_task);
  1350. connection->write_task = NULL;
  1351. }
  1352. signal_transmit_error (connection, errno);
  1353. return;
  1354. }
  1355. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1356. "Connection transmitted %u/%u bytes to `%s' (%p)\n",
  1357. (unsigned int) ret,
  1358. have,
  1359. GNUNET_a2s (connection->addr,
  1360. connection->addrlen),
  1361. connection);
  1362. connection->write_buffer_pos += ret;
  1363. if (connection->write_buffer_pos == connection->write_buffer_off)
  1364. {
  1365. /* transmitted all pending data */
  1366. connection->write_buffer_pos = 0;
  1367. connection->write_buffer_off = 0;
  1368. }
  1369. if ( (0 == connection->write_buffer_off) &&
  1370. (NULL == connection->nth.notify_ready) )
  1371. return; /* all data sent! */
  1372. /* not done writing, schedule more */
  1373. SCHEDULE_WRITE:
  1374. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1375. "Re-scheduling transmit_ready (more to do) (%p).\n",
  1376. connection);
  1377. have = connection->write_buffer_off - connection->write_buffer_pos;
  1378. GNUNET_assert ( (NULL != connection->nth.notify_ready) ||
  1379. (have > 0) );
  1380. if (NULL == connection->write_task)
  1381. connection->write_task =
  1382. GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready ==
  1383. NULL) ? GNUNET_TIME_UNIT_FOREVER_REL :
  1384. GNUNET_TIME_absolute_get_remaining
  1385. (connection->nth.transmit_timeout),
  1386. connection->sock,
  1387. &transmit_ready, connection);
  1388. }
  1389. /**
  1390. * Ask the connection to call us once the specified number of bytes
  1391. * are free in the transmission buffer. Will never call the @a notify
  1392. * callback in this task, but always first go into the scheduler.
  1393. *
  1394. * @param connection connection
  1395. * @param size number of bytes to send
  1396. * @param timeout after how long should we give up (and call
  1397. * @a notify with buf NULL and size 0)?
  1398. * @param notify function to call
  1399. * @param notify_cls closure for @a notify
  1400. * @return non-NULL if the notify callback was queued,
  1401. * NULL if we are already going to notify someone else (busy)
  1402. */
  1403. struct GNUNET_CONNECTION_TransmitHandle *
  1404. GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection,
  1405. size_t size,
  1406. struct GNUNET_TIME_Relative timeout,
  1407. GNUNET_CONNECTION_TransmitReadyNotify notify,
  1408. void *notify_cls)
  1409. {
  1410. if (NULL != connection->nth.notify_ready)
  1411. {
  1412. GNUNET_assert (0);
  1413. return NULL;
  1414. }
  1415. GNUNET_assert (NULL != notify);
  1416. GNUNET_assert (size < GNUNET_MAX_MESSAGE_SIZE);
  1417. GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size);
  1418. GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
  1419. GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off);
  1420. connection->nth.notify_ready = notify;
  1421. connection->nth.notify_ready_cls = notify_cls;
  1422. connection->nth.connection = connection;
  1423. connection->nth.notify_size = size;
  1424. connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
  1425. GNUNET_assert (NULL == connection->nth.timeout_task);
  1426. if ((NULL == connection->sock) &&
  1427. (NULL == connection->ap_head) &&
  1428. (NULL == connection->dns_active) &&
  1429. (NULL == connection->proxy_handshake))
  1430. {
  1431. if (NULL != connection->write_task)
  1432. GNUNET_SCHEDULER_cancel (connection->write_task);
  1433. connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error,
  1434. connection);
  1435. return &connection->nth;
  1436. }
  1437. if (NULL != connection->write_task)
  1438. return &connection->nth; /* previous transmission still in progress */
  1439. if (NULL != connection->sock)
  1440. {
  1441. /* connected, try to transmit now */
  1442. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1443. "Scheduling transmission (%p).\n",
  1444. connection);
  1445. connection->write_task =
  1446. GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
  1447. (connection->nth.transmit_timeout),
  1448. connection->sock,
  1449. &transmit_ready, connection);
  1450. return &connection->nth;
  1451. }
  1452. /* not yet connected, wait for connection */
  1453. LOG (GNUNET_ERROR_TYPE_DEBUG,
  1454. "Need to wait to schedule transmission for connection, adding timeout task (%p).\n",
  1455. connection);
  1456. connection->nth.timeout_task =
  1457. GNUNET_SCHEDULER_add_delayed (timeout,
  1458. &transmit_timeout,
  1459. connection);
  1460. return &connection->nth;
  1461. }
  1462. /**
  1463. * Cancel the specified transmission-ready notification.
  1464. *
  1465. * @param th notification to cancel
  1466. */
  1467. void
  1468. GNUNET_CONNECTION_notify_transmit_ready_cancel (struct GNUNET_CONNECTION_TransmitHandle *th)
  1469. {
  1470. GNUNET_assert (NULL != th->notify_ready);
  1471. th->notify_ready = NULL;
  1472. if (NULL != th->timeout_task)
  1473. {
  1474. GNUNET_SCHEDULER_cancel (th->timeout_task);
  1475. th->timeout_task = NULL;
  1476. }
  1477. if (NULL != th->connection->write_task)
  1478. {
  1479. GNUNET_SCHEDULER_cancel (th->connection->write_task);
  1480. th->connection->write_task = NULL;
  1481. }
  1482. }
  1483. /**
  1484. * Create a connection to be proxied using a given connection.
  1485. *
  1486. * @param cph connection to proxy server
  1487. * @return connection to be proxied
  1488. */
  1489. struct GNUNET_CONNECTION_Handle *
  1490. GNUNET_CONNECTION_create_proxied_from_handshake (struct GNUNET_CONNECTION_Handle *cph)
  1491. {
  1492. struct GNUNET_CONNECTION_Handle *proxied = GNUNET_CONNECTION_create_from_existing (NULL);
  1493. proxied->proxy_handshake = cph;
  1494. return proxied;
  1495. }
  1496. /**
  1497. * Activate proxied connection and destroy initial proxy handshake connection.
  1498. * There must not be any pending requests for reading or writing to the
  1499. * proxy hadshake connection at this time.
  1500. *
  1501. * @param proxied connection connection to proxy server
  1502. */
  1503. void
  1504. GNUNET_CONNECTION_acivate_proxied (struct GNUNET_CONNECTION_Handle *proxied)
  1505. {
  1506. struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake;
  1507. GNUNET_assert (NULL != cph);
  1508. GNUNET_assert (NULL == proxied->sock);
  1509. GNUNET_assert (NULL != cph->sock);
  1510. proxied->sock = cph->sock;
  1511. cph->sock = NULL;
  1512. GNUNET_CONNECTION_destroy (cph);
  1513. connect_success_continuation (proxied);
  1514. }
  1515. /* end of connection.c */