Просмотр исходного кода

Updated DNS to use not-yet-implemented UDP data-xfer API.

tags/v0.9.3
Michael Brown 17 лет назад
Родитель
Сommit
f87bc837f4
3 измененных файлов: 122 добавлений и 127 удалений
  1. 1
    26
      src/include/gpxe/dns.h
  2. 7
    0
      src/include/gpxe/resolv.h
  3. 114
    101
      src/net/udp/dns.c

+ 1
- 26
src/include/gpxe/dns.h Просмотреть файл

@@ -9,8 +9,6 @@
9 9
 
10 10
 #include <stdint.h>
11 11
 #include <gpxe/in.h>
12
-#include <gpxe/async.h>
13
-#include <gpxe/retry.h>
14 12
 
15 13
 /*
16 14
  * Constants
@@ -89,29 +87,6 @@ union dns_rr_info {
89 87
 	struct dns_rr_info_cname cname;
90 88
 };
91 89
 
92
-/** A DNS request */
93
-struct dns_request {
94
-	/** Socket address to fill in with resolved address */
95
-	struct sockaddr *sa;
96
-
97
-	/** Current query packet */
98
-	struct dns_query query;
99
-	/** Length of current query packet */
100
-	struct dns_query_info *qinfo;
101
-	/** Recursion counter */
102
-	unsigned int recursion;
103
-
104
-	/** Asynchronous operation */
105
-	struct async async;
106
-	/** UDP connection */
107
-	struct udp_connection udp;
108
-	/** Retry timer */
109
-	struct retry_timer timer;
110
-};
111
-
112
-extern struct in_addr nameserver;
113
-
114
-extern int dns_resolv ( const char *name, struct sockaddr *sa,
115
-			struct async *parent );
90
+extern struct sockaddr_tcpip nameserver;
116 91
 
117 92
 #endif /* _GPXE_DNS_H */

+ 7
- 0
src/include/gpxe/resolv.h Просмотреть файл

