07e70aee64
git-svn-id: svn://svn.openwrt.org/openwrt/packages@6273 3c298f89-4303-0410-b956-a3cf2f4a3e73
1288 lines
41 KiB
Diff
1288 lines
41 KiB
Diff
diff -Nur olsrd-0.4.10.orig/lib/nameservice/src/nameservice.c olsrd-0.4.10/lib/nameservice/src/nameservice.c
|
|
--- olsrd-0.4.10.orig/lib/nameservice/src/nameservice.c 2005-05-29 14:47:42.000000000 +0200
|
|
+++ olsrd-0.4.10/lib/nameservice/src/nameservice.c 2006-12-01 08:26:58.000000000 +0100
|
|
@@ -1,4 +1,5 @@
|
|
/*
|
|
+ * Copyright (c) 2006, Jens Nachtigall <nachtigall@web.de>
|
|
* Copyright (c) 2005, Bruno Randolf <bruno.randolf@4g-systems.biz>
|
|
* Copyright (c) 2004, Andreas Tønnesen(andreto-at-olsr.org)
|
|
* All rights reserved.
|
|
@@ -39,6 +40,9 @@
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
+#include <ctype.h>
|
|
+#include <sys/types.h>
|
|
+#include <regex.h>
|
|
|
|
#include "olsr.h"
|
|
#include "net_olsr.h"
|
|
@@ -53,6 +57,7 @@
|
|
#include "olsrd_copy.h"
|
|
#include "compat.h"
|
|
|
|
+
|
|
/* send buffer: huge */
|
|
static char buffer[10240];
|
|
|
|
@@ -62,15 +67,35 @@
|
|
static char my_suffix[MAX_SUFFIX];
|
|
static int my_interval = EMISSION_INTERVAL;
|
|
static double my_timeout = NAME_VALID_TIME;
|
|
-static olsr_bool have_dns_server = OLSR_FALSE;
|
|
-static union olsr_ip_addr my_dns_server;
|
|
static char my_resolv_file[MAX_FILE +1];
|
|
+static char my_services_file[MAX_FILE + 1];
|
|
|
|
-/* the database (using hashing) */
|
|
+/* the databases (using hashing)
|
|
+ * for hostnames, service_lines and dns-servers
|
|
+ *
|
|
+ * my own hostnames, service_lines and dns-servers
|
|
+ * are store in a linked list (without hashing)
|
|
+ * */
|
|
struct db_entry* list[HASHSIZE];
|
|
struct name_entry *my_names = NULL;
|
|
olsr_bool name_table_changed = OLSR_TRUE;
|
|
|
|
+struct db_entry* service_list[HASHSIZE];
|
|
+struct name_entry *my_services = NULL;
|
|
+olsr_bool service_table_changed = OLSR_TRUE;
|
|
+
|
|
+struct db_entry* forwarder_list[HASHSIZE];
|
|
+struct name_entry *my_forwarders = NULL;
|
|
+olsr_bool forwarder_table_changed = OLSR_TRUE;
|
|
+
|
|
+/* regualar expression to be matched by valid hostnames, compiled in name_init() */
|
|
+regex_t regex_t_name;
|
|
+regmatch_t regmatch_t_name;
|
|
+
|
|
+/* regualar expression to be matched by valid service_lines, compiled in name_init() */
|
|
+regex_t regex_t_service;
|
|
+int pmatch_service = 10;
|
|
+regmatch_t regmatch_t_service[10];
|
|
|
|
/**
|
|
* do initialization
|
|
@@ -84,27 +109,39 @@
|
|
int len;
|
|
|
|
GetWindowsDirectory(my_hosts_file, MAX_FILE - 12);
|
|
+ GetWindowsDirectory(my_services_file, MAX_FILE - 12);
|
|
|
|
len = strlen(my_hosts_file);
|
|
-
|
|
if (my_hosts_file[len - 1] != '\\')
|
|
my_hosts_file[len++] = '\\';
|
|
-
|
|
strcpy(my_hosts_file + len, "hosts_olsr");
|
|
+
|
|
+ len = strlen(my_services_file);
|
|
+ if (my_services_file[len - 1] != '\\')
|
|
+ my_services_file[len++] = '\\';
|
|
+ strcpy(my_services_file + len, "services_olsr");
|
|
+
|
|
+ len = strlen(my_resolv_file);
|
|
+ if (my_resolv_file[len - 1] != '\\')
|
|
+ my_resolv_file[len++] = '\\';
|
|
+ strcpy(my_resolv_file + len, "resolvconf_olsr");
|
|
#else
|
|
strcpy(my_hosts_file, "/var/run/hosts_olsr");
|
|
+ strcpy(my_services_file, "/var/run/services_olsr");
|
|
+ strcpy(my_resolv_file, "/var/run/resolvconf_olsr");
|
|
#endif
|
|
|
|
my_suffix[0] = '\0';
|
|
my_add_hosts[0] = '\0';
|
|
- my_resolv_file[0] = '\0';
|
|
|
|
- /* init list */
|
|
+ /* init lists */
|
|
for(i = 0; i < HASHSIZE; i++) {
|
|
list[i] = NULL;
|
|
+ forwarder_list[i] = NULL;
|
|
+ service_list[i] = NULL;
|
|
}
|
|
|
|
- memset(&my_dns_server, 0, sizeof(my_dns_server));
|
|
+
|
|
}
|
|
|
|
|
|
@@ -116,56 +153,53 @@
|
|
{
|
|
if(!strcmp(key, "interval")) {
|
|
my_interval = atoi(value);
|
|
- printf("\nNAME PLUGIN: parameter interval: %d\n", my_interval);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter interval: %d", my_interval);
|
|
}
|
|
else if(!strcmp(key, "timeout")) {
|
|
my_timeout = atof(value);
|
|
- printf("\nNAME PLUGIN: parameter timeout: %f\n", my_timeout);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter timeout: %f", my_timeout);
|
|
}
|
|
else if(!strcmp(key, "hosts-file")) {
|
|
strncpy( my_hosts_file, value, MAX_FILE );
|
|
- printf("\nNAME PLUGIN: parameter filename: %s\n", my_hosts_file);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter filename: %s", my_hosts_file);
|
|
}
|
|
else if(!strcmp(key, "resolv-file")) {
|
|
strncpy(my_resolv_file, value, MAX_FILE);
|
|
- printf("\nNAME PLUGIN: parameter resolv file: %s\n", my_resolv_file);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter resolv-file: %s", my_resolv_file);
|
|
}
|
|
else if(!strcmp(key, "suffix")) {
|
|
strncpy(my_suffix, value, MAX_SUFFIX);
|
|
- printf("\nNAME PLUGIN: parameter suffix: %s\n", my_suffix);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter suffix: %s", my_suffix);
|
|
}
|
|
else if(!strcmp(key, "add-hosts")) {
|
|
strncpy(my_add_hosts, value, MAX_FILE);
|
|
- printf("\nNAME PLUGIN: parameter additional host: %s\n", my_add_hosts);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter additional host: %s", my_add_hosts);
|
|
+ }
|
|
+ else if(!strcmp(key, "services-file")) {
|
|
+ strncpy(my_services_file, value, MAX_FILE);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter services-file: %s", my_services_file);
|
|
}
|
|
else if(!strcmp(key, "dns-server")) {
|
|
struct in_addr ip;
|
|
if (strlen(value) == 0) {
|
|
- // set dns server ip to main address
|
|
- // which is not known yet
|
|
- have_dns_server = OLSR_TRUE;
|
|
- }
|
|
- else if (inet_aton(value, &ip)) {
|
|
- my_dns_server.v4 = ip.s_addr;
|
|
- have_dns_server = OLSR_TRUE;
|
|
- }
|
|
- else {
|
|
- printf("\nNAME PLUGIN: invalid dns-server IP %s\n", value);
|
|
- }
|
|
+ my_forwarders = add_name_to_list(my_forwarders, "", NAME_FORWARDER, NULL);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter dns-server: (main address)");
|
|
+ } else if (inet_aton(value, &ip)) {
|
|
+ my_forwarders = add_name_to_list(my_forwarders, "", NAME_FORWARDER, &ip);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter dns-server: (%s)", value);
|
|
+ } else {
|
|
+ olsr_printf(1,"\nNAME PLUGIN: invalid parameter dns-server: %s ", value);
|
|
+ }
|
|
}
|
|
else if(!strcmp(key, "name")) {
|
|
// name for main address
|
|
- struct name_entry *tmp;
|
|
- tmp = malloc(sizeof(struct name_entry));
|
|
- tmp->name = strndup( value, MAX_NAME );
|
|
- tmp->len = strlen( tmp->name );
|
|
- tmp->type = NAME_HOST;
|
|
- // will be set to main_addr later
|
|
- memset(&tmp->ip, 0, sizeof(tmp->ip));
|
|
- tmp->next = my_names;
|
|
- my_names = tmp;
|
|
-
|
|
- printf("\nNAME PLUGIN: parameter name: %s (main address)\n", tmp->name);
|
|
+ my_names = add_name_to_list(my_names, value, NAME_HOST, NULL);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter name: %s (main address)", value);
|
|
+ }
|
|
+ else if(!strcmp(key, "service")) {
|
|
+ // name for main address
|
|
+ my_services = add_name_to_list(my_services, value, NAME_SERVICE, NULL);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter service: %s (main address)", value);
|
|
}
|
|
else {
|
|
// assume this is an IP address and hostname
|
|
@@ -173,33 +207,46 @@
|
|
|
|
if (inet_aton(key, &ip)) {
|
|
// the IP is validated later
|
|
- struct name_entry *tmp;
|
|
- tmp = malloc(sizeof(struct name_entry));
|
|
- tmp->name = strndup( value, MAX_NAME );
|
|
- tmp->len = strlen( tmp->name );
|
|
- tmp->type = NAME_HOST;
|
|
- tmp->ip.v4 = ip.s_addr;
|
|
- tmp->next = my_names;
|
|
- my_names = tmp;
|
|
- printf("\nNAME PLUGIN: parameter %s (%s)\n", tmp->name,
|
|
- olsr_ip_to_string(&tmp->ip));
|
|
+ my_names = add_name_to_list(my_names, value, NAME_HOST, &ip);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: parameter name %s (%s)", value, key);
|
|
}
|
|
else {
|
|
- printf("\nNAME PLUGIN: invalid IP %s for name %s!\n", key, value);
|
|
+ olsr_printf(1,"\nNAME PLUGIN: invalid parameter name: %s (%s)!", value, key);
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
+/**
|
|
+ * queue the name/forwarder/service given in value
|
|
+ * to the front of my_list
|
|
+ */
|
|
+struct name_entry*
|
|
+add_name_to_list(struct name_entry *my_list, char *value, int type, struct in_addr *ip)
|
|
+{
|
|
+ struct name_entry *tmp;
|
|
+ tmp = olsr_malloc(sizeof(struct name_entry), "new name_entry add_name_to_list");
|
|
+ tmp->name = strndup( value, MAX_NAME );
|
|
+ tmp->len = strlen( tmp->name );
|
|
+ tmp->type = type;
|
|
+ // all IPs with value 0 will be set to main_addr later
|
|
+ if (ip==NULL)
|
|
+ memset(&tmp->ip, 0, sizeof(tmp->ip));
|
|
+ else
|
|
+ tmp->ip.v4 = ip->s_addr;
|
|
+ tmp->next = my_list;
|
|
+ return tmp;
|
|
+}
|
|
+
|
|
|
|
/**
|
|
* last initialization
|
|
*
|
|
* we have to do this here because some things like main_addr
|
|
- * are not known before
|
|
+ * or the dns suffix (for validation) are not known before
|
|
*
|
|
- * this is beause of the order in which the plugin is initzalized
|
|
+ * this is beause of the order in which the plugin is initialized
|
|
* by the plugin loader:
|
|
* - first the parameters are sent
|
|
* - then register_olsr_data() from olsrd_plugin.c is called
|
|
@@ -210,50 +257,78 @@
|
|
name_init()
|
|
{
|
|
struct name_entry *name;
|
|
- struct name_entry *prev=NULL;
|
|
-
|
|
- /* fixup names and IP addresses */
|
|
+ int ret;
|
|
+ //regex string for validating the hostnames
|
|
+ char *regex_name = "^[[:alnum:]_.-]+$";
|
|
+ //regex string for the service line
|
|
+ char *regex_service = olsr_malloc(256*sizeof(char) + strlen(my_suffix), "new *char from name_init for regex_service");
|
|
+
|
|
+ //compile the regex from the string
|
|
+ if ((ret = regcomp(®ex_t_name, regex_name , REG_EXTENDED)) != 0)
|
|
+ {
|
|
+ /* #2: call regerror() if regcomp failed
|
|
+ * commented out, because only for debuggin needed
|
|
+ *
|
|
+ int errmsgsz = regerror(ret, ®ex_t_name, NULL, 0);
|
|
+ char *errmsg = malloc(errmsgsz);
|
|
+ regerror(ret, ®ex_t_name, errmsg, errmsgsz);
|
|
+ fprintf(stderr, "regcomp: %s", errmsg);
|
|
+ free(errmsg);
|
|
+ regfree(®ex_t_name);
|
|
+ * */
|
|
+ olsr_printf(0, "compilation of regex \"%s\" for hostname failed", regex_name);
|
|
+ }
|
|
+
|
|
+ // a service line is something like prot://hostname.suffix:port|tcp|my little description about this service
|
|
+ // for example http://router.olsr:80|tcp|my homepage
|
|
+ // prot :// (hostname.suffix OR ip)
|
|
+ //regex_service = "^[[:alnum:]]+://(([[:alnum:]_.-]+.olsr)|([[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}))
|
|
+ // : port /path |(tcp OR udp) |short description
|
|
+ // :[[:digit:]]+[[:alnum:]/?._=#-]*\\|(tcp|udp)\\|[^|[:cntrl:]]+$";
|
|
+ strcat (strcat (strcat(regex_service, "^[[:alnum:]]+://(([[:alnum:]_.-]+"),
|
|
+ my_suffix),
|
|
+ ")|([[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.[[:digit:]]{1,3})):[[:digit:]]+[[:alnum:]/?._=#-]*\\|(tcp|udp)\\|[^|[:cntrl:]]+$");
|
|
+
|
|
+ /* #1: call regcomp() to compile the regex */
|
|
+ if ((ret = regcomp(®ex_t_service, regex_service , REG_EXTENDED )) != 0)
|
|
+ {
|
|
+ /* #2: call regerror() if regcomp failed
|
|
+ * commented out, because only for debuggin needed
|
|
+ *
|
|
+ int errmsgsz = regerror(ret, ®ex_t_service, NULL, 0);
|
|
+ char *errmsg = malloc(errmsgsz);
|
|
+ regerror(ret, ®ex_t_service, errmsg, errmsgsz);
|
|
+ fprintf(stderr, "regcomp: %s", errmsg);
|
|
+ free(errmsg);
|
|
+ regfree(®ex_t_service);
|
|
+ * */
|
|
+ olsr_printf(0, "compilation of regex \"%s\" for hostname failed", regex_name);
|
|
+ }
|
|
+ free(regex_service);
|
|
+ regex_service = NULL;
|
|
+
|
|
+ //fill in main addr for all entries with ip==0
|
|
+ //this does not matter for service, because the ip does not matter
|
|
+ //for service
|
|
for (name = my_names; name != NULL; name = name->next) {
|
|
- if (name->ip.v4 == 0) {
|
|
- // insert main_addr
|
|
+ if (name->ip.v4 == 0) {
|
|
+ olsr_printf(2, "NAME PLUGIN: insert main addr for name %s \n", name->name);
|
|
memcpy(&name->ip, &main_addr, ipsize);
|
|
- prev = name;
|
|
- } else {
|
|
- // IP from config file
|
|
- // check if we are allowed to announce a name for this IP
|
|
- // we can only do this if we also announce the IP
|
|
- if (!allowed_ip(&name->ip)) {
|
|
- olsr_printf(1, "NAME PLUGIN: name for unknown IP %s not allowed, fix your config!\n",
|
|
- olsr_ip_to_string(&name->ip));
|
|
- if (prev!=NULL) {
|
|
- prev->next = name->next;
|
|
- free(name->name);
|
|
- free(name);
|
|
- }
|
|
- }
|
|
- else {
|
|
- prev = name;
|
|
- }
|
|
- }
|
|
- }
|
|
+ }
|
|
+ }
|
|
+ for (name = my_forwarders; name != NULL; name = name->next) {
|
|
+ if (name->ip.v4 == 0) {
|
|
+ olsr_printf(2, "NAME PLUGIN: insert main addr for name %s \n", name->name);
|
|
+ memcpy(&name->ip, &main_addr, ipsize);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ //check if entries I want to announce myself are valid and allowed
|
|
+ my_names = remove_nonvalid_names_from_list(my_names, NAME_HOST);
|
|
+ my_forwarders = remove_nonvalid_names_from_list(my_forwarders, NAME_FORWARDER);
|
|
+ my_services = remove_nonvalid_names_from_list(my_services, NAME_SERVICE);
|
|
+
|
|
|
|
- if (have_dns_server) {
|
|
- if (my_dns_server.v4 == 0) {
|
|
- memcpy(&my_dns_server, &main_addr, ipsize);
|
|
- printf("\nNAME PLUGIN: announcing upstream DNS server: %s\n",
|
|
- olsr_ip_to_string(&my_dns_server));
|
|
- }
|
|
- else if (!allowed_ip(&my_dns_server)) {
|
|
- printf("NAME PLUGIN: announcing DNS server on unknown IP %s is not allowed, fix your config!\n",
|
|
- olsr_ip_to_string(&my_dns_server));
|
|
- memset(&my_dns_server, 0, sizeof(my_dns_server));
|
|
- have_dns_server = OLSR_FALSE;
|
|
- }
|
|
- else {
|
|
- printf("\nNAME PLUGIN: announcing upstream DNS server: %s\n",
|
|
- olsr_ip_to_string(&my_dns_server));
|
|
- }
|
|
- }
|
|
|
|
/* register functions with olsrd */
|
|
olsr_parser_add_function(&olsr_parser, PARSER_TYPE, 1);
|
|
@@ -263,22 +338,75 @@
|
|
return 1;
|
|
}
|
|
|
|
+struct name_entry*
|
|
+remove_nonvalid_names_from_list(struct name_entry *my_list, int type)
|
|
+{
|
|
+ struct name_entry *next = my_list;
|
|
+ olsr_bool valid = OLSR_FALSE;
|
|
+ if (my_list == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ switch (type) {
|
|
+ case NAME_HOST:
|
|
+ valid = is_name_wellformed(my_list->name) && allowed_ip(&my_list->ip);
|
|
+ break;
|
|
+ case NAME_FORWARDER:
|
|
+ valid = allowed_ip(&my_list->ip);
|
|
+ break;
|
|
+ case NAME_SERVICE:
|
|
+ valid = allowed_service(my_list->name);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if ( !valid ) {
|
|
+ olsr_printf(1, "NAME PLUGIN: invalid or malformed parameter %s (%s), fix your config!\n", my_list->name, olsr_ip_to_string(&my_list->ip));
|
|
+ next = my_list->next;
|
|
+ free(my_list->name);
|
|
+ my_list->name = NULL;
|
|
+ free(my_list);
|
|
+ my_list = NULL;
|
|
+ return remove_nonvalid_names_from_list(next, type);
|
|
+ } else {
|
|
+ olsr_printf(2, "NAME PLUGIN: validate parameter %s (%s) -> OK\n", my_list->name, olsr_ip_to_string(&my_list->ip));
|
|
+ my_list->next = remove_nonvalid_names_from_list(my_list->next, type);
|
|
+ return my_list;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
|
|
/**
|
|
* called at unload: free everything
|
|
+ *
|
|
+ * XXX: should I delete the hosts/services/resolv.conf files on exit?
|
|
*/
|
|
void
|
|
name_destructor()
|
|
{
|
|
- int i;
|
|
- struct db_entry **tmp;
|
|
- struct db_entry *to_delete;
|
|
-
|
|
olsr_printf(2, "NAME PLUGIN: exit. cleaning up...\n");
|
|
|
|
free_name_entry_list(&my_names);
|
|
+ free_name_entry_list(&my_services);
|
|
+ free_name_entry_list(&my_forwarders);
|
|
+
|
|
+ free_all_list_entries(list);
|
|
+ free_all_list_entries(service_list);
|
|
+ free_all_list_entries(forwarder_list);
|
|
+
|
|
+ regfree(®ex_t_name);
|
|
+ regfree(®ex_t_service);
|
|
+
|
|
+}
|
|
+
|
|
+/* free all list entries */
|
|
+void
|
|
+free_all_list_entries(struct db_entry **this_db_list)
|
|
+{
|
|
+ int i;
|
|
+ struct db_entry **tmp;
|
|
+ struct db_entry *to_delete;
|
|
|
|
- /* free list entries */
|
|
for(i = 0; i < HASHSIZE; i++)
|
|
{
|
|
tmp = &list[i];
|
|
@@ -296,24 +424,41 @@
|
|
|
|
/**
|
|
* A timeout function called every time
|
|
- * the scheduler is polled: time out old list entries
|
|
+ *
|
|
+ * XXX:the scheduler is polled (by default 10 times a sec,
|
|
+ * which is far too often):
|
|
+ *
|
|
+ * time out old list entries
|
|
* and write changes to file
|
|
*/
|
|
void
|
|
olsr_timeout()
|
|
{
|
|
+ timeout_old_names(list, &name_table_changed);
|
|
+ timeout_old_names(forwarder_list, &forwarder_table_changed);
|
|
+ timeout_old_names(service_list, &service_table_changed);
|
|
+
|
|
+ write_resolv_file();
|
|
+ write_hosts_file();
|
|
+ write_services_file();
|
|
+}
|
|
+
|
|
+void
|
|
+timeout_old_names(struct db_entry **this_list, olsr_bool *this_table_changed)
|
|
+{
|
|
struct db_entry **tmp;
|
|
struct db_entry *to_delete;
|
|
int index;
|
|
|
|
for(index=0;index<HASHSIZE;index++)
|
|
{
|
|
- for (tmp = &list[index]; *tmp != NULL; )
|
|
+ for (tmp = &this_list[index]; *tmp != NULL; )
|
|
{
|
|
- /* check if the entry is timed out */
|
|
+ /* check if the entry for this ip is timed out */
|
|
if (olsr_timed_out(&(*tmp)->timer))
|
|
{
|
|
to_delete = *tmp;
|
|
+ /* update the pointer in the linked list */
|
|
*tmp = (*tmp)->next;
|
|
|
|
olsr_printf(2, "NAME PLUGIN: %s timed out... deleting\n",
|
|
@@ -322,17 +467,17 @@
|
|
/* Delete */
|
|
free_name_entry_list(&to_delete->names);
|
|
free(to_delete);
|
|
- name_table_changed = OLSR_TRUE;
|
|
+ *this_table_changed = OLSR_TRUE;
|
|
} else {
|
|
tmp = &(*tmp)->next;
|
|
}
|
|
}
|
|
}
|
|
- write_resolv_file();
|
|
- write_hosts_file();
|
|
}
|
|
|
|
|
|
+
|
|
+
|
|
/**
|
|
* Scheduled event: generate and send NAME packet
|
|
*/
|
|
@@ -429,21 +574,19 @@
|
|
return;
|
|
}
|
|
|
|
- /* Check if this message has been processed before
|
|
- * Remeber that this also registeres the message as
|
|
+ /* Check if this message has not been processed before
|
|
+ * Remember that this also registers the message as
|
|
* processed if nessecary
|
|
*/
|
|
- if(!olsr_check_dup_table_proc(&originator, ntohs(m->v4.seqno))) {
|
|
- /* If so - do not process */
|
|
- goto forward;
|
|
- }
|
|
-
|
|
- update_name_entry(&originator, namemessage, size, vtime);
|
|
+ if(olsr_check_dup_table_proc(&originator, ntohs(m->v4.seqno))) {
|
|
+ /* If not already processed - do so */
|
|
+ update_name_entry(&originator, namemessage, size, vtime);
|
|
+ }
|
|
+
|
|
+ /* Forward the message if nessecary
|
|
+ * default_fwd does all the work for us! */
|
|
+ olsr_forward_message(m, &originator, ntohs(m->v4.seqno), in_if, in_addr);
|
|
|
|
-forward:
|
|
- /* Forward the message if nessecary
|
|
- * default_fwd does all the work for us! */
|
|
- olsr_forward_message(m, &originator, ntohs(m->v4.seqno), in_if, in_addr);
|
|
}
|
|
|
|
|
|
@@ -457,152 +600,224 @@
|
|
int
|
|
encap_namemsg(struct namemsg* msg)
|
|
{
|
|
- struct name_entry *my_name = my_names;
|
|
- struct name* to_packet;
|
|
+ struct name_entry *my_name;
|
|
+ struct name_entry *my_service;
|
|
+
|
|
+ // add the hostname, service and forwarder entries after the namemsg header
|
|
char* pos = (char*)msg + sizeof(struct namemsg);
|
|
short i=0;
|
|
- int k;
|
|
-
|
|
- // upstream dns server
|
|
- if (have_dns_server) {
|
|
- olsr_printf(3, "NAME PLUGIN: Announcing DNS server (%s)\n",
|
|
- olsr_ip_to_string(&my_dns_server));
|
|
- to_packet = (struct name*)pos;
|
|
- to_packet->type = htons(NAME_FORWARDER);
|
|
- to_packet->len = htons(0);
|
|
- memcpy(&to_packet->ip, &my_dns_server, ipsize);
|
|
- pos += sizeof(struct name);
|
|
- i++;
|
|
- }
|
|
+
|
|
|
|
// names
|
|
for (my_name = my_names; my_name!=NULL; my_name = my_name->next)
|
|
{
|
|
- olsr_printf(3, "NAME PLUGIN: Announcing name %s (%s) %d\n",
|
|
- my_name->name, olsr_ip_to_string(&my_name->ip), my_name->len);
|
|
-
|
|
- to_packet = (struct name*)pos;
|
|
- to_packet->type = htons(my_name->type);
|
|
- to_packet->len = htons(my_name->len);
|
|
- memcpy(&to_packet->ip, &my_name->ip, ipsize);
|
|
- pos += sizeof(struct name);
|
|
- strncpy(pos, my_name->name, my_name->len);
|
|
- pos += my_name->len;
|
|
- // padding to 4 byte boundaries
|
|
- for (k = my_name->len; (k & 3) != 0; k++)
|
|
- *pos++ = '\0';
|
|
+ pos = create_packet( (struct name*) pos, my_name);
|
|
i++;
|
|
}
|
|
+ // forwarders
|
|
+ for (my_name = my_forwarders; my_name!=NULL; my_name = my_name->next)
|
|
+ {
|
|
+ pos = create_packet( (struct name*) pos, my_name);
|
|
+ i++;
|
|
+ }
|
|
+ // services
|
|
+ for (my_service = my_services; my_service!=NULL; my_service = my_service->next)
|
|
+ {
|
|
+ pos = create_packet( (struct name*) pos, my_service);
|
|
+ i++;
|
|
+ }
|
|
+
|
|
+ // write the namemsg header with the number of announced entries and the protocol version
|
|
msg->nr_names = htons(i);
|
|
msg->version = htons(NAME_PROTOCOL_VERSION);
|
|
+
|
|
return pos - (char*)msg; //length
|
|
}
|
|
|
|
|
|
/**
|
|
- * decapsulate a name message and update name_entries if necessary
|
|
+ * convert each of my to be announced name_entries into network
|
|
+ * compatible format
|
|
+ *
|
|
+ * return the length of the name packet
|
|
+ */
|
|
+char*
|
|
+create_packet(struct name* to, struct name_entry *from)
|
|
+{
|
|
+ char *pos = (char*) to;
|
|
+ int k;
|
|
+ olsr_printf(3, "NAME PLUGIN: Announcing name %s (%s) %d\n",
|
|
+ from->name, olsr_ip_to_string(&from->ip), from->len);
|
|
+ to->type = htons(from->type);
|
|
+ to->len = htons(from->len);
|
|
+ memcpy(&to->ip, &from->ip, ipsize);
|
|
+ pos += sizeof(struct name);
|
|
+ strncpy(pos, from->name, from->len);
|
|
+ pos += from->len;
|
|
+ for (k = from->len; (k & 3) != 0; k++)
|
|
+ *pos++ = '\0';
|
|
+ return pos;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * decapsulate a received name, service or forwarder and update the corresponding hash table if necessary
|
|
+ */
|
|
+void
|
|
+decap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_table_changed )
|
|
+{
|
|
+ struct name_entry *tmp;
|
|
+ struct name_entry *already_saved_name_entries;
|
|
+ char *name = (char*)from_packet + sizeof(struct name);
|
|
+ olsr_printf(4, "\nNAME PLUGIN: decapsulating received name, service or forwarder \n");
|
|
+ int type_of_from_packet = ntohs(from_packet->type);
|
|
+ unsigned int len_of_name = ntohs(from_packet->len);
|
|
+
|
|
+ // don't insert the received entry again, if it has already been inserted in the hash table.
|
|
+ // Instead only the validity time is set in insert_new_name_in_list function, which calls this one
|
|
+ for (already_saved_name_entries = (*to); already_saved_name_entries != NULL ; already_saved_name_entries = already_saved_name_entries->next)
|
|
+ {
|
|
+ if ( (type_of_from_packet==NAME_HOST || type_of_from_packet==NAME_SERVICE) && strncmp(already_saved_name_entries->name, name, len_of_name) == 0 ) {
|
|
+ olsr_printf(4, "\nNAME PLUGIN: received name or service entry %s (%s) already in hash table\n", name, olsr_ip_to_string(&already_saved_name_entries->ip));
|
|
+ return;
|
|
+ } else if (type_of_from_packet==NAME_FORWARDER && COMP_IP(&already_saved_name_entries->ip, &from_packet->ip) ) {
|
|
+ olsr_printf(4, "\nNAME PLUGIN: received forwarder entry %s (%s) already in hash table\n", name, olsr_ip_to_string(&already_saved_name_entries->ip));
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ //XXX: should I check the from_packet->ip here? If so, why not also check the ip fro HOST and SERVICE?
|
|
+ if( (type_of_from_packet==NAME_HOST && !is_name_wellformed(name)) || (type_of_from_packet==NAME_SERVICE && !is_service_wellformed(name)) ) {
|
|
+ olsr_printf(4, "\nNAME PLUGIN: invalid name [%s] received, skipping.\n", name );
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ //ignore all packets with a too long name
|
|
+ //or a spoofed len of its included name string
|
|
+ if (len_of_name > MAX_NAME || strlen(name) != len_of_name) {
|
|
+ olsr_printf(4, "\nNAME PLUGIN: from_packet->len %d > MAX_NAME %d or from_packet->len %d !0 strlen(name [%s] in packet)\n",
|
|
+ len_of_name, MAX_NAME, len_of_name, name );
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ //if not yet known entry
|
|
+ tmp = olsr_malloc(sizeof(struct name_entry), "new name_entry");
|
|
+ tmp->type = ntohs(from_packet->type);
|
|
+ tmp->len = len_of_name > MAX_NAME ? MAX_NAME : ntohs(from_packet->len);
|
|
+ tmp->name = olsr_malloc(tmp->len+1, "new name_entry name");
|
|
+ memcpy(&tmp->ip, &from_packet->ip, ipsize);
|
|
+ strncpy(tmp->name, name, tmp->len);
|
|
+ tmp->name[tmp->len] = '\0';
|
|
+
|
|
+ olsr_printf(3, "\nNAME PLUGIN: create new name/service/forwarder entry %s (%s) [len=%d] [type=%d] in linked list\n",
|
|
+ tmp->name, olsr_ip_to_string(&tmp->ip), tmp->len, tmp->type);
|
|
+
|
|
+ *this_table_changed = OLSR_TRUE;
|
|
+
|
|
+ // queue to front
|
|
+ tmp->next = *to;
|
|
+ *to = tmp;
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * unpack the received message and delegate to the decapsilation function for each
|
|
+ * name/service/forwarder entry in the message
|
|
*/
|
|
void
|
|
-decap_namemsg( struct namemsg *msg, int size, struct name_entry **to )
|
|
+update_name_entry(union olsr_ip_addr *originator, struct namemsg *msg, int msg_size, double vtime)
|
|
{
|
|
char *pos, *end_pos;
|
|
- struct name_entry *tmp;
|
|
struct name *from_packet;
|
|
int i;
|
|
+
|
|
+ olsr_printf(3, "NAME PLUGIN: Received Message from %s\n",
|
|
+ olsr_ip_to_string(originator));
|
|
|
|
- olsr_printf(4, "NAME PLUGIN: decapsulating name msg (size %d)\n", size);
|
|
-
|
|
- if (ntohs(msg->version) != NAME_PROTOCOL_VERSION) {
|
|
+ if (ntohs(msg->version) != NAME_PROTOCOL_VERSION) {
|
|
olsr_printf(3, "NAME PLUGIN: ignoring wrong version %d\n", msg->version);
|
|
return;
|
|
}
|
|
-
|
|
- // for now ist easier to just delete everything, than
|
|
- // to update selectively
|
|
- free_name_entry_list(to);
|
|
- name_table_changed = OLSR_TRUE;
|
|
-
|
|
+
|
|
+
|
|
/* now add the names from the message */
|
|
pos = (char*)msg + sizeof(struct namemsg);
|
|
- end_pos = pos + size - sizeof(struct name*); // at least one struct name has to be left
|
|
-
|
|
+ end_pos = pos + msg_size - sizeof(struct name*); // at least one struct name has to be left
|
|
+
|
|
for (i=ntohs(msg->nr_names); i > 0 && pos<end_pos; i--)
|
|
{
|
|
from_packet = (struct name*)pos;
|
|
-
|
|
- tmp = olsr_malloc(sizeof(struct name_entry), "new name_entry");
|
|
- tmp->type = ntohs(from_packet->type);
|
|
- tmp->len = ntohs(from_packet->len) > MAX_NAME ? MAX_NAME : ntohs(from_packet->len);
|
|
- tmp->name = olsr_malloc(tmp->len+1, "new name_entry name");
|
|
- memcpy(&tmp->ip, &from_packet->ip, ipsize);
|
|
+
|
|
+ switch (ntohs(from_packet->type)) {
|
|
+ case NAME_HOST:
|
|
+ insert_new_name_in_list(originator, list, from_packet, &name_table_changed, vtime);
|
|
+ break;
|
|
+ case NAME_FORWARDER:
|
|
+ insert_new_name_in_list(originator, forwarder_list, from_packet, &forwarder_table_changed, vtime);
|
|
+ break;
|
|
+ case NAME_SERVICE:
|
|
+ insert_new_name_in_list(originator, service_list, from_packet, &service_table_changed, vtime);
|
|
+ break;
|
|
+ default:
|
|
+ olsr_printf(3, "NAME PLUGIN: Received Message of unknown type [%d] from (%s)\n", from_packet->type, olsr_ip_to_string(originator));
|
|
+ break;
|
|
+ }
|
|
pos += sizeof(struct name);
|
|
- strncpy(tmp->name, pos, tmp->len);
|
|
- tmp->name[tmp->len] = '\0';
|
|
-
|
|
- olsr_printf(3, "NAME PLUGIN: New name %s (%s) %d %d\n",
|
|
- tmp->name, olsr_ip_to_string(&tmp->ip), tmp->len, tmp->type);
|
|
-
|
|
- // queue to front
|
|
- tmp->next = *to;
|
|
- *to = tmp;
|
|
-
|
|
- // name + padding
|
|
- pos += 1 + ((tmp->len - 1) | 3);
|
|
- }
|
|
+ pos += 1 + (( ntohs(from_packet->len) - 1) | 3);
|
|
+ }
|
|
if (i!=0)
|
|
- olsr_printf(4, "NAME PLUGIN: Lost %d names due to length inconsistency\n", i);
|
|
+ olsr_printf(4, "NAME PLUGIN: Lost %d entries in received packet due to length inconsistency (%s)\n", i, olsr_ip_to_string(originator));
|
|
}
|
|
|
|
|
|
/**
|
|
- * Update or register a new name entry
|
|
+ * insert all the new names,services and forwarders from a received packet into the
|
|
+ * corresponding entry for this ip in the corresponding hash table
|
|
*/
|
|
void
|
|
-update_name_entry(union olsr_ip_addr *originator, struct namemsg *msg, int msg_size, double vtime)
|
|
+insert_new_name_in_list(union olsr_ip_addr *originator, struct db_entry **this_list, struct name *from_packet, olsr_bool *this_table_changed, double vtime)
|
|
{
|
|
int hash;
|
|
struct db_entry *entry;
|
|
-
|
|
- olsr_printf(3, "NAME PLUGIN: Received Name Message from %s\n",
|
|
- olsr_ip_to_string(originator));
|
|
+ olsr_bool entry_found = OLSR_FALSE;
|
|
+ entry_found = OLSR_FALSE;
|
|
|
|
hash = olsr_hashing(originator);
|
|
|
|
- /* find the entry for originator */
|
|
- for (entry = list[hash]; entry != NULL; entry = entry->next)
|
|
- {
|
|
- if (memcmp(originator, &entry->originator, ipsize) == 0) {
|
|
- // found
|
|
- olsr_printf(4, "NAME PLUGIN: %s found\n",
|
|
- olsr_ip_to_string(originator));
|
|
-
|
|
- decap_namemsg(msg, msg_size, &entry->names);
|
|
-
|
|
- olsr_get_timestamp(vtime * 1000, &entry->timer);
|
|
-
|
|
- return;
|
|
- }
|
|
- }
|
|
-
|
|
- olsr_printf(3, "NAME PLUGIN: New entry %s\n",
|
|
- olsr_ip_to_string(originator));
|
|
-
|
|
- /* insert a new entry */
|
|
- entry = olsr_malloc(sizeof(struct db_entry), "new db_entry");
|
|
-
|
|
- memcpy(&entry->originator, originator, ipsize);
|
|
- olsr_get_timestamp(vtime * 1000, &entry->timer);
|
|
- entry->names = NULL;
|
|
- // queue to front
|
|
- entry->next = list[hash];
|
|
- list[hash] = entry;
|
|
-
|
|
- decap_namemsg(msg, msg_size, &entry->names);
|
|
-
|
|
- name_table_changed = OLSR_TRUE;
|
|
+ /* find the entry for originator, if there is already one */
|
|
+ for (entry = this_list[hash]; entry != NULL; entry = entry->next)
|
|
+ {
|
|
+ if (memcmp(originator, &entry->originator, ipsize) == 0) {
|
|
+ // found
|
|
+ olsr_printf(4, "NAME PLUGIN: found entry for (%s) in its hash table\n", olsr_ip_to_string(originator));
|
|
+
|
|
+ //delegate to function for parsing the packet and linking it to entry->names
|
|
+ decap_namemsg(from_packet, &entry->names, this_table_changed);
|
|
+
|
|
+ olsr_get_timestamp(vtime * 1000, &entry->timer);
|
|
+
|
|
+ entry_found = OLSR_TRUE;
|
|
+ }
|
|
+ }
|
|
+ if (! entry_found)
|
|
+ {
|
|
+ olsr_printf(3, "NAME PLUGIN: create new db entry for ip (%s) in hash table\n", olsr_ip_to_string(originator));
|
|
+
|
|
+ /* insert a new entry */
|
|
+ entry = olsr_malloc(sizeof(struct db_entry), "new db_entry");
|
|
+
|
|
+ memcpy(&entry->originator, originator, ipsize);
|
|
+ olsr_get_timestamp(vtime * 1000, &entry->timer);
|
|
+ entry->names = NULL;
|
|
+
|
|
+ // queue to front
|
|
+ entry->next = this_list[hash];
|
|
+ this_list[hash] = entry;
|
|
+
|
|
+ //delegate to function for parsing the packet and linking it to entry->names
|
|
+ decap_namemsg(from_packet, &entry->names, this_table_changed);
|
|
+ }
|
|
}
|
|
|
|
-
|
|
/**
|
|
* write names to a file in /etc/hosts compatible format
|
|
*/
|
|
@@ -650,8 +865,7 @@
|
|
|
|
// write own names
|
|
for (name = my_names; name != NULL; name = name->next) {
|
|
- fprintf(hosts, "%s\t%s%s\t# myself\n", olsr_ip_to_string(&name->ip),
|
|
- name->name, my_suffix );
|
|
+ fprintf(hosts, "%s\t%s%s\t# myself\n", olsr_ip_to_string(&name->ip), name->name, my_suffix );
|
|
}
|
|
|
|
// write received names
|
|
@@ -661,13 +875,11 @@
|
|
{
|
|
for (name = entry->names; name != NULL; name = name->next)
|
|
{
|
|
- if (name->type == NAME_HOST) {
|
|
- olsr_printf(6, "%s\t%s%s", olsr_ip_to_string(&name->ip), name->name, my_suffix);
|
|
- olsr_printf(6, "\t#%s\n", olsr_ip_to_string(&entry->originator));
|
|
-
|
|
- fprintf(hosts, "%s\t%s%s", olsr_ip_to_string(&name->ip), name->name, my_suffix);
|
|
- fprintf(hosts, "\t# %s\n", olsr_ip_to_string(&entry->originator));
|
|
- }
|
|
+ olsr_printf(6, "%s\t%s%s", olsr_ip_to_string(&name->ip), name->name, my_suffix);
|
|
+ olsr_printf(6, "\t#%s\n", olsr_ip_to_string(&entry->originator));
|
|
+
|
|
+ fprintf(hosts, "%s\t%s%s", olsr_ip_to_string(&name->ip), name->name, my_suffix);
|
|
+ fprintf(hosts, "\t# %s\n", olsr_ip_to_string(&entry->originator));
|
|
}
|
|
}
|
|
}
|
|
@@ -682,7 +894,70 @@
|
|
|
|
|
|
/**
|
|
- * write upstream DNS servers to resolv.conf file
|
|
+ * write services to a file in the format:
|
|
+ * service #originator ip
|
|
+ *
|
|
+ * since service has a special format
|
|
+ * each line will look similar to e.g.
|
|
+ * http://me.olsr:80|tcp|my little homepage
|
|
+ */
|
|
+void
|
|
+write_services_file()
|
|
+{
|
|
+ int hash;
|
|
+ struct name_entry *name;
|
|
+ struct db_entry *entry;
|
|
+ FILE* services_file;
|
|
+ time_t currtime;
|
|
+
|
|
+
|
|
+ if (!service_table_changed)
|
|
+ return;
|
|
+
|
|
+ olsr_printf(2, "NAME PLUGIN: writing services file\n");
|
|
+
|
|
+ services_file = fopen( my_services_file, "w" );
|
|
+ if (services_file == NULL) {
|
|
+ olsr_printf(2, "NAME PLUGIN: cant write services_file file\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ fprintf(services_file, "### this file is overwritten regularly by olsrd\n");
|
|
+ fprintf(services_file, "### do not edit\n\n");
|
|
+
|
|
+
|
|
+ // write own services
|
|
+ for (name = my_services; name != NULL; name = name->next) {
|
|
+ fprintf(services_file, "%s\t# my own service\n", name->name);
|
|
+ }
|
|
+
|
|
+ // write received services
|
|
+ for (hash = 0; hash < HASHSIZE; hash++)
|
|
+ {
|
|
+ for(entry = service_list[hash]; entry != NULL; entry = entry->next)
|
|
+ {
|
|
+ for (name = entry->names; name != NULL; name = name->next)
|
|
+ {
|
|
+ olsr_printf(6, "%s\t", name->name);
|
|
+ olsr_printf(6, "\t#%s\n", olsr_ip_to_string(&entry->originator));
|
|
+
|
|
+ fprintf(services_file, "%s\t", name->name );
|
|
+ fprintf(services_file, "\t#%s\n", olsr_ip_to_string(&entry->originator));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (time(&currtime)) {
|
|
+ fprintf(services_file, "\n### written by olsrd at %s", ctime(&currtime));
|
|
+ }
|
|
+
|
|
+ fclose(services_file);
|
|
+ service_table_changed = OLSR_FALSE;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * write the 3 best upstream DNS servers to resolv.conf file
|
|
+ * best means the 3 with the best etx value in routing table
|
|
*/
|
|
void
|
|
write_resolv_file()
|
|
@@ -694,23 +969,17 @@
|
|
struct rt_entry *route, *tmp, *last;
|
|
FILE* resolv;
|
|
int i=0;
|
|
+ time_t currtime;
|
|
|
|
- if (my_resolv_file[0] == '\0')
|
|
- return;
|
|
-
|
|
- if (!name_table_changed)
|
|
+ if (!forwarder_table_changed || my_forwarders != NULL || my_resolv_file[0] == '\0')
|
|
return;
|
|
|
|
- olsr_printf(2, "NAME PLUGIN: writing resolv file\n");
|
|
-
|
|
for (hash = 0; hash < HASHSIZE; hash++)
|
|
{
|
|
- for(entry = list[hash]; entry != NULL; entry = entry->next)
|
|
+ for(entry = forwarder_list[hash]; entry != NULL; entry = entry->next)
|
|
{
|
|
for (name = entry->names; name != NULL; name = name->next)
|
|
{
|
|
- if (name->type != NAME_FORWARDER)
|
|
- continue;
|
|
|
|
/* find the nearest one */
|
|
route = olsr_lookup_routing_table(&name->ip);
|
|
@@ -762,18 +1031,25 @@
|
|
return;
|
|
|
|
/* write to file */
|
|
+ olsr_printf(2, "NAME PLUGIN: try to write to resolv file\n");
|
|
resolv = fopen( my_resolv_file, "w" );
|
|
if (resolv == NULL) {
|
|
olsr_printf(2, "NAME PLUGIN: can't write resolv file\n");
|
|
return;
|
|
}
|
|
+ fprintf(resolv, "### this file is overwritten regularly by olsrd\n");
|
|
+ fprintf(resolv, "### do not edit\n\n");
|
|
i=0;
|
|
for (tmp=best_routes; tmp!=NULL && i<3; tmp=tmp->next) {
|
|
olsr_printf(6, "NAME PLUGIN: nameserver %s\n", olsr_ip_to_string(&tmp->rt_dst));
|
|
fprintf(resolv, "nameserver %s\n", olsr_ip_to_string(&tmp->rt_dst));
|
|
i++;
|
|
}
|
|
+ if (time(&currtime)) {
|
|
+ fprintf(resolv, "\n### written by olsrd at %s", ctime(&currtime));
|
|
+ }
|
|
fclose(resolv);
|
|
+ forwarder_table_changed = OLSR_FALSE;
|
|
}
|
|
|
|
|
|
@@ -789,6 +1065,7 @@
|
|
to_delete = *tmp;
|
|
*tmp = (*tmp)->next;
|
|
free( to_delete->name );
|
|
+ to_delete->name = NULL;
|
|
free( to_delete );
|
|
to_delete = NULL;
|
|
}
|
|
@@ -831,3 +1108,84 @@
|
|
}
|
|
return OLSR_FALSE;
|
|
}
|
|
+
|
|
+/** check if name has the right syntax, i.e. it must adhere to a special regex
|
|
+ * stored in regex_t_name
|
|
+ * necessary to avaid names like "0.0.0.0 google.de\n etc"
|
|
+ */
|
|
+olsr_bool
|
|
+is_name_wellformed(char *name) {
|
|
+ return regexec(®ex_t_name, name, 1, ®match_t_name, 0) == 0 ;
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * check if the service is in the right syntax and also that the hostname
|
|
+ * or ip whithin the service is allowed
|
|
+ */
|
|
+olsr_bool
|
|
+allowed_service(char *service_line)
|
|
+{
|
|
+ /* the call of is_service_wellformed generates the submatches stored in regmatch_t_service
|
|
+ * these are then used by allowed_hostname_or_ip_in_service
|
|
+ * see regexec(3) for more infos */
|
|
+ if (!is_service_wellformed(service_line)) {
|
|
+ return OLSR_FALSE;
|
|
+ } else if (!allowed_hostname_or_ip_in_service(service_line, &(regmatch_t_service[1]))) {
|
|
+ return OLSR_FALSE;
|
|
+ }
|
|
+
|
|
+ return OLSR_TRUE;
|
|
+}
|
|
+
|
|
+olsr_bool
|
|
+allowed_hostname_or_ip_in_service(char *service_line, regmatch_t *hostname_or_ip_match)
|
|
+{
|
|
+ char *hostname_or_ip;
|
|
+ struct in_addr ip;
|
|
+ union olsr_ip_addr olsr_ip;
|
|
+ struct name_entry *name;
|
|
+ if (hostname_or_ip_match->rm_so < 0 || hostname_or_ip_match->rm_eo < 0) {
|
|
+ return OLSR_FALSE;
|
|
+ }
|
|
+
|
|
+ hostname_or_ip = strndup(&service_line[hostname_or_ip_match->rm_so], hostname_or_ip_match->rm_eo - hostname_or_ip_match->rm_so);
|
|
+ //hostname is one of the names, that I announce (i.e. one that i am allowed to announce)
|
|
+ for (name = my_names; name != NULL; name = name->next) {
|
|
+ if (strncmp(name->name, hostname_or_ip, name->len - strlen(my_suffix)) == 0 ) {
|
|
+ olsr_printf(4, "NAME PLUGIN: hostname %s in service %s is OK\n", hostname_or_ip, service_line);
|
|
+ free(hostname_or_ip);
|
|
+ hostname_or_ip = NULL;
|
|
+ return OLSR_TRUE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ //ip in service-line is allowed
|
|
+ if (inet_aton(hostname_or_ip, &ip)) {
|
|
+ olsr_ip.v4 = ip.s_addr;
|
|
+ if (allowed_ip(&olsr_ip)) {
|
|
+ olsr_printf(2, "NAME PLUGIN: ip %s in service %s is OK\n", olsr_ip_to_string(&olsr_ip), service_line);
|
|
+ free(hostname_or_ip);
|
|
+ hostname_or_ip = NULL;
|
|
+ return OLSR_TRUE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ olsr_printf(1, "NAME PLUGIN: ip or hostname %s in service %s is NOT allowed (does not belong to you)\n", hostname_or_ip, service_line);
|
|
+ free(hostname_or_ip);
|
|
+ hostname_or_ip = NULL;
|
|
+
|
|
+ return OLSR_FALSE;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * check if the service matches the syntax
|
|
+ * of "protocol://host:port/path|tcp_or_udp|a short description",
|
|
+ * which is given in the regex regex_t_service
|
|
+ */
|
|
+olsr_bool
|
|
+is_service_wellformed(char *service_line)
|
|
+{
|
|
+ return regexec(®ex_t_service, service_line, pmatch_service, regmatch_t_service, 0) == 0;
|
|
+}
|
|
+
|
|
diff -Nur olsrd-0.4.10.orig/lib/nameservice/src/nameservice.h olsrd-0.4.10/lib/nameservice/src/nameservice.h
|
|
--- olsrd-0.4.10.orig/lib/nameservice/src/nameservice.h 2005-06-02 17:34:00.000000000 +0200
|
|
+++ olsrd-0.4.10/lib/nameservice/src/nameservice.h 2006-12-01 08:26:58.000000000 +0100
|
|
@@ -39,6 +39,7 @@
|
|
#define _NAMESERVICE_PLUGIN
|
|
|
|
#include <sys/time.h>
|
|
+#include <regex.h>
|
|
|
|
#include "olsr_types.h"
|
|
#include "interfaces.h"
|
|
@@ -51,19 +52,27 @@
|
|
#define PLUGIN_VERSION "0.2"
|
|
#define PLUGIN_AUTHOR "Bruno Randolf"
|
|
|
|
+// useful to set for the freifunkfirmware to remove all
|
|
+// calls to olsr_printf by the empty statement ";"
|
|
+//#define olsr_printf(...) ;
|
|
|
|
#define MESSAGE_TYPE 130
|
|
#define PARSER_TYPE MESSAGE_TYPE
|
|
#define EMISSION_INTERVAL 120 /* two minutes */
|
|
-#define NAME_VALID_TIME 3600 /* one hour */
|
|
+#define NAME_VALID_TIME 1800 /* half one hour */
|
|
|
|
#define NAME_PROTOCOL_VERSION 1
|
|
|
|
-#define MAX_NAME 255
|
|
+#define MAX_NAME 127
|
|
#define MAX_FILE 255
|
|
-#define MAX_SUFFIX 255
|
|
-
|
|
+#define MAX_SUFFIX 63
|
|
|
|
+/**
|
|
+ * a linked list of name_entry
|
|
+ * if type is NAME_HOST, name is a hostname and ip its IP addr
|
|
+ * if type is NAME_FORWARDER, then ip is a dns-server (and name is irrelevant)
|
|
+ * if type is NAME_SERVICE, then name is a service-line (and the ip is irrelevant)
|
|
+ */
|
|
struct name_entry
|
|
{
|
|
union olsr_ip_addr ip;
|
|
@@ -73,7 +82,17 @@
|
|
struct name_entry *next; /* linked list */
|
|
};
|
|
|
|
-/* database entry */
|
|
+/* *
|
|
+ * linked list of db_entries for each originator with
|
|
+ * originator being its main_addr
|
|
+ *
|
|
+ * names points to the name_entry with its hostname, dns-server or
|
|
+ * service-line entry
|
|
+ *
|
|
+ * all the db_entries are hashed in nameservice.c to avoid a too long list
|
|
+ * for many nodes in a net
|
|
+ *
|
|
+ * */
|
|
struct db_entry
|
|
{
|
|
union olsr_ip_addr originator; /* IP address of the node this entry describes */
|
|
@@ -98,8 +117,26 @@
|
|
int
|
|
encap_namemsg(struct namemsg *);
|
|
|
|
+struct name_entry*
|
|
+add_name_to_list(struct name_entry *my_list, char *value, int type, struct in_addr *ip);
|
|
+
|
|
+struct name_entry*
|
|
+remove_nonvalid_names_from_list(struct name_entry *my_list, int type);
|
|
+
|
|
+void
|
|
+free_all_list_entries(struct db_entry **this_db_list) ;
|
|
+
|
|
void
|
|
-decap_namemsg(struct namemsg *, int, struct name_entry**);
|
|
+timeout_old_names(struct db_entry **this_list, olsr_bool *this_table_changed);
|
|
+
|
|
+void
|
|
+decap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_table_changed );
|
|
+
|
|
+void
|
|
+insert_new_name_in_list(union olsr_ip_addr *originator, struct db_entry **this_list, struct name *from_packet, olsr_bool *this_table_changed, double vtime);
|
|
+
|
|
+olsr_bool
|
|
+allowed_hostname_or_ip_in_service(char *service_line, regmatch_t *hostname_or_ip);
|
|
|
|
void
|
|
update_name_entry(union olsr_ip_addr *, struct namemsg *, int, double);
|
|
@@ -108,6 +145,9 @@
|
|
write_hosts_file(void);
|
|
|
|
void
|
|
+write_services_file(void);
|
|
+
|
|
+void
|
|
write_resolv_file(void);
|
|
|
|
int
|
|
@@ -119,6 +159,18 @@
|
|
olsr_bool
|
|
allowed_ip(union olsr_ip_addr *addr);
|
|
|
|
+olsr_bool
|
|
+allowed_service(char *service_line);
|
|
+
|
|
+olsr_bool
|
|
+is_name_wellformed(char *service_line);
|
|
+
|
|
+olsr_bool
|
|
+is_service_wellformed(char *service_line);
|
|
+
|
|
+char*
|
|
+create_packet(struct name *to, struct name_entry *from);
|
|
+
|
|
void
|
|
name_constructor(void);
|
|
|
|
diff -Nur olsrd-0.4.10.orig/lib/nameservice/src/nameservice_msg.h olsrd-0.4.10/lib/nameservice/src/nameservice_msg.h
|
|
--- olsrd-0.4.10.orig/lib/nameservice/src/nameservice_msg.h 2005-03-17 22:41:30.000000000 +0100
|
|
+++ olsrd-0.4.10/lib/nameservice/src/nameservice_msg.h 2006-12-01 08:26:58.000000000 +0100
|
|
@@ -38,29 +38,34 @@
|
|
#ifndef _NAMESEVICE_MSG
|
|
#define _NAMESEVICE_MSG
|
|
|
|
-
|
|
+/* type of the packet of name_entry */
|
|
typedef enum {
|
|
NAME_HOST = 0,
|
|
NAME_FORWARDER = 1,
|
|
- NAME_SERVICE = 2
|
|
+ NAME_SERVICE = 2,
|
|
} NAME_TYPE;
|
|
|
|
-
|
|
+/**
|
|
+ * the name, forwarder or service entry as found in a packet within a
|
|
+ * message
|
|
+ **/
|
|
struct name
|
|
{
|
|
olsr_u16_t type;
|
|
olsr_u16_t len; // length of the name
|
|
+ // the ip of the hostname, or the ip of the dns-server
|
|
+ // ip is irrelevant for services
|
|
union olsr_ip_addr ip;
|
|
/*
|
|
- * name is written in plain text after this struct and padded to 4 byte
|
|
+ * name or service is written in plain text after this struct and padded to 4 byte
|
|
*/
|
|
};
|
|
|
|
|
|
struct namemsg
|
|
{
|
|
- olsr_u16_t version;
|
|
- olsr_u16_t nr_names; // number of following name messages
|
|
+ olsr_u16_t version; // version number of the nameservice plugin
|
|
+ olsr_u16_t nr_names; // number of following packets including names, forwarders or services
|
|
/*
|
|
* at least one struct name following
|
|
*/
|