GNUnet  0.10.x
tcp_server_legacy.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2013 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
20 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_protocols.h"
30 
31 #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-server", syscall, filename)
32 
33 
38 {
42  struct HandlerList *next;
43 
48 };
49 
50 
54 struct NotifyList
55 {
59  struct NotifyList *next;
60 
64  struct NotifyList *prev;
65 
70 
74  void *callback_cls;
75 };
76 
77 
82 {
87 
92 
97 
102 
107 
112 
117 
122 
127 
133 
138  struct GNUNET_TIME_Relative idle_timeout;
139 
144 
149 
154 
159 
163  void *mst_cls;
164 
170 
179 };
180 
181 
186 {
191 
196 
201 
202 };
203 
204 
209 {
210 
215 
220 
224  void *mst;
225 
230 
235 
241 
246 
251 
255  struct GNUNET_TIME_Absolute warn_start;
256 
261  struct GNUNET_TIME_Absolute last_activity;
262 
268 
273  struct GNUNET_TIME_Relative idle_timeout;
274 
279  unsigned int reference_count;
280 
287  unsigned int suspended;
288 
294 
304 
309 
316 
322  int persist;
323 
330 
334  uint16_t warn_type;
335 };
336 
337 
338 
347 void *
349  size_t size)
350 {
351  if ((0 == client->user_context_size) &&
352  (NULL == client->user_context))
353  return NULL; /* never set */
354  GNUNET_assert (size == client->user_context_size);
355  return client->user_context;
356 }
357 
358 
367 void
369  void *ptr,
370  size_t size)
371 {
372  if (NULL == ptr)
373  {
374  client->user_context_size = 0;
375  client->user_context = ptr;
376  return;
377  }
378  client->user_context_size = size;
379  client->user_context = ptr;
380 }
381 
382 
389 static void
391 {
392  struct GNUNET_SERVER_Handle *server = cls;
393  const struct GNUNET_SCHEDULER_TaskContext *tc;
395  unsigned int i;
396 
397  server->listen_task = NULL;
399  for (i = 0; NULL != server->listen_sockets[i]; i++)
400  {
402  server->listen_sockets[i]))
403  {
404  sock =
406  server->access_cb_cls,
407  server->listen_sockets[i]);
408  if (NULL != sock)
409  {
411  "Server accepted incoming connection.\n");
412  (void) GNUNET_SERVER_connect_socket (server,
413  sock);
414  }
415  }
416  }
417  /* listen for more! */
418  GNUNET_SERVER_resume (server);
419 }
420 
421 
429 static struct GNUNET_NETWORK_Handle *
430 open_listen_socket (const struct sockaddr *server_addr,
431  socklen_t socklen)
432 {
433  struct GNUNET_NETWORK_Handle *sock;
434  uint16_t port;
435  int eno;
436 
437  switch (server_addr->sa_family)
438  {
439  case AF_INET:
440  port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
441  break;
442  case AF_INET6:
443  port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
444  break;
445  case AF_UNIX:
446  port = 0;
447  break;
448  default:
449  GNUNET_break (0);
450  port = 0;
451  break;
452  }
453  sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, SOCK_STREAM, 0);
454  if (NULL == sock)
455  {
457  errno = 0;
458  return NULL;
459  }
460  /* bind the socket */
461  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, server_addr, socklen))
462  {
463  eno = errno;
464  if (EADDRINUSE != errno)
465  {
466  /* we don't log 'EADDRINUSE' here since an IPv4 bind may
467  * fail if we already took the port on IPv6; if both IPv4 and
468  * IPv6 binds fail, then our caller will log using the
469  * errno preserved in 'eno' */
471  "bind");
472  if (0 != port)
474  _("`%s' failed for port %d (%s).\n"),
475  "bind",
476  port,
477  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
478  eno = 0;
479  }
480  else
481  {
482  if (0 != port)
484  _("`%s' failed for port %d (%s): address already in use\n"),
485  "bind", port,
486  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
487  else if (AF_UNIX == server_addr->sa_family)
488  {
490  _("`%s' failed for `%s': address already in use\n"),
491  "bind",
492  GNUNET_a2s (server_addr, socklen));
493  }
494  }
496  errno = eno;
497  return NULL;
498  }
499  if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
500  {
502  "listen");
504  errno = 0;
505  return NULL;
506  }
507  if (0 != port)
509  "Server starts to listen on port %u.\n",
510  port);
511  return sock;
512 }
513 
514 
527 struct GNUNET_SERVER_Handle *
529  void *access_cb_cls,
530  struct GNUNET_NETWORK_Handle **lsocks,
532  int require_found)
533 {
534  struct GNUNET_SERVER_Handle *server;
535 
536  server = GNUNET_new (struct GNUNET_SERVER_Handle);
537  server->idle_timeout = idle_timeout;
538  server->listen_sockets = lsocks;
539  server->access_cb = access_cb;
540  server->access_cb_cls = access_cb_cls;
541  server->require_found = require_found;
542  if (NULL != lsocks)
543  GNUNET_SERVER_resume (server);
544  return server;
545 }
546 
547 
561 struct GNUNET_SERVER_Handle *
563  void *access_cb_cls,
564  struct sockaddr *const *server_addr,
565  const socklen_t * socklen,
567  int require_found)
568 {
569  struct GNUNET_NETWORK_Handle **lsocks;
570  unsigned int i;
571  unsigned int j;
572  unsigned int k;
573  int seen;
574 
575  i = 0;
576  while (NULL != server_addr[i])
577  i++;
578  if (i > 0)
579  {
580  lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
581  i = 0;
582  j = 0;
583  while (NULL != server_addr[i])
584  {
585  seen = 0;
586  for (k=0;k<i;k++)
587  if ( (socklen[k] == socklen[i]) &&
588  (0 == memcmp (server_addr[k], server_addr[i], socklen[i])) )
589  {
590  seen = 1;
591  break;
592  }
593  if (0 != seen)
594  {
595  /* duplicate address, skip */
596  i++;
597  continue;
598  }
599  lsocks[j] = open_listen_socket (server_addr[i], socklen[i]);
600  if (NULL != lsocks[j])
601  j++;
602  i++;
603  }
604  if (0 == j)
605  {
606  if (0 != errno)
608  GNUNET_free (lsocks);
609  lsocks = NULL;
610  }
611  }
612  else
613  {
614  lsocks = NULL;
615  }
616  return GNUNET_SERVER_create_with_sockets (access_cb,
617  access_cb_cls,
618  lsocks,
619  idle_timeout,
620  require_found);
621 }
622 
623 
636 void
638 {
640  "Marking client as monitor!\n");
641  client->is_monitor = GNUNET_YES;
642 }
643 
644 
651 static void
652 do_destroy (void *cls)
653 {
654  struct GNUNET_SERVER_Handle *server = cls;
655 
656  GNUNET_SERVER_destroy (server);
657 }
658 
659 
666 static void
668 {
669  struct GNUNET_SERVER_Client *client;
670 
671  if (GNUNET_YES != server->in_soft_shutdown)
672  return;
673  for (client = server->clients_head; NULL != client; client = client->next)
674  if (GNUNET_NO == client->is_monitor)
675  return; /* not done yet */
677  (void) GNUNET_SCHEDULER_add_now (&do_destroy, server);
678 }
679 
680 
686 void
688 {
689  if (NULL != server->listen_task)
690  {
692  server->listen_task = NULL;
693  }
694 }
695 
696 
702 void
704 {
705  struct GNUNET_NETWORK_FDSet *r;
706  unsigned int i;
707 
708  if (NULL == server->listen_sockets)
709  return;
710  if (NULL == server->listen_sockets[0])
711  return; /* nothing to do, no listen sockets! */
712  if (NULL == server->listen_sockets[1])
713  {
714  /* simplified method: no fd set needed; this is then much simpler
715  and much more efficient */
716  server->listen_task =
719  server->listen_sockets[0],
720  &process_listen_socket, server);
721  return;
722  }
724  i = 0;
725  while (NULL != server->listen_sockets[i])
726  GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
727  server->listen_task =
730  &process_listen_socket, server);
732 }
733 
734 
741 void
743 {
744  unsigned int i;
745 
747  "Server in soft shutdown\n");
748  if (NULL != server->listen_task)
749  {
751  server->listen_task = NULL;
752  }
753  if (NULL != server->listen_sockets)
754  {
755  i = 0;
756  while (NULL != server->listen_sockets[i])
759  GNUNET_free (server->listen_sockets);
760  server->listen_sockets = NULL;
761  }
762  if (GNUNET_NO == server->in_soft_shutdown)
763  server->in_soft_shutdown = GNUNET_YES;
764  test_monitor_clients (server);
765 }
766 
767 
773 void
775 {
776  struct HandlerList *hpos;
777  struct NotifyList *npos;
778  unsigned int i;
779 
781  "Server shutting down.\n");
782  if (NULL != server->listen_task)
783  {
785  server->listen_task = NULL;
786  }
787  if (NULL != server->listen_sockets)
788  {
789  i = 0;
790  while (NULL != server->listen_sockets[i])
793  GNUNET_free (server->listen_sockets);
794  server->listen_sockets = NULL;
795  }
796  while (NULL != server->clients_head)
798  while (NULL != (hpos = server->handlers))
799  {
800  server->handlers = hpos->next;
801  GNUNET_free (hpos);
802  }
803  while (NULL != (npos = server->disconnect_notify_list_head))
804  {
805  npos->callback (npos->callback_cls,
806  NULL);
809  npos);
810  GNUNET_free (npos);
811  }
812  while (NULL != (npos = server->connect_notify_list_head))
813  {
814  npos->callback (npos->callback_cls,
815  NULL);
817  server->connect_notify_list_tail,
818  npos);
819  GNUNET_free (npos);
820  }
821  GNUNET_free (server);
822 }
823 
824 
838 void
841 {
842  struct HandlerList *p;
843 
844  p = GNUNET_new (struct HandlerList);
845  p->handlers = handlers;
846  p->next = server->handlers;
847  server->handlers = p;
848 }
849 
850 
861 void
866  void *cls)
867 {
868  server->mst_create = create;
869  server->mst_destroy = destroy;
870  server->mst_receive = receive;
871  server->mst_cls = cls;
872 }
873 
874 
880 static void
882 {
883  struct GNUNET_SERVER_Client *client = cls;
884 
885  GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
886  client->warn_task =
888  &warn_no_receive_done, client);
890  _("Processing code for message of type %u did not call `GNUNET_SERVER_receive_done' after %s\n"),
891  (unsigned int) client->warn_type,
893  GNUNET_YES));
894 }
895 
896 
904 void
906 {
907  if (NULL != client->warn_task)
908  {
910  client->warn_task = NULL;
911  }
912 }
913 
914 
930 int
932  struct GNUNET_SERVER_Client *sender,
933  const struct GNUNET_MessageHeader *message)
934 {
935  struct HandlerList *pos;
936  const struct GNUNET_SERVER_MessageHandler *mh;
937  unsigned int i;
938  uint16_t type;
939  uint16_t size;
940  int found;
941 
942  type = ntohs (message->type);
943  size = ntohs (message->size);
945  "Received message of type %u and size %u from client\n",
946  type, size);
947  found = GNUNET_NO;
948  for (pos = server->handlers; NULL != pos; pos = pos->next)
949  {
950  i = 0;
951  while (pos->handlers[i].callback != NULL)
952  {
953  mh = &pos->handlers[i];
954  if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
955  {
956  if ((0 != mh->expected_size) && (mh->expected_size != size))
957  {
958 #if GNUNET8_NETWORK_IS_DEAD
960  "Expected %u bytes for message of type %u, got %u\n",
961  mh->expected_size, mh->type, size);
962  GNUNET_break_op (0);
963 #else
965  "Expected %u bytes for message of type %u, got %u\n",
966  mh->expected_size, mh->type, size);
967 #endif
968  return GNUNET_SYSERR;
969  }
970  if (NULL != sender)
971  {
972  if ( (0 == sender->suspended) &&
973  (NULL == sender->warn_task) )
974  {
975  GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */
977  sender->warn_task =
980  sender);
981  sender->warn_type = type;
982  }
983  sender->suspended++;
984  }
985  mh->callback (mh->callback_cls, sender, message);
986  found = GNUNET_YES;
987  }
988  i++;
989  }
990  }
991  if (GNUNET_NO == found)
992  {
994  "Received message of unknown type %d\n", type);
995  if (GNUNET_YES == server->require_found)
996  return GNUNET_SYSERR;
997  }
998  return GNUNET_OK;
999 }
1000 
1001 
1012 static void
1013 process_incoming (void *cls,
1014  const void *buf,
1015  size_t available,
1016  const struct sockaddr *addr,
1017  socklen_t addrlen,
1018  int errCode);
1019 
1020 
1034 static void
1036  int ret)
1037 {
1038  while ((GNUNET_SYSERR != ret) && (NULL != client->server) &&
1039  (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
1040  {
1041  if (GNUNET_OK == ret)
1042  {
1044  "Server re-enters receive loop, timeout: %s.\n",
1046  client->receive_pending = GNUNET_YES;
1047  if (GNUNET_OK !=
1050  client->idle_timeout,
1052  client))
1053  return;
1054  break;
1055  }
1057  "Server processes additional messages instantly.\n");
1058  if (NULL != client->server->mst_receive)
1059  ret =
1060  client->server->mst_receive (client->server->mst_cls, client->mst,
1061  client, NULL, 0, GNUNET_NO, GNUNET_YES);
1062  else
1063  ret =
1064  GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO,
1065  GNUNET_YES);
1066  }
1068  "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
1069  ret, client->server,
1070  client->shutdown_now,
1071  client->suspended);
1072  if (GNUNET_NO == ret)
1073  {
1075  "Server has more data pending but is suspended.\n");
1076  client->receive_pending = GNUNET_SYSERR; /* data pending */
1077  }
1078  if ( (GNUNET_SYSERR == ret) ||
1079  (GNUNET_YES == client->shutdown_now) )
1081 }
1082 
1083 
1094 static void
1095 process_incoming (void *cls,
1096  const void *buf,
1097  size_t available,
1098  const struct sockaddr *addr,
1099  socklen_t addrlen,
1100  int errCode)
1101 {
1102  struct GNUNET_SERVER_Client *client = cls;
1103  struct GNUNET_SERVER_Handle *server = client->server;
1104  struct GNUNET_TIME_Absolute end;
1105  struct GNUNET_TIME_Absolute now;
1106  int ret;
1107 
1109  client->receive_pending = GNUNET_NO;
1110  now = GNUNET_TIME_absolute_get ();
1111  end = GNUNET_TIME_absolute_add (client->last_activity,
1112  client->idle_timeout);
1113 
1114  if ( (NULL == buf) &&
1115  (0 == available) &&
1116  (NULL == addr) &&
1117  (0 == errCode) &&
1118  (GNUNET_YES != client->shutdown_now) &&
1119  (NULL != server) &&
1121  (end.abs_value_us > now.abs_value_us) )
1122  {
1123  /* wait longer, timeout changed (i.e. due to us sending) */
1125  "Receive time out, but no disconnect due to sending (%p)\n",
1126  client);
1127  client->receive_pending = GNUNET_YES;
1132  client);
1133  return;
1134  }
1135  if ( (NULL == buf) ||
1136  (0 == available) ||
1137  (0 != errCode) ||
1138  (NULL == server) ||
1139  (GNUNET_YES == client->shutdown_now) ||
1141  {
1142  /* other side closed connection, error connecting, etc. */
1144  "Failed to connect or other side closed connection (%p)\n",
1145  client);
1147  return;
1148  }
1150  "Server receives %u bytes from `%s'.\n",
1151  (unsigned int) available,
1152  GNUNET_a2s (addr, addrlen));
1153  GNUNET_SERVER_client_keep (client);
1154  client->last_activity = now;
1155 
1156  if (NULL != server->mst_receive)
1157  {
1158  ret = client->server->mst_receive (client->server->mst_cls,
1159  client->mst,
1160  client,
1161  buf,
1162  available,
1163  GNUNET_NO,
1164  GNUNET_YES);
1165  }
1166  else if (NULL != client->mst)
1167  {
1168  ret =
1169  GNUNET_SERVER_mst_receive (client->mst,
1170  client,
1171  buf,
1172  available,
1173  GNUNET_NO,
1174  GNUNET_YES);
1175  }
1176  else
1177  {
1178  GNUNET_break (0);
1179  return;
1180  }
1181  process_mst (client,
1182  ret);
1183  GNUNET_SERVER_client_drop (client);
1184 }
1185 
1186 
1193 static void
1195 {
1196  struct GNUNET_SERVER_Client *client = cls;
1197 
1198  GNUNET_assert (GNUNET_YES != client->shutdown_now);
1199  client->restart_task = NULL;
1200  if (GNUNET_NO == client->receive_pending)
1201  {
1202  LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n");
1203  client->receive_pending = GNUNET_YES;
1206  client->idle_timeout,
1208  client);
1209  return;
1210  }
1212  "Server continues processing messages still in the buffer.\n");
1213  GNUNET_SERVER_client_keep (client);
1214  client->receive_pending = GNUNET_NO;
1215  process_mst (client,
1216  GNUNET_NO);
1217  GNUNET_SERVER_client_drop (client);
1218 }
1219 
1220 
1231 static int
1233  void *client,
1234  const struct GNUNET_MessageHeader *message)
1235 {
1236  struct GNUNET_SERVER_Handle *server = cls;
1237  struct GNUNET_SERVER_Client *sender = client;
1238  int ret;
1239 
1241  "Tokenizer gives server message of type %u and size %u from client\n",
1242  ntohs (message->type), ntohs (message->size));
1244  ret = GNUNET_SERVER_inject (server, sender, message);
1246  if ( (GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now) )
1247  {
1249  return GNUNET_SYSERR;
1250  }
1251  return GNUNET_OK;
1252 }
1253 
1254 
1266 struct GNUNET_SERVER_Client *
1269 {
1270  struct GNUNET_SERVER_Client *client;
1271  struct NotifyList *n;
1272 
1273  client = GNUNET_new (struct GNUNET_SERVER_Client);
1274  client->connection = connection;
1275  client->server = server;
1277  client->idle_timeout = server->idle_timeout;
1279  server->clients_tail,
1280  client);
1281  if (NULL != server->mst_create)
1282  client->mst =
1283  server->mst_create (server->mst_cls, client);
1284  else
1285  client->mst =
1287  server);
1288  GNUNET_assert (NULL != client->mst);
1289  for (n = server->connect_notify_list_head; NULL != n; n = n->next)
1290  n->callback (n->callback_cls, client);
1291  client->receive_pending = GNUNET_YES;
1292  if (GNUNET_SYSERR ==
1295  client->idle_timeout,
1297  client))
1298  return NULL;
1299  return client;
1300 }
1301 
1302 
1311 void
1314 {
1315  client->idle_timeout = timeout;
1316 }
1317 
1318 
1326 void
1328 {
1329  client->reference_count++;
1330 }
1331 
1332 
1341 void
1343 {
1344  GNUNET_assert (client->reference_count > 0);
1345  client->reference_count--;
1346  if ((GNUNET_YES == client->shutdown_now) && (0 == client->reference_count))
1348 }
1349 
1350 
1359 int
1361  void **addr, size_t * addrlen)
1362 {
1363  return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen);
1364 }
1365 
1366 
1377 void
1380  void *callback_cls)
1381 {
1382  struct NotifyList *n;
1383 
1384  n = GNUNET_new (struct NotifyList);
1385  n->callback = callback;
1389  n);
1390 }
1391 
1392 
1406 void
1409  void *callback_cls)
1410 {
1411  struct NotifyList *n;
1412  struct GNUNET_SERVER_Client *client;
1413 
1414  n = GNUNET_new (struct NotifyList);
1415  n->callback = callback;
1416  n->callback_cls = callback_cls;
1418  server->connect_notify_list_tail,
1419  n);
1420  for (client = server->clients_head; NULL != client; client = client->next)
1421  callback (callback_cls, client);
1422 }
1423 
1424 
1432 void
1435  void *callback_cls)
1436 {
1437  struct NotifyList *pos;
1438 
1439  for (pos = server->disconnect_notify_list_head; NULL != pos; pos = pos->next)
1440  if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
1441  break;
1442  if (NULL == pos)
1443  {
1444  GNUNET_break (0);
1445  return;
1446  }
1449  pos);
1450  GNUNET_free (pos);
1451 }
1452 
1453 
1461 void
1464  void *callback_cls)
1465 {
1466  struct NotifyList *pos;
1467 
1468  for (pos = server->connect_notify_list_head; NULL != pos; pos = pos->next)
1469  if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
1470  break;
1471  if (NULL == pos)
1472  {
1473  GNUNET_break (0);
1474  return;
1475  }
1477  server->connect_notify_list_tail,
1478  pos);
1479  GNUNET_free (pos);
1480 }
1481 
1482 
1491 void
1493 {
1494  struct GNUNET_SERVER_Handle *server = client->server;
1495  struct NotifyList *n;
1496 
1498  "Client is being disconnected from the server.\n");
1499  if (NULL != client->restart_task)
1500  {
1502  client->restart_task = NULL;
1503  }
1504  if (NULL != client->warn_task)
1505  {
1507  client->warn_task = NULL;
1508  }
1509  if (GNUNET_YES == client->receive_pending)
1510  {
1512  client->receive_pending = GNUNET_NO;
1513  }
1514  client->shutdown_now = GNUNET_YES;
1515  client->reference_count++; /* make sure nobody else clean up client... */
1516  if ( (NULL != client->mst) &&
1517  (NULL != server) )
1518  {
1520  server->clients_tail,
1521  client);
1522  if (NULL != server->mst_destroy)
1523  server->mst_destroy (server->mst_cls,
1524  client->mst);
1525  else
1526  GNUNET_SERVER_mst_destroy (client->mst);
1527  client->mst = NULL;
1528  for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
1529  n->callback (n->callback_cls,
1530  client);
1531  }
1532  client->reference_count--;
1533  if (client->reference_count > 0)
1534  {
1536  "RC of %p still positive, not destroying everything.\n",
1537  client);
1538  client->server = NULL;
1539  return;
1540  }
1541  if (GNUNET_YES == client->in_process_client_buffer)
1542  {
1544  "Still processing inputs of %p, not destroying everything.\n",
1545  client);
1546  return;
1547  }
1549  "RC of %p now zero, destroying everything.\n",
1550  client);
1551  if (GNUNET_YES == client->persist)
1553  if (NULL != client->th.cth)
1556  /* need to cancel again, as it might have been re-added
1557  in the meantime (i.e. during callbacks) */
1558  if (NULL != client->warn_task)
1559  {
1561  client->warn_task = NULL;
1562  }
1563  if (GNUNET_YES == client->receive_pending)
1564  {
1566  client->receive_pending = GNUNET_NO;
1567  }
1568  GNUNET_free (client);
1569  /* we might be in soft-shutdown, test if we're done */
1570  if (NULL != server)
1571  test_monitor_clients (server);
1572 }
1573 
1574 
1583 int
1585 {
1587 }
1588 
1589 
1599 static size_t
1600 transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1601 {
1602  struct GNUNET_SERVER_Client *client = cls;
1604 
1605  client->th.cth = NULL;
1606  callback = client->th.callback;
1607  client->th.callback = NULL;
1609  return callback (client->th.callback_cls, size, buf);
1610 }
1611 
1612 
1630  size_t size,
1633  void *callback_cls)
1634 {
1635  if (NULL != client->th.callback)
1636  return NULL;
1637  client->th.callback_cls = callback_cls;
1638  client->th.callback = callback;
1639  client->th.cth = GNUNET_CONNECTION_notify_transmit_ready (client->connection, size,
1640  timeout,
1642  client);
1643  return &client->th;
1644 }
1645 
1646 
1652 void
1654 {
1656  th->cth = NULL;
1657  th->callback = NULL;
1658 }
1659 
1660 
1667 void
1669 {
1670  client->persist = GNUNET_YES;
1671 }
1672 
1673 
1686 void
1688  int success)
1689 {
1690  if (NULL == client)
1691  return;
1692  GNUNET_assert (client->suspended > 0);
1693  client->suspended--;
1694  if (GNUNET_OK != success)
1695  {
1697  "GNUNET_SERVER_receive_done called with failure indication\n");
1698  if ( (client->reference_count > 0) || (client->suspended > 0) )
1699  client->shutdown_now = GNUNET_YES;
1700  else
1702  return;
1703  }
1704  if (client->suspended > 0)
1705  {
1707  "GNUNET_SERVER_receive_done called, but more clients pending\n");
1708  return;
1709  }
1710  if (NULL != client->warn_task)
1711  {
1713  client->warn_task = NULL;
1714  }
1715  if (GNUNET_YES == client->in_process_client_buffer)
1716  {
1718  "GNUNET_SERVER_receive_done called while still in processing loop\n");
1719  return;
1720  }
1721  if ((NULL == client->server) || (GNUNET_YES == client->shutdown_now))
1722  {
1724  return;
1725  }
1727  "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
1728  GNUNET_assert (NULL == client->restart_task);
1730  client);
1731 }
1732 
1733 
1734 /* end of server.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
int GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:796
void GNUNET_SERVER_destroy(struct GNUNET_SERVER_Handle *server)
Free resources held by this server.
Handle server returns for aborting transmission to a client.
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:746
struct GNUNET_NETWORK_Handle * sock
Underlying OS&#39;s socket, set to NULL after fatal errors.
void GNUNET_SERVER_add_handlers(struct GNUNET_SERVER_Handle *server, const struct GNUNET_SERVER_MessageHandler *handlers)
Add additional handlers to an existing server.
void * access_cb_cls
Closure for access_cb.
int(* GNUNET_SERVER_MstReceiveCallback)(void *cls, void *mst, struct GNUNET_SERVER_Client *client, const char *buf, size_t size, int purge, int one_shot)
Signature of a function to receive data for a custom tokenizer.
Run with high priority (important requests).
void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *connection)
Set the persist option on this connection handle.
List of arrays of message handlers.
void * GNUNET_SERVER_client_get_user_context_(struct GNUNET_SERVER_Client *client, size_t size)
Return user context associated with the given client.
int in_process_client_buffer
Are we currently in the "process_client_buffer" function (and will hence restart the receive job on e...
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_SERVER_client_keep(struct GNUNET_SERVER_Client *client)
Notify the server that the given client handle should be kept (keeps the connection up if possible...
struct NotifyList * connect_notify_list_head
Head of linked list of functions to call on connects by clients.
static struct GNUNET_NETWORK_Handle * open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen)
Create and initialize a listen socket for the server.
GNUNET_SERVER_MessageCallback callback
Function to call for messages of "type".
List of arrays of message handlers.
struct GNUNET_SERVER_Client * clients_tail
Head of list of our current clients.
Context information passed to each scheduler task.
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_NETWORK_Handle ** listen_sockets
NULL-terminated array of sockets used to listen for new connections.
#define LOG(kind,...)
Definition: arm_api.c:33
GNUNET_SERVER_MstReceiveCallback mst_receive
Alternative function to give data to a MST instance.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:417
struct GNUNET_TIME_Absolute last_activity
Last activity on this socket (used to time it out if reference_count == 0).
static void warn_no_receive_done(void *cls)
Task run to warn about missing calls to GNUNET_SERVER_receive_done.
int GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:522
struct GNUNET_SERVER_Handle * GNUNET_SERVER_create(GNUNET_CONNECTION_AccessCheck access_cb, void *access_cb_cls, struct sockaddr *const *server_addr, const socklen_t *socklen, struct GNUNET_TIME_Relative idle_timeout, int require_found)
Create a new server.
GNUNET_SERVER_MstDestroyCallback mst_destroy
Alternative function to destroy a MST instance.
void * user_context
User context value, manipulated using &#39;GNUNET_SERVER_client_{get/set}_user_context&#39; functions...
GNUNET_SERVER_DisconnectCallback callback
Function to call.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
void * GNUNET_CONNECTION_receive_cancel(struct GNUNET_CONNECTION_Handle *connection)
Cancel receive job on the given connection.
const struct GNUNET_NETWORK_FDSet * read_ready
Set of file descriptors ready for reading; note that additional bits may be set that were not in the ...
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:393
void GNUNET_SERVER_mst_destroy(struct GNUNET_SERVER_MessageStreamTokenizer *mst)
Destroys a tokenizer.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_CONNECTION_notify_transmit_ready_cancel(struct GNUNET_CONNECTION_TransmitHandle *th)
Cancel the specified transmission-ready notification.
int GNUNET_SERVER_client_disable_corking(struct GNUNET_SERVER_Client *client)
Disable the "CORK" feature for communication with the given client, forcing the OS to immediately flu...
struct GNUNET_SERVER_Client * next
This is a doubly linked list.
int GNUNET_SERVER_mst_receive(struct GNUNET_SERVER_MessageStreamTokenizer *mst, void *client_identity, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
int receive_pending
Are we currently trying to receive? (GNUNET_YES if we are, GNUNET_NO if we are not, GNUNET_SYSERR if data is already available in MST).
static int ret
Final status code.
Definition: gnunet-arm.c:89
void * callback_cls
Closure for callback.
int GNUNET_SERVER_inject(struct GNUNET_SERVER_Handle *server, struct GNUNET_SERVER_Client *sender, const struct GNUNET_MessageHeader *message)
Inject a message into the server, pretend it came from the specified client.
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_accept(GNUNET_CONNECTION_AccessCheck access_cb, void *access_cb_cls, struct GNUNET_NETWORK_Handle *lsock)
Create a connection handle by accepting on a listen socket.
struct NotifyList * next
This is a doubly linked list.
uint64_t abs_value_us
The actual value.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net_with_priority(struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority and to be run after the specified delay or wh...
Definition: scheduler.c:1512
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_SERVER_Handle * GNUNET_SERVER_create_with_sockets(GNUNET_CONNECTION_AccessCheck access_cb, void *access_cb_cls, struct GNUNET_NETWORK_Handle **lsocks, struct GNUNET_TIME_Relative idle_timeout, int require_found)
Create a new server.
size_t(* GNUNET_CONNECTION_TransmitReadyNotify)(void *cls, size_t size, void *buf)
Function called to notify a client about the connection begin ready to queue more data...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
void GNUNET_SERVER_disconnect_notify_cancel(struct GNUNET_SERVER_Handle *server, GNUNET_SERVER_DisconnectCallback callback, void *callback_cls)
Ask the server to stop notifying us whenever a client connects.
struct NotifyList * prev
This is a doubly linked list.
void GNUNET_SERVER_connect_notify_cancel(struct GNUNET_SERVER_Handle *server, GNUNET_SERVER_ConnectCallback callback, void *callback_cls)
Ask the server to stop notifying us whenever a client disconnects.
void GNUNET_SERVER_client_set_user_context_(struct GNUNET_SERVER_Client *client, void *ptr, size_t size)
Set user context to be associated with the given client.
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1554
struct HandlerList * handlers
List of handlers for incoming messages.
int GNUNET_CONNECTION_disable_corking(struct GNUNET_CONNECTION_Handle *connection)
Disable the "CORK" feature for communication with the given connection, forcing the OS to immediately...
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1538
struct GNUNET_CONNECTION_TransmitHandle * cth
Active connection transmission handle.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct GNUNET_SERVER_TransmitHandle th
Transmission handle we return for this client from GNUNET_SERVER_notify_transmit_ready.
int is_monitor
Is this client a &#39;monitor&#39; client that should not be counted when deciding on destroying the server d...
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
void GNUNET_SERVER_notify_transmit_ready_cancel(struct GNUNET_SERVER_TransmitHandle *th)
Abort transmission request.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_TIME_Relative idle_timeout
After how long should an idle connection time out (on write).
struct GNUNET_TIME_Relative idle_timeout
After how long should an idle connection time out (on write).
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:727
collection of IO descriptors
static char buf[2048]
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when any of the specified file descriptor set...
Definition: scheduler.c:1829
void GNUNET_SERVER_set_callbacks(struct GNUNET_SERVER_Handle *server, GNUNET_SERVER_MstCreateCallback create, GNUNET_SERVER_MstDestroyCallback destroy, GNUNET_SERVER_MstReceiveCallback receive, void *cls)
Change functions used by the server to tokenize the message stream.
int GNUNET_CONNECTION_receive(struct GNUNET_CONNECTION_Handle *connection, size_t max, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_Receiver receiver, void *receiver_cls)
Receive data from the given connection.
struct NotifyList * disconnect_notify_list_head
Head of linked list of functions to call on disconnects by clients.
int GNUNET_CONNECTION_check(struct GNUNET_CONNECTION_Handle *connection)
Check if connection is valid (no fatal errors have happened so far).
void GNUNET_SERVER_client_drop(struct GNUNET_SERVER_Client *client)
Notify the server that the given client handle is no longer required.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
handle for a server
GNUNET_SERVER_MstCreateCallback mst_create
Alternative function to create a MST instance.
struct GNUNET_CONNECTION_Handle * connection
Client closure for callbacks.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages)...
void GNUNET_SERVER_client_set_timeout(struct GNUNET_SERVER_Client *client, struct GNUNET_TIME_Relative timeout)
Change the timeout for a particular client.
void GNUNET_SERVER_disconnect_notify(struct GNUNET_SERVER_Handle *server, GNUNET_SERVER_DisconnectCallback callback, void *callback_cls)
Ask the server to notify us whenever a client disconnects.
struct GNUNET_SERVER_Client * prev
This is a doubly linked list.
uint16_t expected_size
Expected size of messages of this type.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
void(* GNUNET_SERVER_DisconnectCallback)(void *cls, struct GNUNET_SERVER_Client *client)
Functions with this signature are called whenever a client is disconnected on the network level...
int shutdown_now
We&#39;re about to close down this client.
void GNUNET_SERVER_resume(struct GNUNET_SERVER_Handle *server)
Resume accepting connections from the listen socket.
unsigned int reference_count
Number of external entities with a reference to this client object.
void GNUNET_SERVER_client_disconnect(struct GNUNET_SERVER_Client *client)
Ask the server to disconnect from the given client.
static void restart_processing(void *cls)
Task run to start again receiving from the network and process requests.
static void process_incoming(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
We are receiving an incoming message.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
size_t user_context_size
Last size given when user context was initialized; used for sanity check.
static int client_message_tokenizer_callback(void *cls, void *client, const struct GNUNET_MessageHeader *message)
This function is called whenever our inbound message tokenizer has received a complete message...
static unsigned int size
Size of the "table".
Definition: peer.c:67
int require_found
Do we ignore messages of types that we do not understand or do we require that a handler is found (an...
uint16_t type
Type of the message this handler covers.
int GNUNET_CONNECTION_get_address(struct GNUNET_CONNECTION_Handle *connection, void **addr, size_t *addrlen)
Obtain the network address of the other party.
static void process_listen_socket(void *cls)
Scheduler says our listen socket is ready.
void GNUNET_CONNECTION_destroy(struct GNUNET_CONNECTION_Handle *connection)
Close the connection and free associated resources.
uint16_t warn_type
Type of last message processed (for warn_no_receive_done).
static void do_destroy(void *cls)
Helper function for test_monitor_clients() to trigger GNUNET_SERVER_destroy() after the stack has unw...
int GNUNET_SERVER_client_get_address(struct GNUNET_SERVER_Client *client, void **addr, size_t *addrlen)
Obtain the network address of the other party.
void GNUNET_NETWORK_fdset_set(struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Add a socket to the FD set.
Definition: network.c:1163
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
void *(* GNUNET_SERVER_MstCreateCallback)(void *cls, struct GNUNET_SERVER_Client *client)
Signature of a function to create a custom tokenizer.
GNUNET_CONNECTION_AccessCheck access_cb
Function to call for access control.
struct GNUNET_TIME_Absolute warn_start
Time when the warn task was started.
void GNUNET_SERVER_client_mark_monitor(struct GNUNET_SERVER_Client *client)
Set the &#39;monitor&#39; flag on this client.
GNUNET_CONNECTION_TransmitReadyNotify callback
Function to call to get the message.
int(* GNUNET_CONNECTION_AccessCheck)(void *cls, const struct GNUNET_CONNECTION_Credentials *ucred, const struct sockaddr *addr, socklen_t addrlen)
Function to call for access control checks.
#define GNUNET_MESSAGE_TYPE_ALL
Next available: 1500.
void(* GNUNET_SERVER_MstDestroyCallback)(void *cls, void *mst)
Signature of a function to destroy a custom tokenizer.
struct GNUNET_SCHEDULER_Task * listen_task
Task scheduled to do the listening.
int persist
Persist the file handle for this client no matter what happens, force the OS to close once the proces...
struct NotifyList * disconnect_notify_list_tail
Tail of linked list of functions to call on disconnects by clients.
void GNUNET_SERVER_connect_notify(struct GNUNET_SERVER_Handle *server, GNUNET_SERVER_ConnectCallback callback, void *callback_cls)
Ask the server to notify us whenever a client connects.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:79
struct GNUNET_CONNECTION_TransmitHandle * GNUNET_CONNECTION_notify_transmit_ready(struct GNUNET_CONNECTION_Handle *connection, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify notify, void *notify_cls)
Ask the connection to call us once the specified number of bytes are free in the transmission buffer...
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:373
void * callback_cls
Closure for callback.
const struct GNUNET_SERVER_MessageHandler * handlers
NULL-terminated array of handlers.
#define LOG_STRERROR(kind, syscall)
#define GNUNET_log(kind,...)
struct GNUNET_SCHEDULER_Task * warn_task
Task that warns about missing calls to GNUNET_SERVER_receive_done.
Entry in list of pending tasks.
Definition: scheduler.c:134
void GNUNET_SERVER_receive_done(struct GNUNET_SERVER_Client *client, int success)
Resume receiving from this client, we are done processing the current request.
void GNUNET_SERVER_suspend(struct GNUNET_SERVER_Handle *server)
Suspend accepting connections from the listen socket temporarily.
struct NotifyList * connect_notify_list_tail
Tail of linked list of functions to call on connects by clients.
struct GNUNET_SERVER_TransmitHandle * GNUNET_SERVER_notify_transmit_ready(struct GNUNET_SERVER_Client *client, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify callback, void *callback_cls)
Notify us when the server has enough space to transmit a message of the given size to the given clien...
handle to a socket
Definition: network.c:46
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
struct GNUNET_SERVER_Client * GNUNET_SERVER_connect_socket(struct GNUNET_SERVER_Handle *server, struct GNUNET_CONNECTION_Handle *connection)
Add a TCP socket-based connection to the set of handles managed by this server.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Header for all communications.
int in_soft_shutdown
Set to GNUNET_YES once we are in &#39;soft&#39; shutdown where we wait for all non-monitor clients to disconn...
void GNUNET_SERVER_client_persist_(struct GNUNET_SERVER_Client *client)
Set the persistent flag on this client, used to setup client connection to only be killed when the se...
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
handle for a client of the server
struct GNUNET_SERVER_Client * clients_head
Head of list of our current clients.
static void destroy(void *cls)
static void test_monitor_clients(struct GNUNET_SERVER_Handle *server)
Check if only &#39;monitor&#39; clients are left.
struct GNUNET_SERVER_Handle * server
Server that this client belongs to.
struct HandlerList * next
This is a linked list.
int GNUNET_NETWORK_fdset_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Check whether a socket is part of the fd set.
Definition: network.c:1181
handle for a network connection
void * mst_cls
Closure for &#39;mst_&#39;-callbacks.
void * mst
Processing of incoming data.
void * callback_cls
Closure argument for callback.
void GNUNET_SERVER_stop_listening(struct GNUNET_SERVER_Handle *server)
Stop the listen socket and get ready to shutdown the server once only &#39;monitor&#39; clients are left...
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
static void process_mst(struct GNUNET_SERVER_Client *client, int ret)
Process messages from the client&#39;s message tokenizer until either the tokenizer is empty (and then sc...
struct GNUNET_SCHEDULER_Task * restart_task
ID of task used to restart processing.
#define GNUNET_malloc(size)
Wrapper around malloc.
struct GNUNET_SERVER_MessageStreamTokenizer * GNUNET_SERVER_mst_create(GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
void GNUNET_SERVER_disable_receive_done_warning(struct GNUNET_SERVER_Client *client)
Disable the warning the server issues if a message is not acknowledged in a timely fashion...
void(* GNUNET_SERVER_ConnectCallback)(void *cls, struct GNUNET_SERVER_Client *client)
Functions with this signature are called whenever a client is connected on the network level...
static size_t transmit_ready_callback_wrapper(void *cls, size_t size, void *buf)
Wrapper for transmission notification that calls the original callback and update the last activity t...
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:1037
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
unsigned int suspended
Was processing if incoming messages suspended while we were still processing data already received...