@@ -153,6 +153,13 @@ struct resolver {
153 153
 #define __resolver( resolv_order ) \
154 154
 	__table ( struct resolver, resolvers, resolv_order )
155 155
 
156
+extern void resolv_done ( struct resolv_interface *resolv,
157
+			  struct sockaddr *sa, int rc );
158
+extern void ignore_resolv_done ( struct resolv_interface *resolv,
159
+			  struct sockaddr *sa, int rc );
160
+extern struct resolv_interface_operations null_resolv_ops;
161
+struct resolv_interface null_resolv;
162
+
156 163
 extern int resolv ( struct resolv_interface *resolv, const char *name,
157 164
 		    struct sockaddr *sa );
158 165
 

+ 114
- 101
src/net/udp/dns.c Просмотреть файл

@@ -24,9 +24,12 @@
24 24
 #include <string.h>
25 25
 #include <errno.h>
26 26
 #include <byteswap.h>
27
-#include <gpxe/async.h>
28
-#include <gpxe/udp.h>
27
+#include <gpxe/refcnt.h>
28
+#include <gpxe/xfer.h>
29
+#include <gpxe/open.h>
29 30
 #include <gpxe/resolv.h>
31
+#include <gpxe/retry.h>
32
+#include <gpxe/tcpip.h>
30 33
 #include <gpxe/dns.h>
31 34
 
32 35
 /** @file
@@ -35,8 +38,54 @@
35 38
  *
36 39
  */
37 40
 
38
-/* The DNS server */
39
-struct in_addr nameserver = { INADDR_NONE };
41
+/** The DNS server */
42
+struct sockaddr_tcpip nameserver = {
43
+	.st_port = htons ( DNS_PORT ),
44
+};
45
+
46
+/** A DNS request */
47
+struct dns_request {
48
+	/** Reference counter */
49
+	struct refcnt refcnt;
50
+	/** Name resolution interface */
51
+	struct resolv_interface resolv;
52
+	/** Data transfer interface */
53
+	struct xfer_interface socket;
54
+	/** Retry timer */
55
+	struct retry_timer timer;
56
+
57
+	/** Socket address to fill in with resolved address */
58
+	struct sockaddr sa;
59
+	/** Current query packet */
60
+	struct dns_query query;
61
+	/** Location of query info structure within current packet
62
+	 *
63
+	 * The query info structure is located immediately after the
64
+	 * compressed name.
65
+	 */
66
+	struct dns_query_info *qinfo;
67
+	/** Recursion counter */
68
+	unsigned int recursion;
69
+};
70
+
71
+/**
72
+ * Mark DNS request as complete
73
+ *
74
+ * @v dns		DNS request
75
+ * @v rc		Return status code
76
+ */
77
+static void dns_done ( struct dns_request *dns, int rc ) {
78
+
79
+	/* Stop the retry timer */
80
+	stop_timer ( &dns->timer );
81
+
82
+	/* Close data transfer interface */
83
+	xfer_nullify ( &dns->socket );
84
+	xfer_close ( &dns->socket, rc );
85
+
86
+	/* Mark name resolution as complete */
87
+	resolv_done ( &dns->resolv, &dns->sa, rc );
88
+}
40 89
 
41 90
 /**
42 91
  * Compare DNS reply name against the query name from the original request
@@ -47,7 +96,8 @@ struct in_addr nameserver = { INADDR_NONE };
47 96
  * @ret	zero		Names match
48 97
  * @ret non-zero	Names do not match
49 98
  */
50
-static int dns_name_cmp ( struct dns_request *dns, struct dns_header *reply, 
99
+static int dns_name_cmp ( struct dns_request *dns,
100
+			  const struct dns_header *reply, 
51 101
 			  const char *rname ) {
52 102
 	const char *qname = dns->query.payload;
53 103
 	int i;
@@ -101,7 +151,7 @@ static const char * dns_skip_name ( const char *name ) {
101 151
  * @ret rr		DNS RR, or NULL if not found
102 152
  */
103 153
 static union dns_rr_info * dns_find_rr ( struct dns_request *dns,
104
-					 struct dns_header *reply ) {
154
+					 const struct dns_header *reply ) {
105 155
 	int i, cmp;
106 156
 	const char *p = ( ( char * ) reply ) + sizeof ( struct dns_header );
107 157
 	union dns_rr_info *rr_info;
@@ -179,7 +229,7 @@ static inline char * dns_unmake_name ( char *name ) {
179 229
  * @v buf		Buffer into which to decompress DNS name
180 230
  * @ret next		Byte following decompressed DNS name
181 231
  */
182
-static char * dns_decompress_name ( struct dns_header *reply,
232
+static char * dns_decompress_name ( const struct dns_header *reply,
183 233
 				    const char *name, char *buf ) {
184 234
 	int i, len;
185 235
 
@@ -198,31 +248,14 @@ static char * dns_decompress_name ( struct dns_header *reply,
198 248
 	return buf;
199 249
 }
200 250
 
201
-/**
202
- * Mark DNS request as complete
203
- *
204
- * @v dns		DNS request
205
- * @v rc		Return status code
206
- */
207
-static void dns_done ( struct dns_request *dns, int rc ) {
208
-
209
-	/* Stop the retry timer */
210
-	stop_timer ( &dns->timer );
211
-
212
-	/* Close UDP connection */
213
-	udp_close ( &dns->udp );
214
-
215
-	/* Mark async operation as complete */
216
-	async_done ( &dns->async, rc );
217
-}
218
-
219 251
 /**
220 252
  * Send next packet in DNS request
221 253
  *
222 254
  * @v dns		DNS request
223 255
  */
224
-static void dns_send_packet ( struct dns_request *dns ) {
256
+static int dns_send_packet ( struct dns_request *dns ) {
225 257
 	static unsigned int qid = 0;
258
+	size_t qlen;
226 259
 
227 260
 	/* Increment query ID */
228 261
 	dns->query.dns.id = htons ( ++qid );
@@ -233,9 +266,9 @@ static void dns_send_packet ( struct dns_request *dns ) {
233 266
 	start_timer ( &dns->timer );
234 267
 
235 268
 	/* Send the data */
236
-	udp_send ( &dns->udp, &dns->query,
237
-		   ( ( ( void * ) dns->qinfo ) - ( ( void * ) &dns->query )
238
-		     + sizeof ( dns->qinfo ) ) );
269
+	qlen = ( ( ( void * ) dns->qinfo ) - ( ( void * ) &dns->query )
270
+		 + sizeof ( dns->qinfo ) );
271
+	return xfer_deliver_raw ( &dns->socket, &dns->query, qlen );
239 272
 }
240 273
 
241 274
 /**
@@ -258,18 +291,16 @@ static void dns_timer_expired ( struct retry_timer *timer, int fail ) {
258 291
 /**
259 292
  * Receive new data
260 293
  *
261
- * @v udp		UDP connection
262
- * @v data		Received data
263
- * @v len		Length of received data
264
- * @v st_src		Partially-filled source address
265
- * @v st_dest		Partially-filled destination address
294
+ * @v socket		UDP socket
295
+ * @v data		DNS reply
296
+ * @v len		Length of DNS reply
297
+ * @ret rc		Return status code
266 298
  */
267
-static int dns_newdata ( struct udp_connection *conn, void *data, size_t len,
268
-			 struct sockaddr_tcpip *st_src __unused,
269
-			 struct sockaddr_tcpip *st_dest __unused ) {
299
+static int dns_xfer_deliver_raw ( struct xfer_interface *socket,
300
+				  const void *data, size_t len ) {
270 301
 	struct dns_request *dns =
271
-		container_of ( conn, struct dns_request, udp );
272
-	struct dns_header *reply = data;
302
+		container_of ( socket, struct dns_request, socket );
303
+	const struct dns_header *reply = data;
273 304
 	union dns_rr_info *rr_info;
274 305
 	struct sockaddr_in *sin;
275 306
 	unsigned int qtype = dns->qinfo->qtype;
@@ -311,7 +342,7 @@ static int dns_newdata ( struct udp_connection *conn, void *data, size_t len,
311 342
 			/* Found the target A record */
312 343
 			DBGC ( dns, "DNS %p found address %s\n",
313 344
 			       dns, inet_ntoa ( rr_info->a.in_addr ) );
314
-			sin = ( struct sockaddr_in * ) dns->sa;
345
+			sin = ( struct sockaddr_in * ) &dns->sa;
315 346
 			sin->sin_family = AF_INET;
316 347
 			sin->sin_addr = rr_info->a.in_addr;
317 348
 
@@ -380,71 +411,62 @@ static int dns_newdata ( struct udp_connection *conn, void *data, size_t len,
380 411
 	}
381 412
 }
382 413
 
383
-/** DNS UDP operations */
384
-struct udp_operations dns_udp_operations = {
385
-	.newdata = dns_newdata,
386
-};
387
-
388 414
 /**
389
- * Reap asynchronous operation
415
+ * Receive new data
390 416
  *
391
- * @v async		Asynchronous operation
417
+ * @v socket		UDP socket
418
+ * @v rc		Reason for close
392 419
  */
393
-static void dns_reap ( struct async *async ) {
420
+static void dns_xfer_close ( struct xfer_interface *socket, int rc ) {
394 421
 	struct dns_request *dns =
395
-		container_of ( async, struct dns_request, async );
422
+		container_of ( socket, struct dns_request, socket );
396 423
 
397
-	free ( dns );
398
-}
424
+	if ( ! rc )
425
+		rc = -ECONNABORTED;
399 426
 
400
-/**
401
- * Handle SIGKILL
402
- *
403
- * @v async		Asynchronous operation
404
- */
405
-static void dns_sigkill ( struct async *async, enum signal signal __unused ) {
406
-	struct dns_request *dns =
407
-		container_of ( async, struct dns_request, async );
408
-
409
-	dns_done ( dns, -ECANCELED );
427
+	dns_done ( dns, rc );
410 428
 }
411 429
 
412
-/** DNS asynchronous operations */
413
-static struct async_operations dns_async_operations = {
414
-	.reap = dns_reap,
415
-	.signal = {
416
-		[SIGKILL] = dns_sigkill,
417
-	},
430
+/** DNS socket operations */
431
+static struct xfer_interface_operations dns_socket_operations = {
432
+	.close		= dns_xfer_close,
433
+	.vredirect	= xfer_vopen,
434
+	.request	= ignore_xfer_request,
435
+	.seek		= ignore_xfer_seek,
436
+	.alloc_iob	= default_xfer_alloc_iob,
437
+	.deliver_iob	= xfer_deliver_as_raw,
438
+	.deliver_raw	= dns_xfer_deliver_raw,
418 439
 };
419 440
 
420 441
 /**
421 442
  * Resolve name using DNS
422 443
  *
423
- * @v name		Host name to resolve
444
+ * @v resolv		Name resolution interface
445
+ * @v name		Name to resolve
424 446
  * @v sa		Socket address to fill in
425
- * @v parent		Parent asynchronous operation
426 447
  * @ret rc		Return status code
427 448
  */
428
-int dns_resolv ( const char *name, struct sockaddr *sa,
429
-		 struct async *parent ) {
449
+static int dns_resolv ( struct resolv_interface *resolv,
450
+			const char *name, struct sockaddr *sa ) {
430 451
 	struct dns_request *dns;
431
-	union {
432
-		struct sockaddr_tcpip st;
433
-		struct sockaddr_in sin;
434
-	} server;
435 452
 	int rc;
436 453
 
454
+	/* Fail immediately if no DNS servers */
455
+	if ( ! nameserver.st_family ) {
456
+		DBG ( "DNS not attempting to resolve \"%s\": "
457
+		      "no DNS servers\n", name );
458
+		return -ENXIO;
459
+	}
460
+
437 461
 	/* Allocate DNS structure */
438 462
 	dns = malloc ( sizeof ( *dns ) );
439
-	if ( ! dns ) {
440
-		rc = -ENOMEM;
441
-		goto err;
442
-	}
463
+	if ( ! dns )
464
+		return -ENOMEM;
443 465
 	memset ( dns, 0, sizeof ( *dns ) );
444
-	dns->sa = sa;
466
+	resolv_init ( &dns->resolv, &null_resolv_ops, &dns->refcnt );
467
+	xfer_init ( &dns->socket, &dns_socket_operations, &dns->refcnt );
445 468
 	dns->timer.expired = dns_timer_expired;
446
-	dns->udp.udp_op = &dns_udp_operations;
447
-	async_init ( &dns->async, &dns_async_operations, parent );
469
+	memcpy ( &dns->sa, sa, sizeof ( dns->sa ) );
448 470
 
449 471
 	/* Create query */
450 472
 	dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
@@ -454,34 +476,25 @@ int dns_resolv ( const char *name, struct sockaddr *sa,
454 476
 	dns->qinfo->qtype = htons ( DNS_TYPE_A );
455 477
 	dns->qinfo->qclass = htons ( DNS_CLASS_IN );
456 478
 
457
-	/* Identify nameserver */
458
-	memset ( &server, 0, sizeof ( server ) );
459
-	server.sin.sin_family = AF_INET;
460
-	server.sin.sin_port = htons ( DNS_PORT );
461
-	server.sin.sin_addr = nameserver;
462
-	if ( server.sin.sin_addr.s_addr == INADDR_NONE ) {
463
-		DBGC ( dns, "DNS %p no name servers\n", dns );
464
-		rc = -ENXIO;
465
-		goto err;
466
-	}
467
-
468 479
 	/* Open UDP connection */
469
-	DBGC ( dns, "DNS %p using nameserver %s\n", dns, 
470
-	       inet_ntoa ( server.sin.sin_addr ) );
471
-	udp_connect ( &dns->udp, &server.st );
472
-	if ( ( rc = udp_open ( &dns->udp, 0 ) ) != 0 )
480
+	if ( ( rc = xfer_open_socket ( &dns->socket, SOCK_DGRAM,
481
+				       ( struct sockaddr * ) &nameserver,
482
+				       NULL ) ) != 0 ) {
483
+		DBGC ( dns, "DNS %p could not open socket: %s\n",
484
+		       dns, strerror ( rc ) );
473 485
 		goto err;
486
+	}
474 487
 
475 488
 	/* Send first DNS packet */
476 489
 	dns_send_packet ( dns );
477 490
 
491
+	/* Attach parent interface, mortalise self, and return */
492
+	resolv_plug_plug ( &dns->resolv, resolv );
493
+	ref_put ( &dns->refcnt );
478 494
 	return 0;	
479 495
 
480 496
  err:
481
-	DBGC ( dns, "DNS %p could not create request: %s\n", 
482
-	       dns, strerror ( rc ) );
483
-	async_uninit ( &dns->async );
484
-	free ( dns );
497
+	ref_put ( &dns->refcnt );
485 498
 	return rc;
486 499
 }
487 500
 

Загрузка…
Отмена
Сохранить