mirror of https://github.com/ipxe/ipxe.git
[dns] Append local domain to relative names
Try to qualify relative names in the DNS resolver using the DHCP Domain Name. For example: DHCP Domain Name: etherboot.org (Relative) Name: www yields: www.etherboot.org Only names with no dots ('.') will be modified. A name with one or more dots is unchanged.pull/1/head
parent
a128973ecb
commit
d10a7e7739
|
@ -218,6 +218,7 @@ extern struct setting ip_setting __setting;
|
||||||
extern struct setting netmask_setting __setting;
|
extern struct setting netmask_setting __setting;
|
||||||
extern struct setting gateway_setting __setting;
|
extern struct setting gateway_setting __setting;
|
||||||
extern struct setting dns_setting __setting;
|
extern struct setting dns_setting __setting;
|
||||||
|
extern struct setting domain_setting __setting;
|
||||||
extern struct setting hostname_setting __setting;
|
extern struct setting hostname_setting __setting;
|
||||||
extern struct setting filename_setting __setting;
|
extern struct setting filename_setting __setting;
|
||||||
extern struct setting root_path_setting __setting;
|
extern struct setting root_path_setting __setting;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#include <gpxe/refcnt.h>
|
#include <gpxe/refcnt.h>
|
||||||
|
@ -47,6 +48,9 @@ static struct sockaddr_tcpip nameserver = {
|
||||||
.st_port = htons ( DNS_PORT ),
|
.st_port = htons ( DNS_PORT ),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** The local domain */
|
||||||
|
static char *localdomain;
|
||||||
|
|
||||||
/** A DNS request */
|
/** A DNS request */
|
||||||
struct dns_request {
|
struct dns_request {
|
||||||
/** Reference counter */
|
/** Reference counter */
|
||||||
|
@ -179,6 +183,27 @@ static union dns_rr_info * dns_find_rr ( struct dns_request *dns,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append DHCP domain name if available and name is not fully qualified
|
||||||
|
*
|
||||||
|
* @v string Name as a NUL-terminated string
|
||||||
|
* @ret fqdn Fully-qualified domain name, malloc'd copy
|
||||||
|
*
|
||||||
|
* The caller must free fqdn which is allocated even if the name is already
|
||||||
|
* fully qualified.
|
||||||
|
*/
|
||||||
|
static char * dns_qualify_name ( const char *string ) {
|
||||||
|
char *fqdn;
|
||||||
|
|
||||||
|
/* Leave unchanged if already fully-qualified or no local domain */
|
||||||
|
if ( ( ! localdomain ) || ( strchr ( string, '.' ) != 0 ) )
|
||||||
|
return strdup ( string );
|
||||||
|
|
||||||
|
/* Append local domain to name */
|
||||||
|
asprintf ( &fqdn, "%s.%s", string, localdomain );
|
||||||
|
return fqdn;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a standard NUL-terminated string to a DNS name
|
* Convert a standard NUL-terminated string to a DNS name
|
||||||
*
|
*
|
||||||
|
@ -452,19 +477,30 @@ static struct xfer_interface_operations dns_socket_operations = {
|
||||||
static int dns_resolv ( struct resolv_interface *resolv,
|
static int dns_resolv ( struct resolv_interface *resolv,
|
||||||
const char *name, struct sockaddr *sa ) {
|
const char *name, struct sockaddr *sa ) {
|
||||||
struct dns_request *dns;
|
struct dns_request *dns;
|
||||||
|
char *fqdn;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Fail immediately if no DNS servers */
|
/* Fail immediately if no DNS servers */
|
||||||
if ( ! nameserver.st_family ) {
|
if ( ! nameserver.st_family ) {
|
||||||
DBG ( "DNS not attempting to resolve \"%s\": "
|
DBG ( "DNS not attempting to resolve \"%s\": "
|
||||||
"no DNS servers\n", name );
|
"no DNS servers\n", name );
|
||||||
return -ENXIO;
|
rc = -ENXIO;
|
||||||
|
goto err_no_nameserver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure fully-qualified domain name if DHCP option was given */
|
||||||
|
fqdn = dns_qualify_name ( name );
|
||||||
|
if ( ! fqdn ) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto err_qualify_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate DNS structure */
|
/* Allocate DNS structure */
|
||||||
dns = zalloc ( sizeof ( *dns ) );
|
dns = zalloc ( sizeof ( *dns ) );
|
||||||
if ( ! dns )
|
if ( ! dns ) {
|
||||||
return -ENOMEM;
|
rc = -ENOMEM;
|
||||||
|
goto err_alloc_dns;
|
||||||
|
}
|
||||||
resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt );
|
resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt );
|
||||||
xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt );
|
xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt );
|
||||||
dns->timer.expired = dns_timer_expired;
|
dns->timer.expired = dns_timer_expired;
|
||||||
|
@ -474,7 +510,7 @@ static int dns_resolv ( struct resolv_interface *resolv,
|
||||||
dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
|
dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
|
||||||
DNS_FLAG_RD );
|
DNS_FLAG_RD );
|
||||||
dns->query.dns.qdcount = htons ( 1 );
|
dns->query.dns.qdcount = htons ( 1 );
|
||||||
dns->qinfo = ( void * ) dns_make_name ( name, dns->query.payload );
|
dns->qinfo = ( void * ) dns_make_name ( fqdn, dns->query.payload );
|
||||||
dns->qinfo->qtype = htons ( DNS_TYPE_A );
|
dns->qinfo->qtype = htons ( DNS_TYPE_A );
|
||||||
dns->qinfo->qclass = htons ( DNS_CLASS_IN );
|
dns->qinfo->qclass = htons ( DNS_CLASS_IN );
|
||||||
|
|
||||||
|
@ -484,7 +520,7 @@ static int dns_resolv ( struct resolv_interface *resolv,
|
||||||
NULL ) ) != 0 ) {
|
NULL ) ) != 0 ) {
|
||||||
DBGC ( dns, "DNS %p could not open socket: %s\n",
|
DBGC ( dns, "DNS %p could not open socket: %s\n",
|
||||||
dns, strerror ( rc ) );
|
dns, strerror ( rc ) );
|
||||||
goto err;
|
goto err_open_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send first DNS packet */
|
/* Send first DNS packet */
|
||||||
|
@ -493,10 +529,15 @@ static int dns_resolv ( struct resolv_interface *resolv,
|
||||||
/* Attach parent interface, mortalise self, and return */
|
/* Attach parent interface, mortalise self, and return */
|
||||||
resolv_plug_plug ( &dns->resolv, resolv );
|
resolv_plug_plug ( &dns->resolv, resolv );
|
||||||
ref_put ( &dns->refcnt );
|
ref_put ( &dns->refcnt );
|
||||||
|
free ( fqdn );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err_open_socket:
|
||||||
|
err_alloc_dns:
|
||||||
ref_put ( &dns->refcnt );
|
ref_put ( &dns->refcnt );
|
||||||
|
err_qualify_name:
|
||||||
|
free ( fqdn );
|
||||||
|
err_no_nameserver:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,12 +562,20 @@ struct setting dns_setting __setting = {
|
||||||
.type = &setting_type_ipv4,
|
.type = &setting_type_ipv4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Domain name setting */
|
||||||
|
struct setting domain_setting __setting = {
|
||||||
|
.name = "domain",
|
||||||
|
.description = "Local domain",
|
||||||
|
.tag = DHCP_DOMAIN_NAME,
|
||||||
|
.type = &setting_type_string,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply nameserver setting
|
* Apply DNS settings
|
||||||
*
|
*
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int apply_nameserver_setting ( void ) {
|
static int apply_dns_settings ( void ) {
|
||||||
struct sockaddr_in *sin_nameserver =
|
struct sockaddr_in *sin_nameserver =
|
||||||
( struct sockaddr_in * ) &nameserver;
|
( struct sockaddr_in * ) &nameserver;
|
||||||
int len;
|
int len;
|
||||||
|
@ -538,10 +587,15 @@ static int apply_nameserver_setting ( void ) {
|
||||||
inet_ntoa ( sin_nameserver->sin_addr ) );
|
inet_ntoa ( sin_nameserver->sin_addr ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get local domain DHCP option */
|
||||||
|
if ( ( len = fetch_string_setting_copy ( NULL, &domain_setting,
|
||||||
|
&localdomain ) ) >= 0 )
|
||||||
|
DBG ( "DNS local domain %s\n", localdomain );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Nameserver setting applicator */
|
/** DNS settings applicator */
|
||||||
struct settings_applicator nameserver_applicator __settings_applicator = {
|
struct settings_applicator dns_applicator __settings_applicator = {
|
||||||
.apply = apply_nameserver_setting,
|
.apply = apply_dns_settings,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue