Author: tjansen Date: Mon Nov 23 16:46:26 2009 New Revision: 1745 Log: Added DNS backend. Look up HIT and remote IPv4 via DNS. Still needs proper error handling. Modified: trunk/pisacd/cdservers.c Modified: trunk/pisacd/cdservers.c ============================================================================== --- trunk/pisacd/cdservers.c Mon Nov 23 15:07:19 2009 (r1744) +++ trunk/pisacd/cdservers.c Mon Nov 23 16:46:26 2009 (r1745) @@ -10,6 +10,12 @@ * @date Jun. 2009 */ +#define _XOPEN_SOURCE + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + #include "cdconf.h" #include "cdctx.h" #include "cdregister.h" @@ -220,42 +226,73 @@ } /** + * Get the HIT and remote IPv4 of a service specified by a virtual local IP + * address. + * + * @param dn domain name + * @param hit destination buffer for the HIT + * @param remote destination buffer for the remote IPv4 + * @return true on success, false otherwise + */ +static bool pisa_servers_lookup_dns(char *dn, struct in6_addr *hit, struct in_addr *remote) +{ + bool found_hit = false, found_remote = false; + struct addrinfo *ai, *ais = NULL, hints; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + + if (getaddrinfo(dn, NULL, &hints, &ais) != 0) + return false; + + for (ai = ais; ai; ai = ai->ai_next) { + if (ai->ai_family == AF_INET) { + struct sockaddr_in *tmp = (struct sockaddr_in *) ai->ai_addr; + pisa_ipv4_copy(remote, &tmp->sin_addr); + found_remote = true; + } else if (ai->ai_family == AF_INET6) { + struct sockaddr_in6 *tmp = (struct sockaddr_in6 *) ai->ai_addr; + pisa_ipv6_copy(hit, &tmp->sin6_addr); + found_hit = true; + } + } + + if (ais) + freeaddrinfo(ais); + + return found_hit && found_remote; +} + +/** * Retrieve the NAT mapping and the conmgr entry from DNS. * * TODO: Remove the NAT mapping if an error occurs. Otherwise we might have a * DOS attack vector: Attacker sends a lot of packets to different * (non-existant) virtual addresses the allocate memory for a NAT mapping. * - * This is currently a stub using hardcoded values for Thomas' virtual - * machines. - * * @param data NAT mapping */ static void pisa_servers_query_dns(void *data) { pisa_nat_mapping *nat = (pisa_nat_mapping *) data; - char local_str[INET_ADDRSTRLEN], remote_str[INET_ADDRSTRLEN]; - char hit_str[INET6_ADDRSTRLEN], dn[128]; + char dn[128]; pisa_conmgr_entry *entry; struct in6_addr hit; struct in_addr remote; - inet_pton(AF_INET6, "2001:16:415e:da37:11f6:d0e7:33f5:3ee7", &hit); - inet_pton(AF_INET, "192.168.151.31", &remote); - - entry = pisa_conmgr_findby_hit(cd_ctx.conlist, &hit); + if (!pisa_servers_build_domain_name(&nat->local_private, dn, sizeof(dn))) + return; + if (!pisa_servers_lookup_dns(dn, &hit, &remote)) + return; + /* TODO: If no conmgr entry exists we have to build one... */ + if (!(entry = pisa_conmgr_findby_hit(cd_ctx.conlist, &hit))) + return; pisa_nat_upgrade_preliminary(cd_ctx.natlist, nat, &remote, entry, NULL); - pisa_servers_build_domain_name(&nat->local_private, dn, sizeof(dn)); - PISA_DEBUG(PL_CONFIG, "domain name: %s\n", dn); - - inet_ntop(AF_INET, &nat->local_private, local_str, sizeof(local_str)); - inet_ntop(AF_INET, &nat->remote.ipv4, remote_str, sizeof(remote_str)); - inet_ntop(AF_INET6, &nat->remote.hit, hit_str, sizeof(hit_str)); - - PISA_DEBUG(PL_CONFIG, "Upgraded NAT mapping: local: %s remote %s HIT %s\n", - local_str, remote_str, hit_str); + /* TODO: clean up after failure, otherwise we're stuck */ } /**