aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport_api_address_lookup.c
blob: d2bc51d471a94384e120b14de2bf755d221f8136 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "platform.h"
#include "gnunet_client_lib.h"
#include "gnunet_arm_service.h"
#include "gnunet_hello_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_server_lib.h"
#include "gnunet_time_lib.h"
#include "gnunet_transport_service.h"
#include "transport.h"

// FIXME: document
struct AddressLookUpCB
{
  GNUNET_TRANSPORT_AddressLookUpCallback cb;
  void *cls;
  struct GNUNET_TIME_Absolute timeout;
  struct GNUNET_CLIENT_Connection *client;
};


// FIXME: document
static void
address_response_processor (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct AddressLookUpCB *alucb = cls;
  const char *address;
  uint16_t size;

  if (msg == NULL)
    {
      /* timeout */
      alucb->cb (alucb->cls, NULL);
      GNUNET_CLIENT_disconnect (alucb->client);
      GNUNET_free (alucb);
      return;
    }
  size = ntohs (msg->size);
  if (size == sizeof (struct GNUNET_MessageHeader))
    {
      /* last reply */
      address = NULL;
    }
  else
    {
      address = (const char *) &msg[1];
      if (address[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0')
        {
          /* invalid reply */
          GNUNET_break_op (0);
          alucb->cb (alucb->cls, NULL);
          GNUNET_CLIENT_disconnect (alucb->client);
          GNUNET_free (alucb);
          return;
        }
      else
        {
          /* expect more replies */
          GNUNET_CLIENT_receive (alucb->client, &address_response_processor,
                                 alucb,
                                 GNUNET_TIME_absolute_get_remaining
                                 (alucb->timeout));
        }
    }
  alucb->cb (alucb->cls, address);
  if (address == NULL)
    {
      /* done! */
      GNUNET_CLIENT_disconnect (alucb->client);
      GNUNET_free (alucb);
    }
}

void
GNUNET_TRANSPORT_address_lookup (struct GNUNET_SCHEDULER_Handle *sched,
                                 const struct GNUNET_CONFIGURATION_Handle
                                 *cfg, const char *address, size_t addressLen,
                                 const char *nameTrans,
                                 struct GNUNET_TIME_Relative timeout,
                                 GNUNET_TRANSPORT_AddressLookUpCallback aluc,
                                 void *aluc_cls)
{
  size_t len =
    sizeof (struct AddressLookupMessage) + addressLen + strlen (nameTrans) +
    1;
  struct AddressLookupMessage *msg;
  struct GNUNET_TIME_Absolute abs_timeout;
  struct AddressLookUpCB *aluCB;
  struct GNUNET_CLIENT_Connection *client;

  if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
    {
      GNUNET_break (0);
      aluc (aluc_cls, NULL);
      return;
    }
  client = GNUNET_CLIENT_connect (sched, "transport", cfg);
  if (client == NULL)
    {
      aluc (aluc_cls, NULL);
      return;
    }
  abs_timeout = GNUNET_TIME_relative_to_absolute (timeout);
  msg = GNUNET_malloc (len);
  msg->header->size = htons (len);
  msg->header->type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP);
  msg->timeout = GNUNET_TIME_absolute_hton (abs_timeout);
  msg->addrlen = htonl (addressLen);
  char *addrbuf = (char *) &msg[1];
  memcpy (addrbuf, address, addressLen);
  char *tbuf = &addrbuf[addressLen];
  memcpy (tbuf, nameTrans, strlen (nameTrans) + 1);
  aluCB = GNUNET_malloc (sizeof (struct AddressLookUpCB));
  aluCB->cb = aluc;
  aluCB->cb_cls = aluc_cls;
  aluCB->timeout = abs_timeout;
  aluCB->client = client;
  GNUNET_CLIENT_transmit_and_get_response (client, msg->header, timeout,
                                           GNUNET_YES,
                                           &address_response_processor,
                                           aluCB);
  GNUNET_free (msg);
}