*/
struct GNUNET_CADET_Port *port;
- /**
- * Port I am listening on within GNUnet for this service, in host
- * byte order. (as we may redirect ports).
- */
- uint16_t my_port;
-
/**
* #GNUNET_YES if this is a UDP service, otherwise TCP.
*/
uint16_t destination_port,
struct LocalService *service)
{
- char key[sizeof (struct GNUNET_HashCode) + sizeof (uint16_t)];
+ struct GNUNET_HashCode cadet_port;
+ service->name = GNUNET_strdup (name);
GNUNET_TUN_service_name_to_hash (name,
&service->descriptor);
- service->name = GNUNET_strdup (name);
- GNUNET_memcpy (&key[0],
- &destination_port,
- sizeof (uint16_t));
- GNUNET_memcpy (&key[sizeof(uint16_t)],
- &service->descriptor,
- sizeof (struct GNUNET_HashCode));
+ GNUNET_TUN_compute_service_cadet_port (&service->descriptor,
+ destination_port,
+ &cadet_port);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Opening CADET port %s for SERVICE exit %s on port %u\n",
+ GNUNET_h2s (&cadet_port),
+ name,
+ (unsigned int) destination_port);
service->port = GNUNET_CADET_open_port (cadet_handle,
- &service->descriptor,
+ &cadet_port,
&new_service_channel,
service);
service->is_udp = (IPPROTO_UDP == proto);
if (GNUNET_OK !=
GNUNET_CONTAINER_multihashmap_put (services,
- (struct GNUNET_HashCode *) key,
+ &cadet_port,
service,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
{
- free_service_record (NULL,
- (struct GNUNET_HashCode *) key,
- service);
+ GNUNET_CADET_close_port (service->port);
+ GNUNET_free_non_null (service->name);
+ GNUNET_free (service);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("Got duplicate service records for `%s:%u'\n"),
name,
GNUNET_assert (slen >= 8);
n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
- for (redirect = strtok (cpy, " "); redirect != NULL;
- redirect = strtok (NULL, " "))
+ for (redirect = strtok (cpy, " ;"); redirect != NULL;
+ redirect = strtok (NULL, " ;"))
{
if (NULL == (hostname = strstr (redirect, ":")))
{
serv = GNUNET_new (struct LocalService);
serv->address.proto = proto;
- serv->my_port = (uint16_t) local_port;
serv->address.port = remote_port;
if (0 == strcmp ("localhost4",
hostname))
* the network.
*
* @param service_name a string
- * @param hc corresponding hash
+ * @param[out] hc corresponding hash
*/
void
GNUNET_TUN_service_name_to_hash (const char *service_name,
struct GNUNET_HashCode *hc);
+
+/**
+ * Compute the CADET port given a service descriptor
+ * (returned from #GNUNET_TUN_service_name_to_hash) and
+ * a TCP/UDP port @a ip_port.
+ *
+ * @param desc service shared secret
+ * @param ip_port TCP/UDP port, use 0 for ICMP
+ * @param[out] cadet_port CADET port to use
+ */
+void
+GNUNET_TUN_compute_service_cadet_port (const struct GNUNET_HashCode *desc,
+ uint16_t ip_port,
+ struct GNUNET_HashCode *cadet_port);
+
#endif
/** @} */ /* end of group */
}
+/**
+ * Compute the CADET port given a service descriptor
+ * (returned from #GNUNET_TUN_service_name_to_hash) and
+ * a TCP/UDP port @a ip_port.
+ *
+ * @param desc service shared secret
+ * @param ip_port TCP/UDP port, use 0 for ICMP
+ * @param[out] cadet_port CADET port to use
+ */
+void
+GNUNET_TUN_compute_service_cadet_port (const struct GNUNET_HashCode *desc,
+ uint16_t ip_port,
+ struct GNUNET_HashCode *cadet_port)
+{
+ uint16_t be_port = htons (ip_port);
+
+ *cadet_port = *desc;
+ GNUNET_memcpy (cadet_port,
+ &be_port,
+ sizeof (uint16_t));
+}
+
+
/* end of regex.c */
ts->af = client_af;
ts->destination = *dt->destination;
ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
+ ts->destination_port = dt->destination_port;
if (dt->destination->is_service)
{
+ struct GNUNET_HashCode cadet_port;
+
+ GNUNET_TUN_compute_service_cadet_port (&ts->destination.details.service_destination.service_descriptor,
+ ts->destination_port,
+ &cadet_port);
ts->channel
= GNUNET_CADET_channel_create (cadet_handle,
ts,
&dt->destination->details.service_destination.target,
- &ts->destination.details.service_destination.service_descriptor,
+ &cadet_port,
GNUNET_CADET_OPTION_DEFAULT);
if (NULL == ts->channel)
{
return NULL;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Creating channel %p to peer %s offering service %s\n",
- ts->channel,
+ "Creating channel to peer %s offering service %s on port %u\n",
GNUNET_i2s (&dt->destination->details.service_destination.target),
- GNUNET_h2s (&ts->destination.details.service_destination.service_descriptor));
+ GNUNET_h2s (&ts->destination.details.service_destination.service_descriptor),
+ (unsigned int) ts->destination_port);
}
else
{
GNUNET_h2s (&destination->details.service_destination.service_descriptor),
GNUNET_i2s (&destination->details.service_destination.target));
}
- dt = destination->dt_head;
+ for (dt = destination->dt_head; NULL != dt; dt = dt->next)
+ if (dt->destination_port == destination_port)
+ break;
}
if (NULL == dt)
{
GNUNET_h2s (&key));
/* need to either use the existing channel from the destination (if still
available) or create a fresh one */
- ts = create_channel_to_destination (dt, af);
+ ts = create_channel_to_destination (dt,
+ af);
if (NULL == ts)
return;
/* now bind existing "unbound" channel to our IP/port tuple */