blob: b2b7eb92c69493c609ee731d5f57cd9c5fe81b4d [file] [log] [blame]
akmhoque59980a52012-08-09 12:36:09 -05001#include<stdio.h>
2#include<string.h>
3#include<stdlib.h>
4#include <unistd.h>
5#include <getopt.h>
6#include <sys/time.h>
7#include <assert.h>
8#ifdef HAVE_CONFIG_H
9#include <config.h>
10#endif
akmhoque03004e62012-09-06 01:12:28 -050011#include <sys/types.h>
12#include <signal.h>
13
akmhoque59980a52012-08-09 12:36:09 -050014
15
16#include <ccn/ccn.h>
17#include <ccn/uri.h>
18#include <ccn/keystore.h>
19#include <ccn/signing.h>
20#include <ccn/schedule.h>
21#include <ccn/hashtb.h>
22
23#include "nlsr.h"
24#include "nlsr_ndn.h"
akmhoque902d57e2012-08-17 09:24:38 -050025#include "nlsr_lsdb.h"
akmhoque53f64222012-09-05 13:57:51 -050026#include "utility.h"
akmhoque03004e62012-09-06 01:12:28 -050027#include "nlsr_npl.h"
28#include "nlsr_adl.h"
akmhoque3560cb62012-09-09 10:52:30 -050029#include "nlsr_npt.h"
30#include "nlsr_route.h"
31
32
akmhoque81c25e02012-09-10 14:50:33 -050033#define ON_ERROR_DESTROY(resval) \
34{ \
35 if ((resval) < 0) { \
36 nlsr_destroy(); \
37 } \
38}
39
40
41#define ON_ERROR_EXIT(resval) \
42{ \
43 if ((resval) < 0) { \
44 exit(-1); \
45 } \
46}
akmhoque59980a52012-08-09 12:36:09 -050047
48struct option longopts[] =
49{
50 { "daemon", no_argument, NULL, 'd'},
51 { "config_file", required_argument, NULL, 'f'},
52 { "help", no_argument, NULL, 'h'},
53 { 0 }
54};
55
56static int
57usage(char *progname)
58{
59
60 printf("Usage: %s [OPTIONS...]\n\
61 NDN routing....\n\
62 -d, --daemon Run in daemon mode\n\
63 -f, --config_file Specify configuration file name\n\
64 -h, --help Display this help message\n", progname);
65
66 exit(1);
67}
68
69void ndn_rtr_gettime(const struct ccn_gettime *self, struct ccn_timeval *result)
70{
71 struct timeval now = {0};
72 gettimeofday(&now, 0);
73 result->s = now.tv_sec;
74 result->micros = now.tv_usec;
75}
76
77static struct ccn_gettime ndn_rtr_ticker = {
78 "timer",
79 &ndn_rtr_gettime,
80 1000000,
81 NULL
82};
83
akmhoque42098b12012-08-27 22:54:23 -050084
85void
akmhoque03004e62012-09-06 01:12:28 -050086nlsr_stop_signal_handler(int sig)
akmhoque42098b12012-08-27 22:54:23 -050087{
akmhoque03004e62012-09-06 01:12:28 -050088 signal(sig, SIG_IGN);
89 nlsr_destroy();
akmhoque59980a52012-08-09 12:36:09 -050090}
91
92void
93process_command_ccnneighbor(char *command)
94{
95 if(command==NULL)
96 {
akmhoque28c45022012-08-09 15:38:02 -050097 printf(" Wrong Command Format ( ccnneighbor router_name faceX)\n");
akmhoque59980a52012-08-09 12:36:09 -050098 return;
99 }
100 char *rem;
101 const char *sep=" \t\n";
akmhoque28c45022012-08-09 15:38:02 -0500102 char *rtr_name,*face;
akmhoque59980a52012-08-09 12:36:09 -0500103
akmhoque28c45022012-08-09 15:38:02 -0500104 rtr_name=strtok_r(command,sep,&rem);
105 if(rtr_name==NULL)
akmhoque59980a52012-08-09 12:36:09 -0500106 {
akmhoque28c45022012-08-09 15:38:02 -0500107 printf(" Wrong Command Format ( ccnneighbor router_name faceX)\n");
akmhoque59980a52012-08-09 12:36:09 -0500108 return;
109 }
110
111 face=strtok_r(NULL,sep,&rem);
112 if(face==NULL)
113 {
akmhoque28c45022012-08-09 15:38:02 -0500114 printf(" Wrong Command Format ( ccnneighbor router_name faceX)\n");
akmhoque59980a52012-08-09 12:36:09 -0500115 return;
116 }
117
akmhoque28c45022012-08-09 15:38:02 -0500118 printf("Router: %s face: %s\n",rtr_name,face);
119 int face_id;
120 int res;
121 res=sscanf(face,"face%d",&face_id);
122
123 if(res != 1 )
124 {
125 printf(" Wrong Command Format ( ccnneighbor router_name faceX) where X is integer\n");
126 return;
127 }
128
akmhoque03004e62012-09-06 01:12:28 -0500129 struct name_prefix *nbr=(struct name_prefix *)malloc(sizeof(struct name_prefix ));
130 nbr->name=(char *)malloc(strlen(rtr_name)+1);
131 memset(nbr->name,0,strlen(rtr_name)+1);
132 memcpy(nbr->name,rtr_name,strlen(rtr_name)+1);
133 nbr->length=strlen(rtr_name)+1;
134
135 add_nbr_to_adl(nbr,face_id);
136
137 free(nbr->name);
138 free(nbr);
139}
140
141void
142process_command_ccnname(char *command)
143{
144
145 if(command==NULL)
146 {
147 printf(" Wrong Command Format ( ccnname /name/prefix)\n");
148 return;
149 }
150 char *rem;
151 const char *sep=" \t\n";
152 char *name;
153 name=strtok_r(command,sep,&rem);
154 if(name==NULL)
155 {
156 printf(" Wrong Command Format ( ccnname /name/prefix/ )\n");
157 return;
158 }
159
160 printf("Name Prefix: %s \n",name);
161
akmhoque53f64222012-09-05 13:57:51 -0500162 struct name_prefix *np=(struct name_prefix *)malloc(sizeof(struct name_prefix ));
akmhoque03004e62012-09-06 01:12:28 -0500163 np->name=(char *)malloc(strlen(name)+1);
164 memset(np->name,0,strlen(name)+1);
165 memcpy(np->name,name,strlen(name)+1);
166 np->length=strlen(name)+1;
akmhoque386081b2012-08-10 10:53:21 -0500167
akmhoque03004e62012-09-06 01:12:28 -0500168 add_name_to_npl(np);
akmhoque28c45022012-08-09 15:38:02 -0500169
akmhoque03004e62012-09-06 01:12:28 -0500170 free(np->name);
akmhoque53f64222012-09-05 13:57:51 -0500171 free(np);
akmhoque59980a52012-08-09 12:36:09 -0500172}
173
akmhoque03004e62012-09-06 01:12:28 -0500174
175void
176process_command_router_name(char *command)
177{
178 if(command==NULL)
179 {
180 printf(" Wrong Command Format ( router-name /router/name )\n");
181 return;
182 }
183 char *rem;
184 const char *sep=" \t\n";
185 char *rtr_name;
186
187 rtr_name=strtok_r(command,sep,&rem);
188 if(rtr_name==NULL)
189 {
190 printf(" Wrong Command Format ( router-name /router/name )\n");
191 return;
192 }
193
194
195 nlsr->router_name=(char *)malloc(strlen(rtr_name)+1);
196 memset(nlsr->router_name,0,strlen(rtr_name)+1);
197 memcpy(nlsr->router_name,rtr_name,strlen(rtr_name)+1);
198
199
200}
201
akmhoque59980a52012-08-09 12:36:09 -0500202void
akmhoqued79438d2012-08-27 13:31:42 -0500203process_command_lsdb_synch_interval(char *command)
204{
205 if(command==NULL)
206 {
207 printf(" Wrong Command Format ( lsdb-synch-interval secs )\n");
208 return;
209 }
210 char *rem;
211 const char *sep=" \t\n";
212 char *secs;
213 long int seconds;
214
215 secs=strtok_r(command,sep,&rem);
216 if(secs==NULL)
217 {
218 printf(" Wrong Command Format ( lsdb-synch-interval secs)\n");
219 return;
220 }
221
222 seconds=atoi(secs);
223 nlsr->lsdb_synch_interval=seconds;
224
225}
226
227
228void
229process_command_interest_retry(char *command)
230{
231 if(command==NULL)
232 {
233 printf(" Wrong Command Format ( interest-retry number )\n");
234 return;
235 }
236 char *rem;
237 const char *sep=" \t\n";
238 char *secs;
239 long int seconds;
240
241 secs=strtok_r(command,sep,&rem);
242 if(secs==NULL)
243 {
244 printf(" Wrong Command Format ( interest-retry number)\n");
245 return;
246 }
247
248 seconds=atoi(secs);
249 nlsr->interest_retry=seconds;
250
251}
252
253void
254process_command_interest_resend_time(char *command)
255{
256 if(command==NULL)
257 {
258 printf(" Wrong Command Format ( interest-resend-time secs )\n");
259 return;
260 }
261 char *rem;
262 const char *sep=" \t\n";
263 char *secs;
264 long int seconds;
265
266 secs=strtok_r(command,sep,&rem);
267 if(secs==NULL)
268 {
269 printf(" Wrong Command Format ( interest-resend-time secs)\n");
270 return;
271 }
272
273 seconds=atoi(secs);
274 nlsr->interest_resend_time=seconds;
275
276}
277
akmhoque03004e62012-09-06 01:12:28 -0500278
279
akmhoqued79438d2012-08-27 13:31:42 -0500280void
akmhoque59980a52012-08-09 12:36:09 -0500281process_conf_command(char *command)
282{
283 const char *separators=" \t\n";
284 char *remainder=NULL;
285 char *cmd_type=NULL;
286
287 if(command==NULL || strlen(command)==0 || command[0]=='!')
288 return;
289
290 cmd_type=strtok_r(command,separators,&remainder);
291
292 if(!strcmp(cmd_type,"router-name") )
293 {
294 process_command_router_name(remainder);
295 }
296 else if(!strcmp(cmd_type,"ccnneighbor") )
297 {
298 process_command_ccnneighbor(remainder);
299 }
300 else if(!strcmp(cmd_type,"ccnname") )
301 {
302 process_command_ccnname(remainder);
303 }
akmhoqued79438d2012-08-27 13:31:42 -0500304 else if(!strcmp(cmd_type,"lsdb-synch-interval") )
305 {
306 process_command_lsdb_synch_interval(remainder);
307 }
308 else if(!strcmp(cmd_type,"interest-retry") )
309 {
310 process_command_interest_retry(remainder);
311 }
312 else if(!strcmp(cmd_type,"interest-resend-time") )
313 {
314 process_command_interest_resend_time(remainder);
315 }
akmhoque59980a52012-08-09 12:36:09 -0500316 else
317 {
318 printf("Wrong configuration Command %s \n",cmd_type);
319 }
320}
321
akmhoque03004e62012-09-06 01:12:28 -0500322
akmhoque59980a52012-08-09 12:36:09 -0500323int
324readConfigFile(const char *filename)
325{
326 FILE *cfg;
327 char buf[1024];
328 int len;
329
330 cfg=fopen(filename, "r");
331
332 if(cfg == NULL)
333 {
334 printf("\nConfiguration File does not exists\n");
335 exit(1);
336 }
337
338 while(fgets((char *)buf, sizeof(buf), cfg))
339 {
340 len=strlen(buf);
341 if(buf[len-1] == '\n')
342 buf[len-1]='\0';
343 process_conf_command(buf);
344 }
345
346 fclose(cfg);
347
348 return 0;
349}
350
akmhoque386081b2012-08-10 10:53:21 -0500351void
352nlsr_destroy( void )
353{
354
akmhoque53f64222012-09-05 13:57:51 -0500355 printf("Freeing Allocated Memory....\n");
akmhoquefbfd0982012-09-09 20:59:03 -0500356 /* Destroying all face created by nlsr in CCND */
357 destroy_all_face_by_nlsr();
358
akmhoque386081b2012-08-10 10:53:21 -0500359 /* Destroying every hash table attached to each neighbor in ADL before destorying ADL */
akmhoque53f64222012-09-05 13:57:51 -0500360 hashtb_destroy(&nlsr->npl);
akmhoque03004e62012-09-06 01:12:28 -0500361 hashtb_destroy(&nlsr->adl);
362 hashtb_destroy(&nlsr->lsdb->name_lsdb);
363 hashtb_destroy(&nlsr->lsdb->adj_lsdb);
akmhoque29c1db52012-09-07 14:47:43 -0500364 hashtb_destroy(&nlsr->pit_alsa);
akmhoque3560cb62012-09-09 10:52:30 -0500365 hashtb_destroy(&nlsr->routing_table);
366
367
368 int i, npt_element;
369 struct npt_entry *ne;
370 struct hashtb_enumerator ee;
371 struct hashtb_enumerator *e = &ee;
372 hashtb_start(nlsr->npt, e);
373 npt_element=hashtb_n(nlsr->npt);
374 for(i=0;i<npt_element;i++)
375 {
376 ne=e->data;
akmhoque810a5b52012-09-09 16:53:14 -0500377 hashtb_destroy(&ne->name_list);
akmhoque3560cb62012-09-09 10:52:30 -0500378 hashtb_next(e);
379 }
380
381 hashtb_end(e);
382 hashtb_destroy(&nlsr->npt);
383
akmhoque03004e62012-09-06 01:12:28 -0500384
akmhoque386081b2012-08-10 10:53:21 -0500385 ccn_schedule_destroy(&nlsr->sched);
386 ccn_destroy(&nlsr->ccn);
akmhoque03004e62012-09-06 01:12:28 -0500387
388 free(nlsr->lsdb->lsdb_version);
389 free(nlsr->lsdb);
390 free(nlsr->router_name);
akmhoque386081b2012-08-10 10:53:21 -0500391 free(nlsr);
392
akmhoque53f64222012-09-05 13:57:51 -0500393 printf("Finished freeing allocated memory\n");
394
akmhoque386081b2012-08-10 10:53:21 -0500395}
396
akmhoque03004e62012-09-06 01:12:28 -0500397
akmhoque81c25e02012-09-10 14:50:33 -0500398int
akmhoque902d57e2012-08-17 09:24:38 -0500399init_nlsr(void)
akmhoque59980a52012-08-09 12:36:09 -0500400{
akmhoque03004e62012-09-06 01:12:28 -0500401 if (signal(SIGQUIT, nlsr_stop_signal_handler ) == SIG_ERR)
402 {
403 perror("SIGQUIT install error\n");
akmhoque81c25e02012-09-10 14:50:33 -0500404 return -1;
akmhoque03004e62012-09-06 01:12:28 -0500405 }
406 if (signal(SIGTERM, nlsr_stop_signal_handler ) == SIG_ERR)
407 {
408 perror("SIGTERM install error\n");
akmhoque81c25e02012-09-10 14:50:33 -0500409 return -1;
akmhoque03004e62012-09-06 01:12:28 -0500410 }
411 if (signal(SIGINT, nlsr_stop_signal_handler ) == SIG_ERR)
412 {
413 perror("SIGTERM install error\n");
akmhoque81c25e02012-09-10 14:50:33 -0500414 return -1;
akmhoque03004e62012-09-06 01:12:28 -0500415 }
akmhoque902d57e2012-08-17 09:24:38 -0500416
akmhoque59980a52012-08-09 12:36:09 -0500417 nlsr=(struct nlsr *)malloc(sizeof(struct nlsr));
akmhoque03004e62012-09-06 01:12:28 -0500418
419 struct hashtb_param param_adl = {0};
akmhoque28c45022012-08-09 15:38:02 -0500420 nlsr->adl=hashtb_create(sizeof(struct ndn_neighbor), &param_adl);
akmhoque03004e62012-09-06 01:12:28 -0500421 struct hashtb_param param_npl = {0};
422 nlsr->npl = hashtb_create(sizeof(struct name_prefix), &param_npl);
akmhoque29c1db52012-09-07 14:47:43 -0500423 struct hashtb_param param_pit_alsa = {0};
424 nlsr->pit_alsa = hashtb_create(sizeof(struct pneding_interest), &param_pit_alsa);
akmhoque3560cb62012-09-09 10:52:30 -0500425 struct hashtb_param param_npt = {0};
426 nlsr->npt = hashtb_create(sizeof(struct npt_entry), &param_npt);
427 struct hashtb_param param_rte = {0};
428 nlsr->routing_table = hashtb_create(sizeof(struct routing_table_entry), &param_rte);
akmhoque29c1db52012-09-07 14:47:43 -0500429
akmhoque59980a52012-08-09 12:36:09 -0500430 nlsr->in_interest.p = &incoming_interest;
431 nlsr->in_content.p = &incoming_content;
akmhoque07dd8cc2012-08-16 10:23:01 -0500432
akmhoque03004e62012-09-06 01:12:28 -0500433 nlsr->lsdb=(struct linkStateDatabase *)malloc(sizeof(struct linkStateDatabase));
akmhoque07dd8cc2012-08-16 10:23:01 -0500434
akmhoque03004e62012-09-06 01:12:28 -0500435 char *time_stamp=(char *)malloc(20);
436 memset(time_stamp,0,20);
437 get_current_timestamp_micro(time_stamp);
438 nlsr->lsdb->lsdb_version=(char *)malloc(strlen(time_stamp)+1);
439 memset(nlsr->lsdb->lsdb_version,'0',strlen(time_stamp));
440 free(time_stamp);
441
442 struct hashtb_param param_adj_lsdb = {0};
akmhoquef71d9082012-08-22 12:51:53 -0400443 nlsr->lsdb->adj_lsdb = hashtb_create(sizeof(struct alsa), &param_adj_lsdb);
akmhoque03004e62012-09-06 01:12:28 -0500444 struct hashtb_param param_name_lsdb = {0};
akmhoquef71d9082012-08-22 12:51:53 -0400445 nlsr->lsdb->name_lsdb = hashtb_create(sizeof(struct nlsa), &param_name_lsdb);
akmhoque29c1db52012-09-07 14:47:43 -0500446
447
akmhoque902d57e2012-08-17 09:24:38 -0500448
akmhoque53f64222012-09-05 13:57:51 -0500449
akmhoque59980a52012-08-09 12:36:09 -0500450 nlsr->is_synch_init=1;
akmhoquec9286692012-08-16 09:57:58 -0500451 nlsr->nlsa_id=0;
akmhoqued79438d2012-08-27 13:31:42 -0500452 nlsr->adj_build_flag=0;
akmhoque53f64222012-09-05 13:57:51 -0500453 nlsr->adj_build_count=0;
454 nlsr->is_build_adj_lsa_sheduled=0;
akmhoque29c1db52012-09-07 14:47:43 -0500455 nlsr->is_send_lsdb_interest_scheduled=0;
456 nlsr->is_route_calculation_scheduled=0;
akmhoqued79438d2012-08-27 13:31:42 -0500457
458 nlsr->lsdb_synch_interval = LSDB_SYNCH_INTERVAL;
459 nlsr->interest_retry = INTEREST_RETRY;
460 nlsr->interest_resend_time = INTEREST_RESEND_TIME;
akmhoque42098b12012-08-27 22:54:23 -0500461
462 nlsr->semaphor=0;
akmhoque81c25e02012-09-10 14:50:33 -0500463
464 return 0;
akmhoque902d57e2012-08-17 09:24:38 -0500465}
466
akmhoque03004e62012-09-06 01:12:28 -0500467
akmhoque902d57e2012-08-17 09:24:38 -0500468int
469main(int argc, char *argv[])
470{
akmhoque81c25e02012-09-10 14:50:33 -0500471 int res, ret;
akmhoque902d57e2012-08-17 09:24:38 -0500472 char *config_file;
akmhoque3560cb62012-09-09 10:52:30 -0500473 int daemon_mode;
akmhoque902d57e2012-08-17 09:24:38 -0500474
akmhoque81c25e02012-09-10 14:50:33 -0500475 ret=init_nlsr();
476 ON_ERROR_EXIT(ret);
477
akmhoque59980a52012-08-09 12:36:09 -0500478 while ((res = getopt_long(argc, argv, "df:h", longopts, 0)) != -1)
479 {
480 switch (res)
481 {
482 case 'd':
akmhoque3560cb62012-09-09 10:52:30 -0500483 daemon_mode = 1;
akmhoque59980a52012-08-09 12:36:09 -0500484 break;
485 case 'f':
486 config_file = optarg;
487 break;
488 case 'h':
489 default:
490 usage(argv[0]);
491 }
492 }
493
494 readConfigFile(config_file);
495
496 nlsr->ccn=ccn_create();
497 if(ccn_connect(nlsr->ccn, NULL) == -1)
akmhoque03004e62012-09-06 01:12:28 -0500498 {
499 fprintf(stderr,"Could not connect to ccnd\n");
akmhoque81c25e02012-09-10 14:50:33 -0500500 ON_ERROR_DESTROY(-1);
akmhoque03004e62012-09-06 01:12:28 -0500501 }
akmhoque53f64222012-09-05 13:57:51 -0500502 struct ccn_charbuf *router_prefix;
akmhoque03004e62012-09-06 01:12:28 -0500503 router_prefix=ccn_charbuf_create();
504 res=ccn_name_from_uri(router_prefix,nlsr->router_name);
akmhoque59980a52012-08-09 12:36:09 -0500505 if(res<0)
akmhoque03004e62012-09-06 01:12:28 -0500506 {
507 fprintf(stderr, "Bad ccn URI: %s\n",nlsr->router_name);
akmhoque81c25e02012-09-10 14:50:33 -0500508 ON_ERROR_DESTROY(res);
akmhoque03004e62012-09-06 01:12:28 -0500509 }
akmhoque59980a52012-08-09 12:36:09 -0500510
511 ccn_name_append_str(router_prefix,"nlsr");
akmhoque03004e62012-09-06 01:12:28 -0500512 nlsr->in_interest.data=nlsr->router_name;
akmhoque59980a52012-08-09 12:36:09 -0500513 res=ccn_set_interest_filter(nlsr->ccn,router_prefix,&nlsr->in_interest);
514 if ( res < 0 )
akmhoque03004e62012-09-06 01:12:28 -0500515 {
516 fprintf(stderr,"Failed to register interest for router\n");
akmhoque81c25e02012-09-10 14:50:33 -0500517 ON_ERROR_DESTROY(res);
akmhoque03004e62012-09-06 01:12:28 -0500518 }
519 ccn_charbuf_destroy(&router_prefix);
520
521 printf("Router Name : %s\n",nlsr->router_name);
522 printf("lsdb_version: %s\n",nlsr->lsdb->lsdb_version);
akmhoque59980a52012-08-09 12:36:09 -0500523
akmhoque53f64222012-09-05 13:57:51 -0500524 print_name_prefix_from_npl();
525 print_adjacent_from_adl();
akmhoque53f64222012-09-05 13:57:51 -0500526 build_and_install_name_lsas();
527 print_name_lsdb();
528
529 nlsr->sched = ccn_schedule_create(nlsr, &ndn_rtr_ticker);
akmhoque03004e62012-09-06 01:12:28 -0500530 nlsr->event_send_info_interest = ccn_schedule_event(nlsr->sched, 1, &send_info_interest, NULL, 0);
akmhoque1c9b92f2012-08-13 10:57:50 -0500531
akmhoque59980a52012-08-09 12:36:09 -0500532 while(1)
akmhoque29c1db52012-09-07 14:47:43 -0500533 {
534 if( nlsr->sched != NULL )
535 {
Obaid Amin485277a2012-09-07 01:08:28 -0400536 ccn_schedule_run(nlsr->sched);
akmhoque29c1db52012-09-07 14:47:43 -0500537 }
538 if(nlsr->ccn != NULL)
539 {
540 res = ccn_run(nlsr->ccn, 500);
541 }
Obaid Amin485277a2012-09-07 01:08:28 -0400542 if (!(nlsr->sched && nlsr->ccn))
akmhoque29c1db52012-09-07 14:47:43 -0500543 {
544 break;
545 }
546
akmhoque59980a52012-08-09 12:36:09 -0500547 }
akmhoque59980a52012-08-09 12:36:09 -0500548
akmhoque59980a52012-08-09 12:36:09 -0500549 return 0;
550}
551