blob: e89e80dcbc1964ecf1b7eadb1bb3695e4236cf16 [file] [log] [blame]
akmhoque29c1db52012-09-07 14:47:43 -05001#include <stdio.h>
2#include <stdlib.h>
3#include <netinet/in.h>
4#include <netdb.h>
5#include <sys/time.h>
6#include <sys/types.h>
7#include <unistd.h>
8#include <stdarg.h>
9#include <string.h>
10
11#include <ccn/ccn.h>
12#include <ccn/uri.h>
13#include <ccn/face_mgmt.h>
14#include <ccn/reg_mgmt.h>
15#include <ccn/charbuf.h>
16
17#include "nlsr_fib.h"
18
19
20static void
21ccn_fib_warn(int lineno, const char *format, ...)
22{
23 struct timeval t;
24 va_list ap;
25 va_start(ap, format);
26 gettimeofday(&t, NULL);
27 fprintf(stderr, "%d.%06d ccn_fib[%d]:%d: ", (int)t.tv_sec, (unsigned)t.tv_usec, (int)getpid(), lineno);
28 vfprintf(stderr, format, ap);
29 va_end(ap);
30}
31
32#define ON_ERROR_CLEANUP(resval) \
33{ \
34 if ((resval) < 0) { \
35 ccn_fib_warn (__LINE__, "OnError cleanup\n"); \
36 goto cleanup; \
37 } \
38}
39
40#define ON_NULL_CLEANUP(resval) \
41{ \
42 if ((resval) == NULL) { \
43 ccn_fib_warn(__LINE__, "OnNull cleanup\n"); \
44 goto cleanup; \
45 } \
46}
47
48
49
50static int
51register_unregister_prefix(struct ccn *h, struct ccn_charbuf *local_scope_template,
52 struct ccn_charbuf *no_name, struct ccn_charbuf *name_prefix,const unsigned char *ccndid, size_t ccnd_id_size, int faceid, int operation)
53{
54 struct ccn_charbuf *temp = NULL;
55 struct ccn_charbuf *resultbuf = NULL;
56 struct ccn_charbuf *signed_info = NULL;
57 struct ccn_charbuf *name = NULL;
58 struct ccn_charbuf *prefixreg = NULL;
59 struct ccn_parsed_ContentObject pcobuf = {0};
60 struct ccn_forwarding_entry forwarding_entry_storage = {0};
61 struct ccn_forwarding_entry *forwarding_entry = &forwarding_entry_storage;
62 struct ccn_forwarding_entry *new_forwarding_entry;
63 const unsigned char *ptr = NULL;
64 size_t length = 0;
65 int res;
66
67 /* Register or unregister the prefix */
68 forwarding_entry->action = (operation == OP_REG) ? "prefixreg" : "unreg";
69 forwarding_entry->name_prefix = name_prefix;
70 forwarding_entry->ccnd_id = ccndid;
71 forwarding_entry->ccnd_id_size =ccnd_id_size;
72 forwarding_entry->faceid = faceid;
73 forwarding_entry->flags = -1;
74 forwarding_entry->lifetime = (~0U) >> 1;
75
76 prefixreg = ccn_charbuf_create();
77 ccnb_append_forwarding_entry(prefixreg, forwarding_entry);
78 temp = ccn_charbuf_create();
79 res = ccn_sign_content(h, temp, no_name, NULL, prefixreg->buf, prefixreg->length);
80 resultbuf = ccn_charbuf_create();
81
82 /* construct Interest containing prefixreg request */
83 name = ccn_charbuf_create();
84 ccn_name_init(name);
85 ccn_name_append_str(name, "ccnx");
86 ccn_name_append(name, ccndid, ccnd_id_size);
87 ccn_name_append_str(name, (operation == OP_REG) ? "prefixreg" : "unreg");
88 ccn_name_append(name, temp->buf, temp->length);
89
90 /* send Interest, get Data */
91 res = ccn_get(h, name, local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0);
92 ON_ERROR_CLEANUP(res);
93
94 res = ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length);
95 ON_ERROR_CLEANUP(res);
96
97 /* extract new forwarding entry from Data */
98 new_forwarding_entry = ccn_forwarding_entry_parse(ptr, length);
99 ON_NULL_CLEANUP(new_forwarding_entry);
100
101 res = new_forwarding_entry->faceid;
102
103 ccn_forwarding_entry_destroy(&new_forwarding_entry);
104 ccn_charbuf_destroy(&signed_info);
105 ccn_charbuf_destroy(&temp);
106 ccn_charbuf_destroy(&resultbuf);
107 ccn_charbuf_destroy(&name);
108 ccn_charbuf_destroy(&prefixreg);
109
110 return res;
111
112 cleanup:
113 ccn_forwarding_entry_destroy(&new_forwarding_entry);
114 ccn_charbuf_destroy(&signed_info);
115 ccn_charbuf_destroy(&temp);
116 ccn_charbuf_destroy(&resultbuf);
117 ccn_charbuf_destroy(&name);
118 ccn_charbuf_destroy(&prefixreg);
119
120 return -1;
121}
122
123
124static int
125get_ccndid(struct ccn *h, struct ccn_charbuf *local_scope_template,
126 unsigned char *ccndid)
127{
128 struct ccn_charbuf *name = NULL;
129 struct ccn_charbuf *resultbuf = NULL;
130 struct ccn_parsed_ContentObject pcobuf = {0};
131 char ccndid_uri[] = "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY";
132 const unsigned char *ccndid_result;
133 static size_t ccndid_result_size;
134 int res;
135
136 name = ccn_charbuf_create();
137 resultbuf = ccn_charbuf_create();
138
139 res = ccn_name_from_uri(name, ccndid_uri);
140 ON_ERROR_CLEANUP(res);
141
142 /* get Data */
143 res = ccn_get(h, name, local_scope_template, 4500, resultbuf, &pcobuf, NULL, 0);
144 ON_ERROR_CLEANUP(res);
145
146 /* extract from Data */
147 res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest,
148 resultbuf->buf,
149 pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest],
150 pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest],
151 &ccndid_result, &ccndid_result_size);
152 ON_ERROR_CLEANUP(res);
153
154 memcpy((void *)ccndid, ccndid_result, ccndid_result_size);
155
156 ccn_charbuf_destroy(&name);
157 ccn_charbuf_destroy(&resultbuf);
158
159 return (ccndid_result_size);
160
161 cleanup:
162 ccn_charbuf_destroy(&name);
163 ccn_charbuf_destroy(&resultbuf);
164
165 return -1;
166}
167
168static void
169init_data(struct ccn_charbuf *local_scope_template,
170 struct ccn_charbuf *no_name)
171{
172 ccn_charbuf_append_tt(local_scope_template, CCN_DTAG_Interest, CCN_DTAG);
173 ccn_charbuf_append_tt(local_scope_template, CCN_DTAG_Name, CCN_DTAG);
174 ccn_charbuf_append_closer(local_scope_template); /* </Name> */
175 ccnb_tagged_putf(local_scope_template, CCN_DTAG_Scope, "1");
176 ccn_charbuf_append_closer(local_scope_template); /* </Interest> */
177
178 ccn_name_init(no_name);
179}
180
181int
182add_delete_ccn_face_by_face_id(struct ccn *h, const char *uri, int operation, int faceid)
183{
184 struct ccn_charbuf *prefix;
185 struct ccn_charbuf *local_scope_template = ccn_charbuf_create();
186 struct ccn_charbuf *no_name = ccn_charbuf_create();
187 unsigned char ccndid_storage[32] = {0};
188 unsigned char *ccndid = ccndid_storage;
189 size_t ccndid_size = 0;
190 int res;
191
192 prefix = ccn_charbuf_create();
193 res = ccn_name_from_uri(prefix, uri);
194 ON_ERROR_CLEANUP(res);
195
196
197 init_data(local_scope_template, no_name);
198
199 ccndid_size = get_ccndid(h, local_scope_template, ccndid);
200 if (ccndid_size != sizeof(ccndid_storage))
201 {
202 fprintf(stderr, "Incorrect size for ccnd id in response\n");
203 ON_ERROR_CLEANUP(-1);
204 }
205
206 res = register_unregister_prefix(h, local_scope_template, no_name, prefix,ccndid, ccndid_size,faceid, operation);
207
208 ON_ERROR_CLEANUP(res);
209
210 ccn_charbuf_destroy(&local_scope_template);
211 ccn_charbuf_destroy(&no_name);
212 ccn_charbuf_destroy(&prefix);
213
214 return 0;
215
216 cleanup:
217 ccn_charbuf_destroy(&prefix);
218 ccn_charbuf_destroy(&local_scope_template);
219 ccn_charbuf_destroy(&no_name);
220
221 return -1;
222}
223
224