struct map_entry {
struct GNUNET_vpn_service_descriptor desc;
uint16_t namelen;
+ uint64_t additional_ports;
/**
* In DNS-Format!
*/
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Mapping exists; type: %d; UDP is %d; port: %x/%x!\n", me->desc.service_type, htonl(GNUNET_DNS_SERVICE_TYPE_UDP), pkt6_udp->udp_hdr.dpt, me->desc.ports);
GNUNET_free(key);
if (me->desc.service_type & htonl(GNUNET_DNS_SERVICE_TYPE_UDP) &&
- port_in_ports(me->desc.ports, pkt6_udp->udp_hdr.dpt))
+ (port_in_ports(me->desc.ports, pkt6_udp->udp_hdr.dpt) ||
+ port_in_ports(me->additional_ports, pkt6_udp->udp_hdr.dpt)))
{
size_t size = sizeof(struct GNUNET_PeerIdentity) + sizeof(struct GNUNET_MessageHeader) + sizeof(GNUNET_HashCode) + ntohs(pkt6_udp->udp_hdr.len);
struct GNUNET_PeerIdentity *cls = GNUNET_malloc(size);
uint16_t namelen = strlen((char*)pkt->data+12)+1;
- struct map_entry* value = GNUNET_malloc(sizeof(struct GNUNET_vpn_service_descriptor) + 2 + namelen);
+ struct map_entry* value = GNUNET_malloc(sizeof(struct GNUNET_vpn_service_descriptor) + 2 + 8 + namelen);
value->namelen = namelen;
memcpy(value->name, pkt->data+12, namelen);
memcpy(&value->desc, &pkt->service_descr, sizeof(struct GNUNET_vpn_service_descriptor));
+ value->additional_ports = 0;
+
if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(hashmap,
&key,
value,
char buf[1400];
- ssize_t len = GNUNET_NETWORK_socket_recv (data->sock, buf, 1400);
+ struct sockaddr_in addr_in;
+ socklen_t addr_len = sizeof(struct sockaddr_in);
+ ssize_t len = GNUNET_NETWORK_socket_recvfrom (data->sock, buf, 1400, (struct sockaddr*)&addr_in, &addr_len);
if (len < 0) {
GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Problem reading from socket: %m\n");
hdr->type = htons (GNUNET_MESSAGE_TYPE_SERVICE_UDP_BACK);
pkt->dpt = htons(data->state.spt);
- pkt->spt = htons(data->state.dpt);
+ pkt->spt = addr_in.sin_port;
pkt->len = htons (len_udp);
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "UDP from %d to %d\n", ntohs(pkt->spt), ntohs(pkt->dpt));
/* The chksm can only be computed knowing the ip-addresses */
}
+static void
+add_additional_port (struct map_entry *me, uint16_t port)
+{
+ uint16_t *ps = (uint16_t *) & me->additional_ports;
+ unsigned int i;
+ for (i = 0; i < 4; i++)
+ {
+ if (ps[i] == 0)
+ {
+ ps[i] = port;
+ break;
+ }
+ }
+}
+
static int
receive_udp_back (void *cls, const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
struct ip6_udp* pkt6 = alloca(size);
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Relaying calc:%d gnu:%d udp:%d bytes!\n", size, ntohs(message->size), ntohs(pkt->len));
+
pkt6->shdr.type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
pkt6->shdr.size = htons(size);
memcpy(&pkt6->udp_hdr, pkt, ntohs(pkt->len));
+ GNUNET_HashCode* key = address_mapping_exists(pkt6->ip6_hdr.sadr);
+ GNUNET_assert (key != NULL);
+
+ struct map_entry *me = GNUNET_CONTAINER_multihashmap_get(hashmap, key);
+
+ GNUNET_free(key);
+
+ GNUNET_assert (me != NULL);
+ GNUNET_assert (me->desc.service_type & htonl(GNUNET_DNS_SERVICE_TYPE_UDP));
+ if (!port_in_ports(me->desc.ports, pkt6->udp_hdr.spt) ||
+ !port_in_ports(me->additional_ports, pkt6->udp_hdr.spt)) {
+ add_additional_port(me, pkt6->udp_hdr.spt);
+ }
+
pkt6->udp_hdr.crc = 0;
uint32_t sum = 0;
sum = calculate_checksum_update(sum, (uint16_t*)&pkt6->ip6_hdr.sadr, 16);
memcpy (&state->peer, other, sizeof (struct GNUNET_PeerIdentity));
memcpy (&state->desc, desc, sizeof (GNUNET_HashCode));
state->spt = ntohs (pkt->spt);
- state->dpt = ntohs (pkt->dpt);
+
+ /* Hash without the dpt, so that eg tftp works */
+ state->dpt = 0;
memcpy (send + 1, pkt, ntohs (pkt->len));
GNUNET_HashCode hash;
GNUNET_CRYPTO_hash (state, state_size, &hash);
+ state->dpt = ntohs (pkt->dpt);
+
struct GNUNET_NETWORK_Handle *sock =
GNUNET_CONTAINER_multihashmap_get (udp_connections, &hash);