Ver código fonte

[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 anos atrás
pai
commit
d10a7e7739
2 arquivos alterados com 66 adições e 11 exclusões
  1. 1
    0
      src/include/gpxe/settings.h
  2. 65
    11
      src/net/udp/dns.c

+ 1
- 0
src/include/gpxe/settings.h Ver arquivo

218
 extern struct setting netmask_setting __setting;
218
 extern struct setting netmask_setting __setting;
219
 extern struct setting gateway_setting __setting;
219
 extern struct setting gateway_setting __setting;
220
 extern struct setting dns_setting __setting;
220
 extern struct setting dns_setting __setting;
221
+extern struct setting domain_setting __setting;
221
 extern struct setting hostname_setting __setting;
222
 extern struct setting hostname_setting __setting;
222
 extern struct setting filename_setting __setting;
223
 extern struct setting filename_setting __setting;
223
 extern struct setting root_path_setting __setting;
224
 extern struct setting root_path_setting __setting;

+ 65
- 11
src/net/udp/dns.c Ver arquivo

22
 #include <stdint.h>
22
 #include <stdint.h>
23
 #include <stdlib.h>
23
 #include <stdlib.h>
24
 #include <string.h>
24
 #include <string.h>
25
+#include <stdio.h>
25
 #include <errno.h>
26
 #include <errno.h>
26
 #include <byteswap.h>
27
 #include <byteswap.h>
27
 #include <gpxe/refcnt.h>
28
 #include <gpxe/refcnt.h>
47
 	.st_port = htons ( DNS_PORT ),
48
 	.st_port = htons ( DNS_PORT ),
48
 };
49
 };
49
 
50
 
51
+/** The local domain */
52
+static char *localdomain;
53
+
50
 /** A DNS request */
54
 /** A DNS request */
51
 struct dns_request {
55
 struct dns_request {
52
 	/** Reference counter */
56
 	/** Reference counter */
179
 	return NULL;
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
  * Convert a standard NUL-terminated string to a DNS name
208
  * Convert a standard NUL-terminated string to a DNS name
184
  *
209
  *
452
 static int dns_resolv ( struct resolv_interface *resolv,
477
 static int dns_resolv ( struct resolv_interface *resolv,
453
 			const char *name, struct sockaddr *sa ) {
478
 			const char *name, struct sockaddr *sa ) {
454
 	struct dns_request *dns;
479
 	struct dns_request *dns;
480
+	char *fqdn;
455
 	int rc;
481
 	int rc;
456
 
482
 
457
 	/* Fail immediately if no DNS servers */
483
 	/* Fail immediately if no DNS servers */
458
 	if ( ! nameserver.st_family ) {
484
 	if ( ! nameserver.st_family ) {
459
 		DBG ( "DNS not attempting to resolve \"%s\": "
485
 		DBG ( "DNS not attempting to resolve \"%s\": "
460
 		      "no DNS servers\n", name );
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
 	/* Allocate DNS structure */
498
 	/* Allocate DNS structure */
465
 	dns = zalloc ( sizeof ( *dns ) );
499
 	dns = zalloc ( sizeof ( *dns ) );
466
-	if ( ! dns )
467
-		return -ENOMEM;
500
+	if ( ! dns ) {
501
+		rc = -ENOMEM;
502
+		goto err_alloc_dns;
503
+	}
468
 	resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt );
504
 	resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt );
469
 	xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt );
505
 	xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt );
470
 	dns->timer.expired = dns_timer_expired;
506
 	dns->timer.expired = dns_timer_expired;
474
 	dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
510
 	dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
475
 				       DNS_FLAG_RD );
511
 				       DNS_FLAG_RD );
476
 	dns->query.dns.qdcount = htons ( 1 );
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
 	dns->qinfo->qtype = htons ( DNS_TYPE_A );
514
 	dns->qinfo->qtype = htons ( DNS_TYPE_A );
479
 	dns->qinfo->qclass = htons ( DNS_CLASS_IN );
515
 	dns->qinfo->qclass = htons ( DNS_CLASS_IN );
480
 
516
 
484
 				       NULL ) ) != 0 ) {
520
 				       NULL ) ) != 0 ) {
485
 		DBGC ( dns, "DNS %p could not open socket: %s\n",
521
 		DBGC ( dns, "DNS %p could not open socket: %s\n",
486
 		       dns, strerror ( rc ) );
522
 		       dns, strerror ( rc ) );
487
-		goto err;
523
+		goto err_open_socket;
488
 	}
524
 	}
489
 
525
 
490
 	/* Send first DNS packet */
526
 	/* Send first DNS packet */
493
 	/* Attach parent interface, mortalise self, and return */
529
 	/* Attach parent interface, mortalise self, and return */
494
 	resolv_plug_plug ( &dns->resolv, resolv );
530
 	resolv_plug_plug ( &dns->resolv, resolv );
495
 	ref_put ( &dns->refcnt );
531
 	ref_put ( &dns->refcnt );
532
+	free ( fqdn );
496
 	return 0;	
533
 	return 0;	
497
 
534
 
498
- err:
535
+ err_open_socket:
536
+ err_alloc_dns:
499
 	ref_put ( &dns->refcnt );
537
 	ref_put ( &dns->refcnt );
538
+ err_qualify_name:
539
+	free ( fqdn );
540
+ err_no_nameserver:
500
 	return rc;
541
 	return rc;
501
 }
542
 }
502
 
543
 
521
 	.type = &setting_type_ipv4,
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
  * @ret rc		Return status code
576
  * @ret rc		Return status code
528
  */
577
  */
529
-static int apply_nameserver_setting ( void ) {
578
+static int apply_dns_settings ( void ) {
530
 	struct sockaddr_in *sin_nameserver =
579
 	struct sockaddr_in *sin_nameserver =
531
 		( struct sockaddr_in * ) &nameserver;
580
 		( struct sockaddr_in * ) &nameserver;
532
 	int len;
581
 	int len;
538
 		      inet_ntoa ( sin_nameserver->sin_addr ) );
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
 	return 0;
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
 };

Carregando…
Cancelar
Salvar