- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "New inbound tunnel from peer %s; first message has type %d.\n",
- GNUNET_i2s (other), ntohs (rmessage->type));
- tunnel = GNUNET_malloc (sizeof (struct tunnel_list_element));
- tunnel->tunnel.connect_handler = NULL;
- tunnel->tunnel.disconnect_handler = NULL;
- tunnel->tunnel.handler_cls = NULL;
- tunnel->tunnel.ctx = NULL;
- tunnel->tunnel.handle = handle;
- memcpy (&tunnel->tunnel.peer, other, sizeof (struct GNUNET_PeerIdentity));
- memcpy (&tunnel->tunnel.id, &tmessage->id, sizeof (struct tunnel_id));
-
- GNUNET_CONTAINER_DLL_insert_after (handle->established_tunnels.head,
- handle->established_tunnels.tail,
- handle->established_tunnels.tail,
- tunnel);
+ if (NULL != th->notify)
+ {
+ if (th->tunnel->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
+ {
+ /* traffic to origin */
+ struct GNUNET_MESH_ToOrigin to;
+ struct GNUNET_MessageHeader *mh;
+
+ GNUNET_assert (size >= th->size);
+ mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (to)];
+ psize = th->notify (th->notify_cls, size - sizeof (to), mh);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: to origin, type %u\n",
+ ntohs (mh->type));
+ if (psize > 0)
+ {
+ psize += sizeof (to);
+ GNUNET_assert (size >= psize);
+ to.header.size = htons (psize);
+ to.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
+ to.tid = htonl (th->tunnel->tid);
+ memset (&to.oid, 0, sizeof (struct GNUNET_PeerIdentity));
+ memset (&to.sender, 0, sizeof (struct GNUNET_PeerIdentity));
+ memcpy (cbuf, &to, sizeof (to));
+ }
+ }
+ else if (th->target == 0)
+ {
+ /* multicast */
+ struct GNUNET_MESH_Multicast mc;
+ struct GNUNET_MessageHeader *mh;
+
+ GNUNET_assert (size >= th->size);
+ mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (mc)];
+ psize = th->notify (th->notify_cls, size - sizeof (mc), mh);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: multicast, type %u\n",
+ ntohs (mh->type));
+ if (psize > 0)
+ {
+ psize += sizeof (mc);
+ GNUNET_assert (size >= psize);
+ mc.header.size = htons (psize);
+ mc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
+ mc.tid = htonl (th->tunnel->tid);
+ memset (&mc.oid, 0, sizeof (struct GNUNET_PeerIdentity));
+ memcpy (cbuf, &mc, sizeof (mc));
+ }
+ }
+ else
+ {
+ /* unicast */
+ struct GNUNET_MESH_Unicast uc;
+ struct GNUNET_MessageHeader *mh;
+
+ GNUNET_assert (size >= th->size);
+ mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (uc)];
+ psize = th->notify (th->notify_cls, size - sizeof (uc), mh);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: unicast, type %u\n",
+ ntohs (mh->type));
+ if (psize > 0)
+ {
+ psize += sizeof (uc);
+ GNUNET_assert (size >= psize);
+ uc.header.size = htons (psize);
+ uc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
+ uc.tid = htonl (th->tunnel->tid);
+ memset (&uc.oid, 0, sizeof (struct GNUNET_PeerIdentity));
+ GNUNET_PEER_resolve (th->target, &uc.destination);
+ memcpy (cbuf, &uc, sizeof (uc));
+ }
+ }
+ }
+ else
+ {
+ memcpy (cbuf, &th[1], th->size);
+ psize = th->size;
+ }
+ if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (th->timeout_task);
+ GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
+ GNUNET_free (th);
+ cbuf += psize;
+ size -= psize;
+ tsize += psize;