Browse Source

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

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
f87bc837f4
3 changed files with 122 additions and 127 deletions
  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 View File

9
 
9
 
10
 #include <stdint.h>
10
 #include <stdint.h>
11
 #include <gpxe/in.h>
11
 #include <gpxe/in.h>
12
-#include <gpxe/async.h>
13
-#include <gpxe/retry.h>
14
 
12
 
15
 /*
13
 /*
16
  * Constants
14
  * Constants
89
 	struct dns_rr_info_cname cname;
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
 #endif /* _GPXE_DNS_H */
92
 #endif /* _GPXE_DNS_H */

+ 7
- 0
src/include/gpxe/resolv.h View File

153
 #define __resolver( resolv_order ) \
153
 #define __resolver( resolv_order ) \
154
 	__table ( struct resolver, resolvers, resolv_order )
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
 extern int resolv ( struct resolv_interface *resolv, const char *name,
163
 extern int resolv ( struct resolv_interface *resolv, const char *name,
157
 		    struct sockaddr *sa );
164
 		    struct sockaddr *sa );
158
 
165
 

+ 114
- 101
src/net/udp/dns.c View File

24
 #include <string.h>
24
 #include <string.h>
25
 #include <errno.h>
25
 #include <errno.h>
26
 #include <byteswap.h>
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
 #include <gpxe/resolv.h>
30
 #include <gpxe/resolv.h>
31
+#include <gpxe/retry.h>
32
+#include <gpxe/tcpip.h>
30
 #include <gpxe/dns.h>
33
 #include <gpxe/dns.h>
31
 
34
 
32
 /** @file
35
 /** @file
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
  * Compare DNS reply name against the query name from the original request
91
  * Compare DNS reply name against the query name from the original request
47
  * @ret	zero		Names match
96
  * @ret	zero		Names match
48
  * @ret non-zero	Names do not match
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
 			  const char *rname ) {
101
 			  const char *rname ) {
52
 	const char *qname = dns->query.payload;
102
 	const char *qname = dns->query.payload;
53
 	int i;
103
 	int i;
101
  * @ret rr		DNS RR, or NULL if not found
151
  * @ret rr		DNS RR, or NULL if not found
102
  */
152
  */
103
 static union dns_rr_info * dns_find_rr ( struct dns_request *dns,
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
 	int i, cmp;
155
 	int i, cmp;
106
 	const char *p = ( ( char * ) reply ) + sizeof ( struct dns_header );
156
 	const char *p = ( ( char * ) reply ) + sizeof ( struct dns_header );
107
 	union dns_rr_info *rr_info;
157
 	union dns_rr_info *rr_info;
179
  * @v buf		Buffer into which to decompress DNS name
229
  * @v buf		Buffer into which to decompress DNS name
180
  * @ret next		Byte following decompressed DNS name
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
 				    const char *name, char *buf ) {
233
 				    const char *name, char *buf ) {
184
 	int i, len;
234
 	int i, len;
185
 
235
 
198
 	return buf;
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
  * Send next packet in DNS request
252
  * Send next packet in DNS request
221
  *
253
  *
222
  * @v dns		DNS request
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
 	static unsigned int qid = 0;
257
 	static unsigned int qid = 0;
258
+	size_t qlen;
226
 
259
 
227
 	/* Increment query ID */
260
 	/* Increment query ID */
228
 	dns->query.dns.id = htons ( ++qid );
261
 	dns->query.dns.id = htons ( ++qid );
233
 	start_timer ( &dns->timer );
266
 	start_timer ( &dns->timer );
234
 
267
 
235
 	/* Send the data */
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
 /**
291
 /**
259
  * Receive new data
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
 	struct dns_request *dns =
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
 	union dns_rr_info *rr_info;
304
 	union dns_rr_info *rr_info;
274
 	struct sockaddr_in *sin;
305
 	struct sockaddr_in *sin;
275
 	unsigned int qtype = dns->qinfo->qtype;
306
 	unsigned int qtype = dns->qinfo->qtype;
311
 			/* Found the target A record */
342
 			/* Found the target A record */
312
 			DBGC ( dns, "DNS %p found address %s\n",
343
 			DBGC ( dns, "DNS %p found address %s\n",
313
 			       dns, inet_ntoa ( rr_info->a.in_addr ) );
344
 			       dns, inet_ntoa ( rr_info->a.in_addr ) );
314
-			sin = ( struct sockaddr_in * ) dns->sa;
345
+			sin = ( struct sockaddr_in * ) &dns->sa;
315
 			sin->sin_family = AF_INET;
346
 			sin->sin_family = AF_INET;
316
 			sin->sin_addr = rr_info->a.in_addr;
347
 			sin->sin_addr = rr_info->a.in_addr;
317
 
348
 
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
 	struct dns_request *dns =
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
  * Resolve name using DNS
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
  * @v sa		Socket address to fill in
446
  * @v sa		Socket address to fill in
425
- * @v parent		Parent asynchronous operation
426
  * @ret rc		Return status code
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
 	struct dns_request *dns;
451
 	struct dns_request *dns;
431
-	union {
432
-		struct sockaddr_tcpip st;
433
-		struct sockaddr_in sin;
434
-	} server;
435
 	int rc;
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
 	/* Allocate DNS structure */
461
 	/* Allocate DNS structure */
438
 	dns = malloc ( sizeof ( *dns ) );
462
 	dns = malloc ( sizeof ( *dns ) );
439
-	if ( ! dns ) {
440
-		rc = -ENOMEM;
441
-		goto err;
442
-	}
463
+	if ( ! dns )
464
+		return -ENOMEM;
443
 	memset ( dns, 0, sizeof ( *dns ) );
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
 	dns->timer.expired = dns_timer_expired;
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
 	/* Create query */
471
 	/* Create query */
450
 	dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
472
 	dns->query.dns.flags = htons ( DNS_FLAG_QUERY | DNS_FLAG_OPCODE_QUERY |
454
 	dns->qinfo->qtype = htons ( DNS_TYPE_A );
476
 	dns->qinfo->qtype = htons ( DNS_TYPE_A );
455
 	dns->qinfo->qclass = htons ( DNS_CLASS_IN );
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
 	/* Open UDP connection */
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
 		goto err;
485
 		goto err;
486
+	}
474
 
487
 
475
 	/* Send first DNS packet */
488
 	/* Send first DNS packet */
476
 	dns_send_packet ( dns );
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
 	return 0;	
494
 	return 0;	
479
 
495
 
480
  err:
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
 	return rc;
498
 	return rc;
486
 }
499
 }
487
 
500
 

Loading…
Cancel
Save