tcp_connection_legacy.c 48 KB

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