+/**
+ * Send a message to a particular client.
+ *
+ * @param nc context to modify
+ * @param client client to transmit to
+ * @param msg message to send
+ * @param can_drop can this message be dropped due to queue length limitations
+ */
+static void
+do_unicast (struct GNUNET_SERVER_NotificationContext *nc,
+ struct ClientList *client,
+ const struct GNUNET_MessageHeader *msg,
+ int can_drop)
+{
+ struct PendingMessageList *pml;
+ uint16_t size;
+
+ if ( (client->num_pending > nc->queue_length) &&
+ (GNUNET_YES == can_drop) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Dropping message of type %u and size %u due to full queue (%u entries)\n",
+ ntohs (msg->type),
+ ntohs (msg->size),
+ (unsigned int) nc->queue_length);
+ return; /* drop! */
+ }
+ if (client->num_pending > nc->queue_length)
+ {
+ /* FIXME: consider checking for other messages in the
+ queue that are 'droppable' */
+ }
+ client->num_pending++;
+ size = ntohs (msg->size);
+ pml = GNUNET_malloc (sizeof (struct PendingMessageList) + size);
+ pml->msg = (const struct GNUNET_MessageHeader*) &pml[1];
+ pml->can_drop = can_drop;
+#if DEBUG_SERVER_NC
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding message of type %u and size %u to pending queue (which has %u entries)\n",
+ ntohs (msg->type),
+ ntohs (msg->size),
+ (unsigned int) nc->queue_length);
+#endif
+ memcpy (&pml[1], msg, size);
+ /* append */
+ if (client->pending_tail != NULL)
+ client->pending_tail->next = pml;
+ else
+ client->pending_head = pml;
+ client->pending_tail = pml;
+ if (client->th == NULL)
+ client->th = GNUNET_SERVER_notify_transmit_ready (client->client,
+ ntohs (client->pending_head->msg->size),
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &transmit_message,
+ client);
+}
+
+