+static void
+clients_handle_send (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct OutboundMessage *obm;
+ const struct GNUNET_MessageHeader *obmm;
+ struct SendTransmitContinuationContext *stcc;
+ uint16_t size;
+ uint16_t msize;
+ struct TransportClient *tc;
+
+ tc = lookup_client (client);
+ if (NULL == tc)
+ {
+ /* client asked for transmission before 'START' */
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+
+ size = ntohs (message->size);
+ if (size <
+ sizeof (struct OutboundMessage) + sizeof (struct GNUNET_MessageHeader))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ obm = (const struct OutboundMessage *) message;
+ obmm = (const struct GNUNET_MessageHeader *) &obm[1];
+ msize = size - sizeof (struct OutboundMessage);
+ if (msize < sizeof (struct GNUNET_MessageHeader))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ GNUNET_STATISTICS_update (GST_stats,
+ gettext_noop
+ ("# bytes payload received for other peers"), msize,
+ GNUNET_NO);
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' request from client with target `%4s' and first message of type %u and total size %u\n",
+ "SEND", GNUNET_i2s (&obm->peer), ntohs (obmm->type), msize);
+#endif
+ if (GNUNET_NO == GST_neighbours_test_connected (&obm->peer))
+ {
+ /* not connected, not allowed to send; can happen due to asynchronous operations */
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Could not send message to peer `%s': not connected\n",
+ GNUNET_i2s (&obm->peer));
+#endif
+ GNUNET_STATISTICS_update (GST_stats,
+ gettext_noop
+ ("# bytes payload dropped (other peer was not connected)"),
+ msize, GNUNET_NO);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ stcc = GNUNET_malloc (sizeof (struct SendTransmitContinuationContext));
+ stcc->target = obm->peer;
+ stcc->client = client;
+ GNUNET_SERVER_client_keep (client);
+ GST_neighbours_send (&obm->peer, obmm, msize,
+ GNUNET_TIME_relative_ntoh (obm->timeout),
+ &handle_send_transmit_continuation, stcc);
+}
+
+
+/**
+ * Try to initiate a connection to the given peer if the blacklist
+ * allowed it.
+ *
+ * @param cls closure (unused, NULL)
+ * @param peer identity of peer that was tested
+ * @param result GNUNET_OK if the connection is allowed,
+ * GNUNET_NO if not
+ */
+static void
+try_connect_if_allowed (void *cls, const struct GNUNET_PeerIdentity *peer,
+ int result)