📄 nameservice.c
字号:
/* * Copyright (c) 2006, Jens Nachtigall <nachtigall@web.de> * Copyright (c) 2005, Bruno Randolf <bruno.randolf@4g-systems.biz> * Copyright (c) 2004, Andreas T鴑nesen(andreto-at-olsr.org) * Copyright (c) 2007, Sven-Ola <sven-ola@gmx.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the UniK olsr daemon nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * *//* $Id: nameservice.c,v 1.32 2007/10/05 20:24:47 bernd67 Exp $ *//* * Dynamic linked library for UniK OLSRd */#include <stdio.h>#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"#include "routing_table.h"#include "mantissa.h"#include "scheduler.h"#include "parser.h"#include "duplicate_set.h"#include "tc_set.h"#include "hna_set.h"#include "mid_set.h"#include "link_set.h"#include "plugin_util.h"#include "nameservice.h"#include "olsrd_copy.h"#include "compat.h"/* config parameters */static char my_hosts_file[MAX_FILE + 1];static char my_add_hosts[MAX_FILE + 1];static char my_suffix[MAX_SUFFIX];static int my_interval = EMISSION_INTERVAL;static double my_timeout = NAME_VALID_TIME;static char my_resolv_file[MAX_FILE +1];static char my_services_file[MAX_FILE + 1];static char latlon_in_file[MAX_FILE + 1];static char my_latlon_file[MAX_FILE + 1];static float my_lat = 0.0, my_lon = 0.0;/* 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) * */static struct db_entry* list[HASHSIZE];static struct name_entry *my_names = NULL;static olsr_bool name_table_changed = OLSR_TRUE;static struct db_entry* service_list[HASHSIZE];static struct name_entry *my_services = NULL;static olsr_bool service_table_changed = OLSR_TRUE;static struct db_entry* forwarder_list[HASHSIZE];static struct name_entry *my_forwarders = NULL;static olsr_bool forwarder_table_changed = OLSR_TRUE;static struct db_entry* latlon_list[HASHSIZE];static olsr_bool latlon_table_changed = OLSR_TRUE;/* regular expression to be matched by valid hostnames, compiled in name_init() */static regex_t regex_t_name;static regmatch_t regmatch_t_name;/* regular expression to be matched by valid service_lines, compiled in name_init() */static regex_t regex_t_service;static int pmatch_service = 10;static regmatch_t regmatch_t_service[10];/** * do initialization */voidname_constructor(void) { int i; #ifdef WIN32 int len; GetWindowsDirectory(my_hosts_file, MAX_FILE - 12); GetWindowsDirectory(my_services_file, MAX_FILE - 12); GetWindowsDirectory(my_latlon_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"); len = strlen(my_latlon_file); if (my_latlon_file[len - 1] != '\\') my_latlon_file[len++] = '\\'; strcpy(my_latlon_file + len, "latlon.js");#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"); strcpy(my_latlon_file, "/var/run/latlon.js");#endif my_suffix[0] = '\0'; my_add_hosts[0] = '\0'; latlon_in_file[0] = '\0'; /* init lists */ for(i = 0; i < HASHSIZE; i++) { list[i] = NULL; forwarder_list[i] = NULL; service_list[i] = NULL; latlon_list[i] = NULL; } }static int set_nameservice_server(const char *value, void *data, set_plugin_parameter_addon addon){ union olsr_ip_addr ip; struct name_entry **v = data; if (0 == strlen(value)) { *v = add_name_to_list(*v, "", addon.ui, NULL); OLSR_PRINTF(1, "%s got %s (main address)\n", "Got", value); return 0; } else if (0 < inet_pton(olsr_cnf->ip_version, value, &ip)) { *v = add_name_to_list(*v, "", addon.ui, &ip); OLSR_PRINTF(1, "%s got %s\n", "Got", value); return 0; } else { OLSR_PRINTF(0, "Illegal IP address \"%s\"", value); } return 1;}static int set_nameservice_name(const char *value, void *data, set_plugin_parameter_addon addon){ struct name_entry **v = data; if (0 < strlen(value)) { *v = add_name_to_list(*v, (char*)value, addon.ui, NULL); OLSR_PRINTF(1, "%s got %s (main address)\n", "Got", value); return 0; } else { OLSR_PRINTF(0, "Illegal name \"%s\"", value); } return 1;}static int set_nameservice_host(const char *value, void *data, set_plugin_parameter_addon addon){ union olsr_ip_addr ip; struct name_entry **v = data; if (0 < inet_pton(olsr_cnf->ip_version, addon.pc, &ip)) { // the IP is validated later *v = add_name_to_list(*v, (char*)value, NAME_HOST, &ip); OLSR_PRINTF(1, "%s: %s got %s\n", "Got", addon.pc, value); return 0; } else { OLSR_PRINTF(0, "%s: Illegal IP address \"%s\"", addon.pc, value); } return 1;}static int set_nameservice_float(const char *value, void *data, set_plugin_parameter_addon addon __attribute__((unused))){ const float thefloat = atof(value); if (data != NULL) { float *v = data; *v = thefloat; OLSR_PRINTF(1, "%s float %f\n", "Got", thefloat); } else { OLSR_PRINTF(0, "%s float %f\n", "Ignored", thefloat); } return 0;}static const struct olsrd_plugin_parameters plugin_parameters[] = { { .name = "interval", .set_plugin_parameter = &set_plugin_int, .data = &my_interval }, { .name = "timeout", .set_plugin_parameter = &set_nameservice_float, .data = &my_timeout }, { .name = "hosts-file", .set_plugin_parameter = &set_plugin_string, .data = &my_hosts_file, .addon = {sizeof(my_hosts_file)} }, { .name = "resolv-file", .set_plugin_parameter = &set_plugin_string, .data = &my_resolv_file, .addon = {sizeof(my_resolv_file)} }, { .name = "suffix", .set_plugin_parameter = &set_plugin_string, .data = &my_suffix, .addon = {sizeof(my_suffix)} }, { .name = "add-hosts", .set_plugin_parameter = &set_plugin_string, .data = &my_add_hosts, .addon = {sizeof(my_add_hosts)} }, { .name = "services-file", .set_plugin_parameter = &set_plugin_string, .data = &my_services_file, .addon = {sizeof(my_services_file)} }, { .name = "lat", .set_plugin_parameter = &set_nameservice_float, .data = &my_lat }, { .name = "lon", .set_plugin_parameter = &set_nameservice_float, .data = &my_lon }, { .name = "latlon-file", .set_plugin_parameter = &set_plugin_string, .data = &my_latlon_file, .addon = {sizeof(my_latlon_file)} }, { .name = "latlon-infile", .set_plugin_parameter = &set_plugin_string, .data = &latlon_in_file, .addon = {sizeof(latlon_in_file)} }, { .name = "dns-server", .set_plugin_parameter = &set_nameservice_server, .data = &my_forwarders, .addon = {NAME_FORWARDER} }, { .name = "name", .set_plugin_parameter = &set_nameservice_name, .data = &my_names, .addon = {NAME_HOST} }, { .name = "service", .set_plugin_parameter = &set_nameservice_name, .data = &my_services, .addon = {NAME_SERVICE} }, { .name = "", .set_plugin_parameter = &set_nameservice_host, .data = &my_names },};void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size){ *params = plugin_parameters; *size = sizeof(plugin_parameters)/sizeof(*plugin_parameters);}/** * 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, const char *value, int type, const union olsr_ip_addr *ip) { struct name_entry *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 = *ip; tmp->next = my_list; return tmp;}/** * last initialization * * we have to do this here because some things like main_addr * or the dns suffix (for validation) are not known before * * 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 * which sets up main_addr and some other variables * - register_olsr_data() then then finally calls this function */intname_init(void){ struct name_entry *name; union olsr_ip_addr ipz; 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"); memset(&ipz, 0, sizeof(ipz)); //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:]]+$"; strcpy(regex_service, "^[[:alnum:]]+://(([[:alnum:]_.-]+"); strcat(regex_service, my_suffix); strcat(regex_service, ")|([[: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 (memcmp(&name->ip, &ipz, olsr_cnf->ipsize) == 0) { OLSR_PRINTF(2, "NAME PLUGIN: insert main addr for name %s \n", name->name); memcpy(&name->ip, &olsr_cnf->main_addr, olsr_cnf->ipsize); } } 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, &olsr_cnf->main_addr, olsr_cnf->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); /* register functions with olsrd */ olsr_parser_add_function(&olsr_parser, PARSER_TYPE, 1); olsr_register_timeout_function(&olsr_timeout, OLSR_TRUE); olsr_register_scheduler_event(&olsr_event, NULL, my_interval, 0, NULL); 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -