GNUnet  0.11.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, \
32  filename) GNUNET_log_from_strerror_file (kind, \
33  "util-server", \
34  syscall, \
35  filename)
36 
37 
42 {
46  struct HandlerList *next;
47 
52 };
53 
54 
58 struct NotifyList
59 {
63  struct NotifyList *next;
64 
68  struct NotifyList *prev;
69 
74 
78  void *callback_cls;
79 };
80 
81 
86 {
91 
96 
101 
106 
111 
116 
121 
126 
131 
137 
142  struct GNUNET_TIME_Relative idle_timeout;
143 
148 
153 
158 
163 
167  void *mst_cls;
168 
174 
183 };
184 
185 
190 {
195 
200 
205 };
206 
207 
212 {
217 
222 
226  void *mst;
227 
232 
237 
243 
248 
253 
257  struct GNUNET_TIME_Absolute warn_start;
258 
263  struct GNUNET_TIME_Absolute last_activity;
264 
270 
275  struct GNUNET_TIME_Relative idle_timeout;
276 
281  unsigned int reference_count;
282 
289  unsigned int suspended;
290 
296 
306 
311 
318 
324  int persist;
325 
332 
336  uint16_t warn_type;
337 };
338 
339 
348 void *
350  size_t size)
351 {
352  if ((0 == client->user_context_size) &&
353  (NULL == client->user_context))
354  return NULL; /* never set */
355  GNUNET_assert (size == client->user_context_size);
356  return client->user_context;
357 }
358 
359 
368 void
370  void *ptr,
371  size_t size)
372 {
373  if (NULL == ptr)
374  {
375  client->user_context_size = 0;
376  client->user_context = ptr;
377  return;
378  }
379  client->user_context_size = size;
380  client->user_context = ptr;
381 }
382 
383 
390 static void
392 {
393  struct GNUNET_SERVER_Handle *server = cls;
394  const struct GNUNET_SCHEDULER_TaskContext *tc;
396  unsigned int i;
397 
398  server->listen_task = NULL;
400  for (i = 0; NULL != server->listen_sockets[i]; i++)
401  {
403  server->listen_sockets[i]))
404  {
405  sock =
407  server->access_cb_cls,
408  server->listen_sockets[i]);
409  if (NULL != sock)
410  {
412  "Server accepted incoming connection.\n");
413  (void) GNUNET_SERVER_connect_socket (server,
414  sock);
415  }
416  }
417  }
418  /* listen for more! */
419  GNUNET_SERVER_resume (server);
420 }
421 
422 
430 static struct GNUNET_NETWORK_Handle *
431 open_listen_socket (const struct sockaddr *server_addr,
432  socklen_t socklen)
433 {
434  struct GNUNET_NETWORK_Handle *sock;
435  uint16_t port;
436  int eno;
437 
438  switch (server_addr->sa_family)
439  {
440  case AF_INET:
441  port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
442  break;
443 
444  case AF_INET6:
445  port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
446  break;
447 
448  case AF_UNIX:
449  port = 0;
450  break;
451 
452  default:
453  GNUNET_break (0);
454  port = 0;
455  break;
456  }
457  sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, SOCK_STREAM, 0);
458  if (NULL == sock)
459  {
461  errno = 0;
462  return NULL;
463  }
464  /* bind the socket */
465  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, server_addr, socklen))
466  {
467  eno = errno;
468  if (EADDRINUSE != errno)
469  {
470  /* we don't log 'EADDRINUSE' here since an IPv4 bind may
471  * fail if we already took the port on IPv6; if both IPv4 and
472  * IPv6 binds fail, then our caller will log using the
473  * errno preserved in 'eno' */
475  "bind");
476  if (0 != port)
478  _ ("`%s' failed for port %d (%s).\n"),
479  "bind",
480  port,
481  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
482  eno = 0;
483  }
484  else
485  {
486  if (0 != port)
488  _ ("`%s' failed for port %d (%s): address already in use\n"),
489  "bind", port,
490  (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
491  else if (AF_UNIX == server_addr->sa_family)
492  {
494  _ ("`%s' failed for `%s': address already in use\n"),
495  "bind",
496  GNUNET_a2s (server_addr, socklen));
497  }
498  }
500  errno = eno;
501  return NULL;
502  }
503  if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
504  {
506  "listen");
508  errno = 0;
509  return NULL;
510  }
511  if (0 != port)
513  "Server starts to listen on port %u.\n",
514  port);
515  return sock;
516 }
517 
518 
531 struct GNUNET_SERVER_Handle *
533  void *access_cb_cls,
534  struct GNUNET_NETWORK_Handle **lsocks,
536  int require_found)
537 {
538  struct GNUNET_SERVER_Handle *server;
539 
540  server = GNUNET_new (struct GNUNET_SERVER_Handle);
541  server->idle_timeout = idle_timeout;
542  server->listen_sockets = lsocks;
543  server->access_cb = access_cb;
544  server->access_cb_cls = access_cb_cls;
545  server->require_found = require_found;
546  if (NULL != lsocks)
547  GNUNET_SERVER_resume (server);
548  return server;
549 }
550 
551 
565 struct GNUNET_SERVER_Handle *
567  void *access_cb_cls,
568  struct sockaddr *const *server_addr,
569  const socklen_t *socklen,
571  int require_found)
572 {
573  struct GNUNET_NETWORK_Handle **lsocks;
574  unsigned int i;
575  unsigned int j;
576  unsigned int k;
577  int seen;
578 
579  i = 0;
580  while (NULL != server_addr[i])
581  i++;
582  if (i > 0)
583  {
584  lsocks = GNUNET_malloc (sizeof(struct GNUNET_NETWORK_Handle *) * (i + 1));
585  i = 0;
586  j = 0;
587  while (NULL != server_addr[i])
588  {
589  seen = 0;
590  for (k = 0; k < i; k++)
591  if ((socklen[k] == socklen[i]) &&
592  (0 == memcmp (server_addr[k], server_addr[i], socklen[i])))
593  {
594  seen = 1;
595  break;
596  }
597  if (0 != seen)
598  {
599  /* duplicate address, skip */
600  i++;
601  continue;
602  }
603  lsocks[j] = open_listen_socket (server_addr[i], socklen[i]);
604  if (NULL != lsocks[j])
605  j++;
606  i++;
607  }
608  if (0 == j)
609  {
610  if (0 != errno)
612  GNUNET_free (lsocks);
613  lsocks = NULL;
614  }
615  }
616  else
617  {
618  lsocks = NULL;
619  }
620  return GNUNET_SERVER_create_with_sockets (access_cb,
621  access_cb_cls,
622  lsocks,
623  idle_timeout,
624  require_found);
625 }
626 
627 
640 void
642 {
644  "Marking client as monitor!\n");
645  client->is_monitor = GNUNET_YES;
646 }
647 
648 
655 static void
656 do_destroy (void *cls)
657 {
658  struct GNUNET_SERVER_Handle *server = cls;
659 
660  GNUNET_SERVER_destroy (server);
661 }
662 
663 
670 static void
672 {
673  struct GNUNET_SERVER_Client *client;
674 
675  if (GNUNET_YES != server->in_soft_shutdown)
676  return;
677  for (client = server->clients_head; NULL != client; client = client->next)
678  if (GNUNET_NO == client->is_monitor)
679  return;
680  /* not done yet */
682  (void) GNUNET_SCHEDULER_add_now (&do_destroy, server);
683 }
684 
685 
691 void
693 {
694  if (NULL != server->listen_task)
695  {
697  server->listen_task = NULL;
698  }
699 }
700 
701 
707 void
709 {
710  struct GNUNET_NETWORK_FDSet *r;
711  unsigned int i;
712 
713  if (NULL == server->listen_sockets)
714  return;
715  if (NULL == server->listen_sockets[0])
716  return; /* nothing to do, no listen sockets! */
717  if (NULL == server->listen_sockets[1])
718  {
719  /* simplified method: no fd set needed; this is then much simpler
720  and much more efficient */
721  server->listen_task =
724  server->listen_sockets[0],
726  server);
727  return;
728  }
730  i = 0;
731  while (NULL != server->listen_sockets[i])
732  GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
733  server->listen_task =
736  &process_listen_socket, server);
738 }
739 
740 
747 void
749 {
750  unsigned int i;
751 
753  "Server in soft shutdown\n");
754  if (NULL != server->listen_task)
755  {
757  server->listen_task = NULL;
758  }
759  if (NULL != server->listen_sockets)
760  {
761  i = 0;
762  while (NULL != server->listen_sockets[i])
765  GNUNET_free (server->listen_sockets);
766  server->listen_sockets = NULL;
767  }
768  if (GNUNET_NO == server->in_soft_shutdown)
769  server->in_soft_shutdown = GNUNET_YES;
770  test_monitor_clients (server);
771 }
772 
773 
779 void
781 {
782  struct HandlerList *hpos;
783  struct NotifyList *npos;
784  unsigned int i;
785 
787  "Server shutting down.\n");
788  if (NULL != server->listen_task)
789  {
791  server->listen_task = NULL;
792  }
793  if (NULL != server->listen_sockets)
794  {
795  i = 0;
796  while (NULL != server->listen_sockets[i])
799  GNUNET_free (server->listen_sockets);
800  server->listen_sockets = NULL;
801  }
802  while (NULL != server->clients_head)
804  while (NULL != (hpos = server->handlers))
805  {
806  server->handlers = hpos->next;
807  GNUNET_free (hpos);
808  }
809  while (NULL != (npos = server->disconnect_notify_list_head))
810  {
811  npos->callback (npos->callback_cls,
812  NULL);
815  npos);
816  GNUNET_free (npos);
817  }
818  while (NULL != (npos = server->connect_notify_list_head))
819  {
820  npos->callback (npos->callback_cls,
821  NULL);
823  server->connect_notify_list_tail,
824  npos);
825  GNUNET_free (npos);
826  }
827  GNUNET_free (server);
828 }
829 
830 
844 void
847 {
848  struct HandlerList *p;
849 
850  p = GNUNET_new (struct HandlerList);
851  p->handlers = handlers;
852  p->next = server->handlers;
853  server->handlers = p;
854 }
855 
856 
867 void
872  void *cls)
873 {
874  server->mst_create = create;
875  server->mst_destroy = destroy;
876  server->mst_receive = receive;
877  server->mst_cls = cls;
878 }
879 
880 
886 static void
888 {
889  struct GNUNET_SERVER_Client *client = cls;
890 
891  GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
892  client->warn_task =
894  &warn_no_receive_done, client);
896  _ (
897  "Processing code for message of type %u did not call `GNUNET_SERVER_receive_done' after %s\n"),
898  (unsigned int) client->warn_type,
901  GNUNET_YES));
902 }
903 
904 
912 void
914 {
915  if (NULL != client->warn_task)
916  {
918  client->warn_task = NULL;
919  }
920 }
921 
922 
938 int
940  struct GNUNET_SERVER_Client *sender,
941  const struct GNUNET_MessageHeader *message)
942 {
943  struct HandlerList *pos;
944  const struct GNUNET_SERVER_MessageHandler *mh;
945  unsigned int i;
946  uint16_t type;
947  uint16_t size;
948  int found;
949 
950  type = ntohs (message->type);
951  size = ntohs (message->size);
953  "Received message of type %u and size %u from client\n",
954  type, size);
955  found = GNUNET_NO;
956  for (pos = server->handlers; NULL != pos; pos = pos->next)
957  {
958  i = 0;
959  while (pos->handlers[i].callback != NULL)
960  {
961  mh = &pos->handlers[i];
962  if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
963  {
964  if ((0 != mh->expected_size) && (mh->expected_size != size))
965  {
966 #if GNUNET8_NETWORK_IS_DEAD
968  "Expected %u bytes for message of type %u, got %u\n",
969  mh->expected_size, mh->type, size);
970  GNUNET_break_op (0);
971 #else
973  "Expected %u bytes for message of type %u, got %u\n",
974  mh->expected_size, mh->type, size);
975 #endif
976  return GNUNET_SYSERR;
977  }
978  if (NULL != sender)
979  {
980  if ((0 == sender->suspended) &&
981  (NULL == sender->warn_task))
982  {
983  GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */
985  sender->warn_task =
988  sender);
989  sender->warn_type = type;
990  }
991  sender->suspended++;
992  }
993  mh->callback (mh->callback_cls, sender, message);
994  found = GNUNET_YES;
995  }
996  i++;
997  }
998  }
999  if (GNUNET_NO == found)
1000  {
1002  "Received message of unknown type %d\n", type);
1003  if (GNUNET_YES == server->require_found)
1004  return GNUNET_SYSERR;
1005  }
1006  return GNUNET_OK;
1007 }
1008 
1009 
1020 static void
1021 process_incoming (void *cls,
1022  const void *buf,
1023  size_t available,
1024  const struct sockaddr *addr,
1025  socklen_t addrlen,
1026  int errCode);
1027 
1028 
1042 static void
1044  int ret)
1045 {
1046  while ((GNUNET_SYSERR != ret) && (NULL != client->server) &&
1047  (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
1048  {
1049  if (GNUNET_OK == ret)
1050  {
1052  "Server re-enters receive loop, timeout: %s.\n",
1054  GNUNET_YES));
1055  client->receive_pending = GNUNET_YES;
1056  if (GNUNET_OK !=
1059  client->idle_timeout,
1061  client))
1062  return;
1063  break;
1064  }
1066  "Server processes additional messages instantly.\n");
1067  if (NULL != client->server->mst_receive)
1068  ret =
1069  client->server->mst_receive (client->server->mst_cls, client->mst,
1070  client, NULL, 0, GNUNET_NO, GNUNET_YES);
1071  else
1072  ret =
1073  GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO,
1074  GNUNET_YES);
1075  }
1077  "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
1078  ret, client->server,
1079  client->shutdown_now,
1080  client->suspended);
1081  if (GNUNET_NO == ret)
1082  {
1084  "Server has more data pending but is suspended.\n");
1085  client->receive_pending = GNUNET_SYSERR; /* data pending */
1086  }
1087  if ((GNUNET_SYSERR == ret) ||
1088  (GNUNET_YES == client->shutdown_now))
1090 }
1091 
1092 
1103 static void
1104 process_incoming (void *cls,
1105  const void *buf,
1106  size_t available,
1107  const struct sockaddr *addr,
1108  socklen_t addrlen,
1109  int errCode)
1110 {
1111  struct GNUNET_SERVER_Client *client = cls;
1112  struct GNUNET_SERVER_Handle *server = client->server;
1113  struct GNUNET_TIME_Absolute end;
1114  struct GNUNET_TIME_Absolute now;
1115  int ret;
1116 
1118  client->receive_pending = GNUNET_NO;
1119  now = GNUNET_TIME_absolute_get ();
1120  end = GNUNET_TIME_absolute_add (client->last_activity,
1121  client->idle_timeout);
1122 
1123  if ((NULL == buf) &&
1124  (0 == available) &&
1125  (NULL == addr) &&
1126  (0 == errCode) &&
1127  (GNUNET_YES != client->shutdown_now) &&
1128  (NULL != server) &&
1130  (end.abs_value_us > now.abs_value_us))
1131  {
1132  /* wait longer, timeout changed (i.e. due to us sending) */
1134  "Receive time out, but no disconnect due to sending (%p)\n",
1135  client);
1136  client->receive_pending = GNUNET_YES;
1141  client);
1142  return;
1143  }
1144  if ((NULL == buf) ||
1145  (0 == available) ||
1146  (0 != errCode) ||
1147  (NULL == server) ||
1148  (GNUNET_YES == client->shutdown_now) ||
1150  {
1151  /* other side closed connection, error connecting, etc. */
1153  "Failed to connect or other side closed connection (%p)\n",
1154  client);
1156  return;
1157  }
1159  "Server receives %u bytes from `%s'.\n",
1160  (unsigned int) available,
1161  GNUNET_a2s (addr, addrlen));
1162  GNUNET_SERVER_client_keep (client);
1163  client->last_activity = now;
1164 
1165  if (NULL != server->mst_receive)
1166  {
1167  ret = client->server->mst_receive (client->server->mst_cls,
1168  client->mst,
1169  client,
1170  buf,
1171  available,
1172  GNUNET_NO,
1173  GNUNET_YES);
1174  }
1175  else if (NULL != client->mst)
1176  {
1177  ret =
1178  GNUNET_SERVER_mst_receive (client->mst,
1179  client,
1180  buf,
1181  available,
1182  GNUNET_NO,
1183  GNUNET_YES);
1184  }
1185  else
1186  {
1187  GNUNET_break (0);
1188  return;
1189  }
1190  process_mst (client,
1191  ret);
1192  GNUNET_SERVER_client_drop (client);
1193 }
1194 
1195 
1202 static void
1204 {
1205  struct GNUNET_SERVER_Client *client = cls;
1206 
1207  GNUNET_assert (GNUNET_YES != client->shutdown_now);
1208  client->restart_task = NULL;
1209  if (GNUNET_NO == client->receive_pending)
1210  {
1211  LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n");
1212  client->receive_pending = GNUNET_YES;
1215  client->idle_timeout,
1217  client);
1218  return;
1219  }
1221  "Server continues processing messages still in the buffer.\n");
1222  GNUNET_SERVER_client_keep (client);
1223  client->receive_pending = GNUNET_NO;
1224  process_mst (client,
1225  GNUNET_NO);
1226  GNUNET_SERVER_client_drop (client);
1227 }
1228 
1229 
1240 static int
1242  void *client,
1243  const struct GNUNET_MessageHeader *message)
1244 {
1245  struct GNUNET_SERVER_Handle *server = cls;
1246  struct GNUNET_SERVER_Client *sender = client;
1247  int ret;
1248 
1250  "Tokenizer gives server message of type %u and size %u from client\n",
1251  ntohs (message->type), ntohs (message->size));
1253  ret = GNUNET_SERVER_inject (server, sender, message);
1255  if ((GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now))
1256  {
1258  return GNUNET_SYSERR;
1259  }
1260  return GNUNET_OK;
1261 }
1262 
1263 
1275 struct GNUNET_SERVER_Client *
1278 {
1279  struct GNUNET_SERVER_Client *client;
1280  struct NotifyList *n;
1281 
1282  client = GNUNET_new (struct GNUNET_SERVER_Client);
1283  client->connection = connection;
1284  client->server = server;
1286  client->idle_timeout = server->idle_timeout;
1288  server->clients_tail,
1289  client);
1290  if (NULL != server->mst_create)
1291  client->mst =
1292  server->mst_create (server->mst_cls, client);
1293  else
1294  client->mst =
1296  server);
1297  GNUNET_assert (NULL != client->mst);
1298  for (n = server->connect_notify_list_head; NULL != n; n = n->next)
1299  n->callback (n->callback_cls, client);
1300  client->receive_pending = GNUNET_YES;
1301  if (GNUNET_SYSERR ==
1304  client->idle_timeout,
1306  client))
1307  return NULL;
1308  return client;
1309 }
1310 
1311 
1320 void
1323 {
1324  client->idle_timeout = timeout;
1325 }
1326 
1327 
1335 void
1337 {
1338  client->reference_count++;
1339 }
1340 
1341 
1350 void
1352 {
1353  GNUNET_assert (client->reference_count > 0);
1354  client->reference_count--;
1355  if ((GNUNET_YES == client->shutdown_now) && (0 == client->reference_count))
1357 }
1358 
1359 
1368 int
1370  void **addr, size_t *addrlen)
1371 {
1372  return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen);
1373 }
1374 
1375 
1386 void
1389  void *callback_cls)
1390 {
1391  struct NotifyList *n;
1392 
1393  n = GNUNET_new (struct NotifyList);
1394  n->callback = callback;
1398  n);
1399 }
1400 
1401 
1415 void
1418  void *callback_cls)
1419 {
1420  struct NotifyList *n;
1421  struct GNUNET_SERVER_Client *client;
1422 
1423  n = GNUNET_new (struct NotifyList);
1424  n->callback = callback;
1425  n->callback_cls = callback_cls;
1427  server->connect_notify_list_tail,
1428  n);
1429  for (client = server->clients_head; NULL != client; client = client->next)
1430  callback (callback_cls, client);
1431 }
1432 
1433 
1441 void
1444  callback,
1445  void *callback_cls)
1446 {
1447  struct NotifyList *pos;
1448 
1449  for (pos = server->disconnect_notify_list_head; NULL != pos; pos = pos->next)
1450  if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
1451  break;
1452  if (NULL == pos)
1453  {
1454  GNUNET_break (0);
1455  return;
1456  }
1459  pos);
1460  GNUNET_free (pos);
1461 }
1462 
1463 
1471 void
1474  void *callback_cls)
1475 {
1476  struct NotifyList *pos;
1477 
1478  for (pos = server->connect_notify_list_head; NULL != pos; pos = pos->next)
1479  if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
1480  break;
1481  if (NULL == pos)
1482  {
1483  GNUNET_break (0);
1484  return;
1485  }
1487  server->connect_notify_list_tail,
1488  pos);
1489  GNUNET_free (pos);
1490 }
1491 
1492 
1501 void
1503 {
1504  struct GNUNET_SERVER_Handle *server = client->server;
1505  struct NotifyList *n;
1506 
1508  "Client is being disconnected from the server.\n");
1509  if (NULL != client->restart_task)
1510  {
1512  client->restart_task = NULL;
1513  }
1514  if (NULL != client->warn_task)
1515  {
1517  client->warn_task = NULL;
1518  }
1519  if (GNUNET_YES == client->receive_pending)
1520  {
1522  client->receive_pending = GNUNET_NO;
1523  }
1524  client->shutdown_now = GNUNET_YES;
1525  client->reference_count++; /* make sure nobody else clean up client... */
1526  if ((NULL != client->mst) &&
1527  (NULL != server))
1528  {
1530  server->clients_tail,
1531  client);
1532  if (NULL != server->mst_destroy)
1533  server->mst_destroy (server->mst_cls,
1534  client->mst);
1535  else
1536  GNUNET_SERVER_mst_destroy (client->mst);
1537  client->mst = NULL;
1538  for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
1539  n->callback (n->callback_cls,
1540  client);
1541  }
1542  client->reference_count--;
1543  if (client->reference_count > 0)
1544  {
1546  "RC of %p still positive, not destroying everything.\n",
1547  client);
1548  client->server = NULL;
1549  return;
1550  }
1551  if (GNUNET_YES == client->in_process_client_buffer)
1552  {
1554  "Still processing inputs of %p, not destroying everything.\n",
1555  client);
1556  return;
1557  }
1559  "RC of %p now zero, destroying everything.\n",
1560  client);
1561  if (GNUNET_YES == client->persist)
1563  if (NULL != client->th.cth)
1566  /* need to cancel again, as it might have been re-added
1567  in the meantime (i.e. during callbacks) */
1568  if (NULL != client->warn_task)
1569  {
1571  client->warn_task = NULL;
1572  }
1573  if (GNUNET_YES == client->receive_pending)
1574  {
1576  client->receive_pending = GNUNET_NO;
1577  }
1578  GNUNET_free (client);
1579  /* we might be in soft-shutdown, test if we're done */
1580  if (NULL != server)
1581  test_monitor_clients (server);
1582 }
1583 
1584 
1593 int
1595 {
1597 }
1598 
1599 
1609 static size_t
1610 transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
1611 {
1612  struct GNUNET_SERVER_Client *client = cls;
1614 
1615  client->th.cth = NULL;
1616  callback = client->th.callback;
1617  client->th.callback = NULL;
1619  return callback (client->th.callback_cls, size, buf);
1620 }
1621 
1622 
1640  size_t size,
1643  callback,
1644  void *callback_cls)
1645 {
1646  if (NULL != client->th.callback)
1647  return NULL;
1648  client->th.callback_cls = callback_cls;
1649  client->th.callback = callback;
1651  size,
1652  timeout,
1653  &
1655  client);
1656  return &client->th;
1657 }
1658 
1659 
1665 void
1668 {
1670  th->cth = NULL;
1671  th->callback = NULL;
1672 }
1673 
1674 
1681 void
1683 {
1684  client->persist = GNUNET_YES;
1685 }
1686 
1687 
1700 void
1702  int success)
1703 {
1704  if (NULL == client)
1705  return;
1706  GNUNET_assert (client->suspended > 0);
1707  client->suspended--;
1708  if (GNUNET_OK != success)
1709  {
1711  "GNUNET_SERVER_receive_done called with failure indication\n");
1712  if ((client->reference_count > 0) || (client->suspended > 0))
1713  client->shutdown_now = GNUNET_YES;
1714  else
1716  return;
1717  }
1718  if (client->suspended > 0)
1719  {
1721  "GNUNET_SERVER_receive_done called, but more clients pending\n");
1722  return;
1723  }
1724  if (NULL != client->warn_task)
1725  {
1727  client->warn_task = NULL;
1728  }
1729  if (GNUNET_YES == client->in_process_client_buffer)
1730  {
1732  "GNUNET_SERVER_receive_done called while still in processing loop\n");
1733  return;
1734  }
1735  if ((NULL == client->server) || (GNUNET_YES == client->shutdown_now))
1736  {
1738  return;
1739  }
1741  "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
1742  GNUNET_assert (NULL == client->restart_task);
1744  client);
1745 }
1746 
1747 
1748 /* 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:708
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:747
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.
GNUNET_SERVER_MstReceiveCallback mst_receive
Alternative function to give data to a MST instance.
#define LOG(kind,...)
Definition: abd_api.c:38
#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:418
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:485
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.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:395
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).
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:1520
#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:181
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:1266
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:1253
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1250
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
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
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:1280
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:687
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:1810
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:76
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:1011
#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:81
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:375
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:52
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:77
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:1029
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:560
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:912
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
unsigned int suspended
Was processing if incoming messages suspended while we were still processing data already received...