1c0cf734055515481dada589083bf85229e3233f
[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         GNUNET_TRANSPORT_AddressLookUpCallback cb;
14         void *cls;
15         struct GNUNET_TIME_Absolute timeout;
16         struct GNUNET_CLIENT_Connection *client;
17 };
18
19
20 // FIXME: document
21 static void
22 address_response_processor(void *cls, const struct
23                            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, alucb,
59                                                                    GNUNET_TIME_absolute_get_remaining (alucb->timeout));
60                 }
61         }
62         alucb->cb (alucb->cls, address);
63         if (address == NULL)
64         {
65                 /* done! */
66                 GNUNET_CLIENT_disconnect (alucb->client);
67                 GNUNET_free (alucb);
68         }
69 }
70
71 void
72 GNUNET_TRANSPORT_address_lookup (struct GNUNET_SCHEDULER_Handle *sched,
73                                          const struct GNUNET_CONFIGURATION_Handle *cfg,
74                                  const char * address,
75                                  size_t addressLen,
76                                  const char * nameTrans,
77                                          struct GNUNET_TIME_Relative timeout,
78                                          GNUNET_TRANSPORT_AddressLookUpCallback aluc,
79                                          void *aluc_cls)
80 {
81         size_t len = sizeof (struct AddressLookupMessage) + addressLen + strlen (nameTrans) + 1;
82         struct AddressLookupMessage *msg;
83         struct GNUNET_TIME_Absolute abs_timeout;
84         struct AddressLookUpCB *aluCB;
85         struct GNUNET_CLIENT_Connection *client;
86
87         if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
88         {
89                 GNUNET_break (0);
90                 aluc (aluc_cls, NULL);
91                 return;
92         }
93         client = GNUNET_CLIENT_connect (sched, "transport", cfg);
94         if (client == NULL)
95         {
96                 aluc (aluc_cls, NULL);
97                 return;
98         }
99         abs_timeout = GNUNET_TIME_relative_to_absolute(timeout);
100         msg = GNUNET_malloc (len);
101         msg->header->size = htons (len);
102         msg->header->type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP);
103         msg->timeout = GNUNET_TIME_absolute_hton(abs_timeout);
104         msg->addrlen = htonl (addressLen);
105         char *addrbuf = (char*) &msg[1];
106         memcpy (addrbuf, address, addressLen);
107         char *tbuf = &addrbuf[addressLen];
108         memcpy (tbuf, nameTrans, strlen(nameTrans) + 1);
109         aluCB = GNUNET_malloc (sizeof (struct AddressLookUpCB));
110         aluCB->cb = aluc;
111         aluCB->cb_cls = aluc_cls;
112         aluCB->timeout = abs_timeout;
113         aluCB->client = client;
114         GNUNET_CLIENT_transmit_and_get_response(client, msg->header, timeout, GNUNET_YES, &address_response_processor, aluCB);
115     GNUNET_free(msg);
116 }