pre-commit
[oweals/gnunet.git] / src / transport / transport_api_address_lookup.c
1 #include "platform.h"
2 #include "gnunet_client_lib.h"
3 #include "gnunet_arm_service.h"
4 #include "gnunet_hello_lib.h"
5 #include "gnunet_protocols.h"
6 #include "gnunet_server_lib.h"
7 #include "gnunet_time_lib.h"
8 #include "gnunet_transport_service.h"
9 #include "transport.h"
10
11 // FIXME: document
12 struct AddressLookUpCB
13 {
14   GNUNET_TRANSPORT_AddressLookUpCallback cb;
15   void *cls;
16   struct GNUNET_TIME_Absolute timeout;
17   struct GNUNET_CLIENT_Connection *client;
18 };
19
20
21 // FIXME: document
22 static void
23 address_response_processor (void *cls, const struct GNUNET_MessageHeader *msg)
24 {
25   struct AddressLookUpCB *alucb = cls;
26   const char *address;
27   uint16_t size;
28
29   if (msg == NULL)
30     {
31       /* timeout */
32       alucb->cb (alucb->cls, NULL);
33       GNUNET_CLIENT_disconnect (alucb->client);
34       GNUNET_free (alucb);
35       return;
36     }
37   size = ntohs (msg->size);
38   if (size == sizeof (struct GNUNET_MessageHeader))
39     {
40       /* last reply */
41       address = NULL;
42     }
43   else
44     {
45       address = (const char *) &msg[1];
46       if (address[size - sizeof (struct GNUNET_MessageHeader) - 1] != '\0')
47         {
48           /* invalid reply */
49           GNUNET_break_op (0);
50           alucb->cb (alucb->cls, NULL);
51           GNUNET_CLIENT_disconnect (alucb->client);
52           GNUNET_free (alucb);
53           return;
54         }
55       else
56         {
57           /* expect more replies */
58           GNUNET_CLIENT_receive (alucb->client, &address_response_processor,
59                                  alucb,
60                                  GNUNET_TIME_absolute_get_remaining (alucb->
61                                                                      timeout));
62         }
63     }
64   alucb->cb (alucb->cls, address);
65   if (address == NULL)
66     {
67       /* done! */
68       GNUNET_CLIENT_disconnect (alucb->client);
69       GNUNET_free (alucb);
70     }
71 }
72
73 void
74 GNUNET_TRANSPORT_address_lookup (struct GNUNET_SCHEDULER_Handle *sched,
75                                  const struct GNUNET_CONFIGURATION_Handle
76                                  *cfg, const char *address, size_t addressLen,
77                                  const char *nameTrans,
78                                  struct GNUNET_TIME_Relative timeout,
79                                  GNUNET_TRANSPORT_AddressLookUpCallback aluc,
80                                  void *aluc_cls)
81 {
82   size_t len =
83     sizeof (struct AddressLookupMessage) + addressLen + strlen (nameTrans) +
84     1;
85   struct AddressLookupMessage *msg;
86   struct GNUNET_TIME_Absolute abs_timeout;
87   struct AddressLookUpCB *aluCB;
88   struct GNUNET_CLIENT_Connection *client;
89
90   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
91     {
92       GNUNET_break (0);
93       aluc (aluc_cls, NULL);
94       return;
95     }
96   client = GNUNET_CLIENT_connect (sched, "transport", cfg);
97   if (client == NULL)
98     {
99       aluc (aluc_cls, NULL);
100       return;
101     }
102   abs_timeout = GNUNET_TIME_relative_to_absolute (timeout);
103   msg = GNUNET_malloc (len);
104   msg->header->size = htons (len);
105   msg->header->type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP);
106   msg->timeout = GNUNET_TIME_absolute_hton (abs_timeout);
107   msg->addrlen = htonl (addressLen);
108   char *addrbuf = (char *) &msg[1];
109   memcpy (addrbuf, address, addressLen);
110   char *tbuf = &addrbuf[addressLen];
111   memcpy (tbuf, nameTrans, strlen (nameTrans) + 1);
112   aluCB = GNUNET_malloc (sizeof (struct AddressLookUpCB));
113   aluCB->cb = aluc;
114   aluCB->cb_cls = aluc_cls;
115   aluCB->timeout = abs_timeout;
116   aluCB->client = client;
117   GNUNET_CLIENT_transmit_and_get_response (client, msg->header, timeout,
118                                            GNUNET_YES,
119                                            &address_response_processor,
120                                            aluCB);
121   GNUNET_free (msg);
122 }