4293b18f82e26614a619a3af0375ae4c2aa1caff
[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. GNUNET_NO);
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, GNUNET_NO);
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
61                                  (alucb->timeout));
62         }
63     }
64   alucb->cb (alucb->cls, address);
65   if (address == NULL)
66     {
67       /* done! */
68       GNUNET_CLIENT_disconnect (alucb->client, GNUNET_NO);
69       GNUNET_free (alucb);
70     }
71 }
72
73 /**
74  * Convert a binary address into a human readable address.
75  *
76  * @param sched scheduler to use
77  * @param cfg configuration to use
78  * @param address address to convert (binary format)
79  * @param addressLen number of bytes in address
80  * @param numeric should (IP) addresses be displayed in numeric form 
81  *                (otherwise do reverse DNS lookup)
82  * @param nameTrans name of the transport to which the address belongs
83  * @param timeout how long is the lookup allowed to take at most
84  * @param aluc function to call with the results
85  * @param aluc_cls closure for aluc
86  */
87 void
88 GNUNET_TRANSPORT_address_lookup (struct GNUNET_SCHEDULER_Handle *sched,
89                                  const struct GNUNET_CONFIGURATION_Handle  *cfg, 
90                                  const char *address, 
91                                  size_t addressLen,
92                                  int numeric,
93                                  const char *nameTrans,
94                                  struct GNUNET_TIME_Relative timeout,
95                                  GNUNET_TRANSPORT_AddressLookUpCallback aluc,
96                                  void *aluc_cls)
97 {
98   size_t len =
99     sizeof (struct AddressLookupMessage) + addressLen + strlen (nameTrans) +
100     1;
101   struct AddressLookupMessage *msg;
102   struct GNUNET_TIME_Absolute abs_timeout;
103   struct AddressLookUpCB *aluCB;
104   struct GNUNET_CLIENT_Connection *client;
105
106   if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
107     {
108       GNUNET_break (0);
109       aluc (aluc_cls, NULL);
110       return;
111     }
112   client = GNUNET_CLIENT_connect (sched, "transport", cfg);
113   if (client == NULL)
114     {
115       aluc (aluc_cls, NULL);
116       return;
117     }
118   abs_timeout = GNUNET_TIME_relative_to_absolute (timeout);
119   msg = GNUNET_malloc (len);
120   msg->header->size = htons (len);
121   msg->header->type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP);
122   msg->timeout = GNUNET_TIME_absolute_hton (abs_timeout);
123   msg->addrlen = htonl (addressLen);
124   char *addrbuf = (char *) &msg[1];
125   memcpy (addrbuf, address, addressLen);
126   char *tbuf = &addrbuf[addressLen];
127   memcpy (tbuf, nameTrans, strlen (nameTrans) + 1);
128   aluCB = GNUNET_malloc (sizeof (struct AddressLookUpCB));
129   aluCB->cb = aluc;
130   aluCB->cb_cls = aluc_cls;
131   aluCB->timeout = abs_timeout;
132   aluCB->client = client;
133   GNUNET_CLIENT_transmit_and_get_response (client, msg->header, timeout,
134                                            GNUNET_YES,
135                                            &address_response_processor,
136                                            aluCB);
137   GNUNET_free (msg);
138 }