📄 nameservice.c
字号:
if (len_of_name > MAX_NAME || strlen(name) != len_of_name) { OLSR_PRINTF(4, "NAME 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; } // 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, "NAME 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, "NAME PLUGIN: received forwarder 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_LATLON ) { if (0 != strncmp(already_saved_name_entries->name, name, len_of_name)) { OLSR_PRINTF(4, "NAME PLUGIN: updating name %s -> %s (%s)\n", already_saved_name_entries->name, name, olsr_ip_to_string(&already_saved_name_entries->ip)); free(already_saved_name_entries->name); already_saved_name_entries->name = olsr_malloc(len_of_name + 1, "upd name_entry name"); strncpy(already_saved_name_entries->name, name, len_of_name); *this_table_changed = OLSR_TRUE; } if (!COMP_IP(&already_saved_name_entries->ip, &from_packet->ip)) { OLSR_PRINTF(4, "NAME PLUGIN: updating ip %s -> %s (%s)\n", olsr_ip_to_string(&already_saved_name_entries->ip), olsr_ip_to_string(&from_packet->ip), olsr_ip_to_string(&already_saved_name_entries->ip)); memcpy(&already_saved_name_entries->ip, &from_packet->ip, olsr_cnf->ipsize); *this_table_changed = OLSR_TRUE; } if (!*this_table_changed) { OLSR_PRINTF(4, "NAME PLUGIN: received latlon entry %s (%s) already in hash table\n", name, olsr_ip_to_string(&already_saved_name_entries->ip)); } 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, olsr_cnf->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 decapsulation function for each * name/service/forwarder entry in the message */voidupdate_name_entry(union olsr_ip_addr *originator, struct namemsg *msg, int msg_size, double vtime){ char *pos, *end_pos; struct name *from_packet; int i; OLSR_PRINTF(3, "NAME PLUGIN: Received Message from %s\n", olsr_ip_to_string(originator)); if (ntohs(msg->version) != NAME_PROTOCOL_VERSION) { OLSR_PRINTF(3, "NAME PLUGIN: ignoring wrong version %d\n", msg->version); return; } /* now add the names from the message */ pos = (char*)msg + sizeof(struct namemsg); 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; 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; case NAME_LATLON: insert_new_name_in_list(originator, latlon_list, from_packet, &latlon_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); pos += 1 + (( ntohs(from_packet->len) - 1) | 3); } if (i!=0) OLSR_PRINTF(4, "NAME PLUGIN: Lost %d entries in received packet due to length inconsistency (%s)\n", i, olsr_ip_to_string(originator));}/** * insert all the new names,services and forwarders from a received packet into the * corresponding entry for this ip in the corresponding hash table */voidinsert_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_bool entry_found = OLSR_FALSE; hash = olsr_hashing(originator); /* 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, olsr_cnf->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, olsr_cnf->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 */voidwrite_hosts_file(void){ int hash; struct name_entry *name; struct db_entry *entry; FILE* hosts; FILE* add_hosts; int c=0; time_t currtime; if (!name_table_changed) return; OLSR_PRINTF(2, "NAME PLUGIN: writing hosts file\n"); hosts = fopen( my_hosts_file, "w" ); if (hosts == NULL) { OLSR_PRINTF(2, "NAME PLUGIN: cant write hosts file\n"); return; } fprintf(hosts, "### this /etc/hosts file is overwritten regularly by olsrd\n"); fprintf(hosts, "### do not edit\n\n"); fprintf(hosts, "127.0.0.1\tlocalhost\n"); fprintf(hosts, "::1\t\tlocalhost\n\n"); // copy content from additional hosts filename if (my_add_hosts[0] != '\0') { add_hosts = fopen( my_add_hosts, "r" ); if (add_hosts == NULL) { OLSR_PRINTF(2, "NAME PLUGIN: cant open additional hosts file\n"); } else { fprintf(hosts, "### contents from '%s' ###\n\n", my_add_hosts); while ((c = getc(add_hosts)) != EOF) putc(c, hosts); } fclose(add_hosts); fprintf(hosts, "\n### olsr names ###\n\n"); } // 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 ); } // write received names for (hash = 0; hash < HASHSIZE; hash++) { for(entry = list[hash]; entry != NULL; entry = entry->next) { for (name = entry->names; name != NULL; name = name->next) { 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)); } } } if (time(&currtime)) { fprintf(hosts, "\n### written by olsrd at %s", ctime(&currtime)); } fclose(hosts); name_table_changed = OLSR_FALSE;}/** * 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 */voidwrite_services_file(void){ 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;}/** * Sort the nameserver pointer array. * * fresh entries are at the beginning of the array and * the best entry is at the end of the array. */static voidselect_best_nameserver(struct rt_entry **rt){ int nameserver_idx; struct rt_entry *rt1, *rt2; for (nameserver_idx = 0; nameserver_idx < NAMESERVER_COUNT; nameserver_idx++) { rt1 = rt[nameserver_idx]; rt2 = rt[nameserver_idx+1]; /* * compare the next two pointers in the array. * if the second pointer is NULL then percolate it up. */ if (!rt2 || olsr_cmp_rt(rt1, rt2)) { /* * first is better, swap the pointers. */ OLSR_PRINTF(6, "NAME PLUGIN: nameserver %s, etx %.3f\n", olsr_ip_to_string(&rt1->rt_dst.prefix), rt1->rt_best->rtp_metric.etx); rt[nameserver_idx] = rt2; rt[nameserver_idx+1] = rt1; } }}/** * write the 3 best upstream DNS servers to resolv.conf file * best means the 3 with the best etx value in routing table */voidwrite_resolv_file(void){ int hash; struct name_entry *name; struct db_entry *entry; struct rt_entry *route; static struct rt_entry *nameserver_routes[NAMESERVER_COUNT+1]; FILE* resolv; int i=0; time_t currtime; if (!forwarder_table_changed || my_forwarders != NULL || my_resolv_file[0] == '\0') return; /* clear the array of 3+1 nameserver routes */ memset(nameserver_routes, 0, sizeof(nameserver_routes)); for (hash = 0; hash < HASHSIZE; hash++) { for(entry = forwarder_list[hash]; entry != NULL; entry = entry->next) { for (name = entry->names; name != NULL; name = name->next) { route = olsr_lookup_routing_table(&name->ip); OLSR_PRINTF(6, "NAME PLUGIN: check route for nameserver %s %s", olsr_ip_to_string(&name->ip), route ? "suceeded" : "failed"); if (route==NULL) // it's possible that route is not present yet continue; /* enqueue it on the head of list */ *nameserver_routes = route; OLSR_PRINTF(6, "NAME PLUGIN: found nameserver %s, etx %.3f", olsr_ip_to_string(&name->ip), route->rt_best->rtp_metric.etx); /* find the closet one */ select_best_nameserver(nameserver_routes);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -