Browse Source

[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.
tags/v0.9.7
Stefan Hajnoczi 15 years ago
parent
commit
d10a7e7739
2 changed files with 66 additions and 11 deletions
  1. 1
    0
      src/include/gpxe/settings.h
  2. 65
    11
      src/net/udp/dns.c

+ 1
- 0
src/include/gpxe/settings.h View File

@@ -218,6 +218,7 @@ extern struct setting ip_setting __setting;
218 218
 extern struct setting netmask_setting __setting;
219 219
 extern struct setting gateway_setting __setting;
220 220
 extern struct setting dns_setting __setting;
221
+extern struct setting domain_setting __setting;
221 222
 extern struct setting hostname_setting __setting;
222 223
 extern struct setting filename_setting __setting;
223 224
 extern struct setting root_path_setting __setting;

+ 65
- 11
src/net/udp/dns.c View File

@@ -22,6 +22,7 @@
22 22
 #include <stdint.h>
23 23
 #include <stdlib.h>
24 24
 #include <string.h>
25
+#include <stdio.h>
25 26
 #include <errno.h>
26 27
 #include <byteswap.h>
27 28
 #include <gpxe/refcnt.h>
@@ -47,6 +48,9 @@ static struct sockaddr_tcpip nameserver = {
47 48
 	.st_port = htons ( DNS_PORT ),
48 49
 };
49 50
 
51
+/** The local domain */
52
+static char *localdomain;
53
+
50 54
 /** A DNS request */
51 55
 struct dns_request {
52 56
 	/** Reference counter */
@@ -179,6 +183,27 @@ static union dns_rr_info * dns_find_rr ( struct dns_request *dns,
179 183
 	return NULL;
180 184
 }
181 185
 
186
+/**
187
+ * Append DHCP domain name if available and name is not fully qualified
188
+ *
189
+ * @v string		Name as a NUL-terminated string
190
+ * @ret fqdn		Fully-qualified domain name, malloc'd copy
191
+ *
192
+ * The caller must free fqdn which is allocated even if the name is already
193
+ * fully qualified.
194
+ */
195
+static char * dns_qualify_name ( const char *string ) {
196
+	char *fqdn;
197
+
198
+	/* Leave unchanged if already fully-qualified or no local domain */
199
+	if ( ( ! localdomain ) || ( strchr ( string, '.' ) != 0 ) )
200
+		return strdup ( string );
201
+
202
+	/* Append local domain to name */
203
+	asprintf ( &fqdn, "%s.%s", string, localdomain );
204
+	return fqdn;
205
+}
206
+
182 207
 /**
183 208
  * Convert a standard NUL-terminated string to a DNS name
184 209
  *
@@ -452,19 +477,30 @@ static struct xfer_interface_operations dns_socket_operations = {
452 477
 static int dns_resolv ( struct resolv_interface *resolv,
453 478
 			const char *name, struct sockaddr *sa ) {
454 479
 	struct dns_request *dns;
480
+	char *fqdn;
455 481
 	int rc;
456 482
 
457 483
 	/* Fail immediately if no DNS servers */
458 484
 	if ( ! nameserver.st_family ) {
459 485
 		DBG ( "DNS not attempting to resolve \"%s\": "
460 486
 		      "no DNS servers\n", name );
461
-		return -ENXIO;
487
+		rc = -ENXIO;
488
+		goto err_no_nameserver;
489
+	}
490
+
491
+	/* Ensure fully-qualified domain name if DHCP option was given */
492
+	fqdn = dns_qualify_name ( name );
493
+	if ( ! fqdn ) {
494
+		rc = -ENOMEM;
495
+		goto err_qualify_name;
462 496
 	}
463 497
 
464 498
 	/* Allocate DNS structure */
465 499
 	dns = zalloc ( sizeof ( *dns ) );
466
-	if ( ! dns )
467
-		return -ENOMEM;
500
+	if ( ! dns ) {
501
+		rc = -ENOMEM;
502
+		goto err_alloc_dns;
503
+	}
468 504
 	resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt );
469 505
 	xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt );
470 506
 	dns->timer.expired = dns_timer_expired;
@@ -474,7 +510,7 @@ static int dns_resolv ( struct resolv_interface *resolv,
474 510
 	dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
475 511
 				       DNS_FLAG_RD );
476 512
 	dns->query.dns.qdcount = htons ( 1 );
477
-	dns->qinfo = ( void * ) dns_make_name ( name, dns->query.payload );
513
+	dns->qinfo = ( void * ) dns_make_name ( fqdn, dns->query.payload );
478 514
 	dns->qinfo->qtype = htons ( DNS_TYPE_A );
479 515
 	dns->qinfo->qclass = htons ( DNS_CLASS_IN );
480 516
 
@@ -484,7 +520,7 @@ static int dns_resolv ( struct resolv_interface *resolv,
484 520
 				       NULL ) ) != 0 ) {
485 521
 		DBGC ( dns, "DNS %p could not open socket: %s\n",
486 522
 		       dns, strerror ( rc ) );
487
-		goto err;
523
+		goto err_open_socket;
488 524
 	}
489 525
 
490 526
 	/* Send first DNS packet */
@@ -493,10 +529,15 @@ static int dns_resolv ( struct resolv_interface *resolv,
493 529
 	/* Attach parent interface, mortalise self, and return */
494 530
 	resolv_plug_plug ( &dns->resolv, resolv );
495 531
 	ref_put ( &dns->refcnt );
532
+	free ( fqdn );
496 533
 	return 0;	
497 534
 
498
- err:
535
+ err_open_socket:
536
+ err_alloc_dns:
499 537
 	ref_put ( &dns->refcnt );
538
+ err_qualify_name:
539
+	free ( fqdn );
540
+ err_no_nameserver:
500 541
 	return rc;
501 542
 }
502 543
 
@@ -521,12 +562,20 @@ struct setting dns_setting __setting = {
521 562
 	.type = &setting_type_ipv4,
522 563
 };
523 564
 
565
+/** Domain name setting */
566
+struct setting domain_setting __setting = {
567
+	.name = "domain",
568
+	.description = "Local domain",
569
+	.tag = DHCP_DOMAIN_NAME,
570
+	.type = &setting_type_string,
571
+};
572
+
524 573
 /**
525
- * Apply nameserver setting
574
+ * Apply DNS settings
526 575
  *
527 576
  * @ret rc		Return status code
528 577
  */
529
-static int apply_nameserver_setting ( void ) {
578
+static int apply_dns_settings ( void ) {
530 579
 	struct sockaddr_in *sin_nameserver =
531 580
 		( struct sockaddr_in * ) &nameserver;
532 581
 	int len;
@@ -538,10 +587,15 @@ static int apply_nameserver_setting ( void ) {
538 587
 		      inet_ntoa ( sin_nameserver->sin_addr ) );
539 588
 	}
540 589
 
590
+	/* Get local domain DHCP option */
591
+	if ( ( len = fetch_string_setting_copy ( NULL, &domain_setting,
592
+						 &localdomain ) ) >= 0 )
593
+		DBG ( "DNS local domain %s\n", localdomain );
594
+
541 595
 	return 0;
542 596
 }
543 597
 
544
-/** Nameserver setting applicator */
545
-struct settings_applicator nameserver_applicator __settings_applicator = {
546
-	.apply = apply_nameserver_setting,
598
+/** DNS settings applicator */
599
+struct settings_applicator dns_applicator __settings_applicator = {
600
+	.apply = apply_dns_settings,
547 601
 };

Loading…
Cancel
Save