aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-service-gns_reverser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-service-gns_reverser.c')
-rw-r--r--src/gns/gnunet-service-gns_reverser.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/gns/gnunet-service-gns_reverser.c b/src/gns/gnunet-service-gns_reverser.c
new file mode 100644
index 000000000..6bae20b61
--- /dev/null
+++ b/src/gns/gnunet-service-gns_reverser.c
@@ -0,0 +1,244 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file gns/gnunet-service-gns_reverser.c
22 * @brief GNUnet GNS service
23 * @author Martin Schanzenbach
24 */
25
26
27#include "platform.h"
28#include "gnunet_gns_service.h"
29#include "gnunet-service-gns_resolver.h"
30#include "gnunet-service-gns_reverser.h"
31
32struct ReverseTreeNode
33{
34 /**
35 * DLL
36 */
37 struct ReverseTreeNode *next;
38
39 /**
40 * DLL
41 */
42 struct ReverseTreeNode *prev;
43
44 /**
45 * Resolved name until now
46 */
47 char *name;
48
49 /**
50 * Depth of the resolution at this node
51 */
52 uint8_t depth;
53
54 /**
55 * The pkey of the namespace
56 */
57 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
58
59};
60
61
62struct GNS_ReverserHandle
63{
64 /**
65 * GNS resolver handle
66 */
67 struct GNS_ResolverHandle *rh;
68
69 /**
70 * The authority to look for
71 */
72 struct GNUNET_CRYPTO_EcdsaPublicKey authority;
73
74 /**
75 * Resolution candidate queue
76 */
77 struct ReverseTreeNode *node_queue_head;
78
79 /**
80 * Resolution candidate queue
81 */
82 struct ReverseTreeNode *node_queue_tail;
83
84 /**
85 * Max depth for the resolution
86 */
87 uint8_t max_depth;
88
89 /**
90 * Result callback
91 */
92 GNS_ReverseResultProcessor proc;
93
94 /**
95 * Callback closure
96 */
97 void *proc_cls;
98};
99
100void
101cleanup_handle (struct GNS_ReverserHandle *rh)
102{
103 struct ReverseTreeNode *rtn;
104
105 for (rtn = rh->node_queue_head; NULL != rtn; rtn = rh->node_queue_head)
106 {
107 if (NULL != rtn->name)
108 GNUNET_free (rtn->name);
109 GNUNET_CONTAINER_DLL_remove (rh->node_queue_head,
110 rh->node_queue_tail,
111 rtn);
112 GNUNET_free (rtn);
113 }
114}
115
116void
117handle_gns_result (void *cls,
118 uint32_t rd_count,
119 const struct GNUNET_GNSRECORD_Data *rd)
120{
121 struct GNS_ReverserHandle *rh = cls;
122 const struct GNUNET_GNSRECORD_ReverseRecord *rr;
123 struct ReverseTreeNode *rtn;
124 char *result;
125 const char *name;
126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
127 "Got result (%d)\n", rd_count);
128
129 for (int i = 0; i < rd_count; i++)
130 {
131 /**
132 * Check if we are in the delegation set
133 */
134 if (GNUNET_GNSRECORD_TYPE_REVERSE != rd[i].record_type)
135 continue;
136 rr = rd[i].data;
137 name = (const char*) &rr[1];
138 if (0 == memcmp (&rh->authority,
139 &rr->pkey,
140 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
141 {
142 //Found!
143 GNUNET_asprintf (&result,
144 "%s.%s.gnu",
145 rh->node_queue_head->name,
146 name);
147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
148 "Found path from %s\n", result);
149
150 rh->proc (rh->proc_cls, result);
151 cleanup_handle (rh);
152 GNUNET_free (result);
153 return;
154 } else {
155 if (rh->node_queue_head->depth >= rh->max_depth)
156 break;
157 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
158 "Found REVERSE from %s\n", name);
159
160 rtn = GNUNET_new (struct ReverseTreeNode);
161 if (NULL == rh->node_queue_head->name)
162 rtn->name = GNUNET_strdup (name);
163 else
164 GNUNET_asprintf (&rtn->name,
165 "%s.%s",
166 rh->node_queue_head->name,
167 name);
168 rtn->depth = rh->node_queue_head->depth + 1;
169 rtn->pkey = rr->pkey;
170 GNUNET_CONTAINER_DLL_insert_tail (rh->node_queue_head,
171 rh->node_queue_tail,
172 rtn);
173 }
174 }
175
176 /**
177 * Done here remove node from queue
178 */
179 rtn = rh->node_queue_head;
180 GNUNET_CONTAINER_DLL_remove (rh->node_queue_head,
181 rh->node_queue_tail,
182 rtn);
183 if (NULL == rh->node_queue_head)
184 {
185 //No luck
186 rh->proc (rh->proc_cls, NULL);
187 cleanup_handle (rh);
188 return;
189 }
190 rh->rh = GNS_resolver_lookup (&rh->node_queue_head->pkey,
191 GNUNET_GNSRECORD_TYPE_REVERSE,
192 "+.gnu",
193 NULL,
194 GNUNET_GNS_LO_DEFAULT,
195 &handle_gns_result,
196 rh);
197}
198
199struct GNS_ReverserHandle *
200GNS_reverse_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *target,
201 const struct GNUNET_CRYPTO_EcdsaPublicKey *authority,
202 GNS_ReverseResultProcessor proc,
203 void *proc_cls)
204{
205 struct GNS_ReverserHandle *rh;
206 struct ReverseTreeNode *rtn;
207
208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
209 "Starting reverse resolution\n");
210 rh = GNUNET_new (struct GNS_ReverserHandle);
211 rh->proc = proc;
212 rh->proc_cls = proc_cls;
213 rtn = GNUNET_new (struct ReverseTreeNode);
214 rtn->name = NULL;
215 rtn->pkey = *target;
216 rtn->depth = 0;
217 GNUNET_CONTAINER_DLL_insert (rh->node_queue_head,
218 rh->node_queue_tail,
219 rtn);
220 rh->authority = *authority;
221 rh->max_depth = 3; //TODO make argument
222 rh->rh = GNS_resolver_lookup (target,
223 GNUNET_GNSRECORD_TYPE_REVERSE,
224 "+.gnu",
225 NULL,
226 GNUNET_GNS_LO_DEFAULT,
227 &handle_gns_result,
228 rh);
229 return rh;
230}
231
232/**
233 * Cancel active resolution (i.e. client disconnected).
234 *
235 * @param rh resolution to abort
236 */
237void
238GNS_reverse_lookup_cancel (struct GNS_ReverserHandle *rh)
239{
240 cleanup_handle (rh);
241 return;
242}
243
244