These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / core / resolv.c
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <ipxe/xfer.h>
31 #include <ipxe/open.h>
32 #include <ipxe/process.h>
33 #include <ipxe/socket.h>
34 #include <ipxe/resolv.h>
35
36 /** @file
37  *
38  * Name resolution
39  *
40  */
41
42 /***************************************************************************
43  *
44  * Name resolution interfaces
45  *
46  ***************************************************************************
47  */
48
49 /**
50  * Name resolved
51  *
52  * @v intf              Object interface
53  * @v sa                Completed socket address (if successful)
54  */
55 void resolv_done ( struct interface *intf, struct sockaddr *sa ) {
56         struct interface *dest;
57         resolv_done_TYPE ( void * ) *op =
58                 intf_get_dest_op ( intf, resolv_done, &dest );
59         void *object = intf_object ( dest );
60
61         DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " resolv_done\n",
62                INTF_INTF_DBG ( intf, dest ) );
63
64         if ( op ) {
65                 op ( object, sa );
66         } else {
67                 /* Default is to ignore resolutions */
68         }
69
70         intf_put ( dest );
71 }
72
73 /***************************************************************************
74  *
75  * Numeric name resolver
76  *
77  ***************************************************************************
78  */
79
80 /** A numeric name resolver */
81 struct numeric_resolv {
82         /** Reference counter */
83         struct refcnt refcnt;
84         /** Name resolution interface */
85         struct interface resolv;
86         /** Process */
87         struct process process;
88         /** Completed socket address */
89         struct sockaddr sa;
90         /** Overall status code */
91         int rc;
92 };
93
94 static void numeric_step ( struct numeric_resolv *numeric ) {
95
96         if ( numeric->rc == 0 )
97                 resolv_done ( &numeric->resolv, &numeric->sa );
98         intf_shutdown ( &numeric->resolv, numeric->rc );
99 }
100
101 static struct process_descriptor numeric_process_desc =
102         PROC_DESC_ONCE ( struct numeric_resolv, process, numeric_step );
103
104 static int numeric_resolv ( struct interface *resolv,
105                             const char *name, struct sockaddr *sa ) {
106         struct numeric_resolv *numeric;
107
108         /* Allocate and initialise structure */
109         numeric = zalloc ( sizeof ( *numeric ) );
110         if ( ! numeric )
111                 return -ENOMEM;
112         ref_init ( &numeric->refcnt, NULL );
113         intf_init ( &numeric->resolv, &null_intf_desc, &numeric->refcnt );
114         process_init ( &numeric->process, &numeric_process_desc,
115                        &numeric->refcnt );
116         memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) );
117
118         /* Attempt to resolve name */
119         numeric->rc = sock_aton ( name, &numeric->sa );
120
121         /* Attach to parent interface, mortalise self, and return */
122         intf_plug_plug ( &numeric->resolv, resolv );
123         ref_put ( &numeric->refcnt );
124         return 0;
125 }
126
127 struct resolver numeric_resolver __resolver ( RESOLV_NUMERIC ) = {
128         .name = "NUMERIC",
129         .resolv = numeric_resolv,
130 };
131
132 /***************************************************************************
133  *
134  * Name resolution multiplexer
135  *
136  ***************************************************************************
137  */
138
139 /** A name resolution multiplexer */
140 struct resolv_mux {
141         /** Reference counter */
142         struct refcnt refcnt;
143         /** Parent name resolution interface */
144         struct interface parent;
145
146         /** Child name resolution interface */
147         struct interface child;
148         /** Current child resolver */
149         struct resolver *resolver;
150
151         /** Socket address to complete */
152         struct sockaddr sa;
153         /** Name to be resolved
154          *
155          * Must be at end of structure
156          */
157         char name[0];
158 };
159
160 /**
161  * Try current child name resolver
162  *
163  * @v mux               Name resolution multiplexer
164  * @ret rc              Return status code
165  */
166 static int resmux_try ( struct resolv_mux *mux ) {
167         struct resolver *resolver = mux->resolver;
168         int rc;
169
170         DBGC ( mux, "RESOLV %p trying method %s\n", mux, resolver->name );
171
172         if ( ( rc = resolver->resolv ( &mux->child, mux->name,
173                                        &mux->sa ) ) != 0 ) {
174                 DBGC ( mux, "RESOLV %p could not use method %s: %s\n",
175                        mux, resolver->name, strerror ( rc ) );
176                 return rc;
177         }
178
179         return 0;
180 }
181
182 /**
183  * Child resolved name
184  *
185  * @v mux               Name resolution multiplexer
186  * @v sa                Completed socket address
187  */
188 static void resmux_child_resolv_done ( struct resolv_mux *mux,
189                                        struct sockaddr *sa ) {
190
191         DBGC ( mux, "RESOLV %p resolved \"%s\" to %s using method %s\n",
192                mux, mux->name, sock_ntoa ( sa ), mux->resolver->name );
193
194         /* Pass resolution to parent */
195         resolv_done ( &mux->parent, sa );
196 }
197
198 /**
199  * Child finished resolution
200  *
201  * @v mux               Name resolution multiplexer
202  * @v rc                Return status code
203  */
204 static void resmux_child_close ( struct resolv_mux *mux, int rc ) {
205
206         /* Restart child interface */
207         intf_restart ( &mux->child, rc );
208
209         /* If this resolution succeeded, stop now */
210         if ( rc == 0 ) {
211                 DBGC ( mux, "RESOLV %p succeeded using method %s\n",
212                        mux, mux->resolver->name );
213                 goto finished;
214         }
215
216         /* Attempt next child resolver, if possible */
217         mux->resolver++;
218         if ( mux->resolver >= table_end ( RESOLVERS ) ) {
219                 DBGC ( mux, "RESOLV %p failed to resolve name\n", mux );
220                 goto finished;
221         }
222         if ( ( rc = resmux_try ( mux ) ) != 0 )
223                 goto finished;
224
225         /* Next resolver is now running */
226         return;
227
228  finished:
229         intf_shutdown ( &mux->parent, rc );
230 }
231
232 /** Name resolution multiplexer child interface operations */
233 static struct interface_operation resmux_child_op[] = {
234         INTF_OP ( resolv_done, struct resolv_mux *, resmux_child_resolv_done ),
235         INTF_OP ( intf_close, struct resolv_mux *, resmux_child_close ),
236 };
237
238 /** Name resolution multiplexer child interface descriptor */
239 static struct interface_descriptor resmux_child_desc =
240         INTF_DESC ( struct resolv_mux, child, resmux_child_op );
241
242 /**
243  * Start name resolution
244  *
245  * @v resolv            Name resolution interface
246  * @v name              Name to resolve
247  * @v sa                Socket address to complete
248  * @ret rc              Return status code
249  */
250 int resolv ( struct interface *resolv, const char *name,
251              struct sockaddr *sa ) {
252         struct resolv_mux *mux;
253         size_t name_len = ( strlen ( name ) + 1 );
254         int rc;
255
256         /* Allocate and initialise structure */
257         mux = zalloc ( sizeof ( *mux ) + name_len );
258         if ( ! mux )
259                 return -ENOMEM;
260         ref_init ( &mux->refcnt, NULL );
261         intf_init ( &mux->parent, &null_intf_desc, &mux->refcnt );
262         intf_init ( &mux->child, &resmux_child_desc, &mux->refcnt );
263         mux->resolver = table_start ( RESOLVERS );
264         if ( sa )
265                 memcpy ( &mux->sa, sa, sizeof ( mux->sa ) );
266         memcpy ( mux->name, name, name_len );
267
268         DBGC ( mux, "RESOLV %p attempting to resolve \"%s\"\n", mux, name );
269
270         /* Start first resolver in chain.  There will always be at
271          * least one resolver (the numeric resolver), so no need to
272          * check for the zero-resolvers-available case.
273          */
274         if ( ( rc = resmux_try ( mux ) ) != 0 )
275                 goto err;
276
277         /* Attach parent interface, mortalise self, and return */
278         intf_plug_plug ( &mux->parent, resolv );
279         ref_put ( &mux->refcnt );
280         return 0;
281
282  err:
283         ref_put ( &mux->refcnt );
284         return rc;      
285 }
286
287 /***************************************************************************
288  *
289  * Named socket opening
290  *
291  ***************************************************************************
292  */
293
294 /** A named socket */
295 struct named_socket {
296         /** Reference counter */
297         struct refcnt refcnt;
298         /** Data transfer interface */
299         struct interface xfer;
300         /** Name resolution interface */
301         struct interface resolv;
302         /** Communication semantics (e.g. SOCK_STREAM) */
303         int semantics;
304         /** Stored local socket address, if applicable */
305         struct sockaddr local;
306         /** Stored local socket address exists */
307         int have_local;
308 };
309
310 /**
311  * Terminate named socket opener
312  *
313  * @v named             Named socket
314  * @v rc                Reason for termination
315  */
316 static void named_close ( struct named_socket *named, int rc ) {
317         /* Shut down interfaces */
318         intf_shutdown ( &named->resolv, rc );
319         intf_shutdown ( &named->xfer, rc );
320 }
321
322 /**
323  * Check flow control window
324  *
325  * @v named             Named socket
326  * @ret len             Length of window
327  */
328 static size_t named_window ( struct named_socket *named __unused ) {
329         /* Not ready for data until we have redirected away */
330         return 0;
331 }
332
333 /** Named socket opener data transfer interface operations */
334 static struct interface_operation named_xfer_ops[] = {
335         INTF_OP ( xfer_window, struct named_socket *, named_window ),
336         INTF_OP ( intf_close, struct named_socket *, named_close ),
337 };
338
339 /** Named socket opener data transfer interface descriptor */
340 static struct interface_descriptor named_xfer_desc =
341         INTF_DESC ( struct named_socket, xfer, named_xfer_ops );
342
343 /**
344  * Name resolved
345  *
346  * @v named             Named socket
347  * @v sa                Completed socket address
348  */
349 static void named_resolv_done ( struct named_socket *named,
350                                 struct sockaddr *sa ) {
351         int rc;
352
353         /* Nullify data transfer interface */
354         intf_nullify ( &named->xfer );
355
356         /* Redirect data-xfer interface */
357         if ( ( rc = xfer_redirect ( &named->xfer, LOCATION_SOCKET,
358                                     named->semantics, sa,
359                                     ( named->have_local ?
360                                       &named->local : NULL ) ) ) != 0 ) {
361                 /* Redirection failed - do not unplug data-xfer interface */
362                 DBGC ( named, "NAMED %p could not redirect: %s\n",
363                        named, strerror ( rc ) );
364         } else {
365                 /* Redirection succeeded - unplug data-xfer interface */
366                 DBGC ( named, "NAMED %p redirected successfully\n", named );
367                 intf_unplug ( &named->xfer );
368         }
369
370         /* Terminate named socket opener */
371         named_close ( named, rc );
372 }
373
374 /** Named socket opener resolver interface operations */
375 static struct interface_operation named_resolv_op[] = {
376         INTF_OP ( intf_close, struct named_socket *, named_close ),
377         INTF_OP ( resolv_done, struct named_socket *, named_resolv_done ),
378 };
379
380 /** Named socket opener resolver interface descriptor */
381 static struct interface_descriptor named_resolv_desc =
382         INTF_DESC ( struct named_socket, resolv, named_resolv_op );
383
384 /**
385  * Open named socket
386  *
387  * @v semantics         Communication semantics (e.g. SOCK_STREAM)
388  * @v peer              Peer socket address to complete
389  * @v name              Name to resolve
390  * @v local             Local socket address, or NULL
391  * @ret rc              Return status code
392  */
393 int xfer_open_named_socket ( struct interface *xfer, int semantics,
394                              struct sockaddr *peer, const char *name,
395                              struct sockaddr *local ) {
396         struct named_socket *named;
397         int rc;
398
399         /* Allocate and initialise structure */
400         named = zalloc ( sizeof ( *named ) );
401         if ( ! named )
402                 return -ENOMEM;
403         ref_init ( &named->refcnt, NULL );
404         intf_init ( &named->xfer, &named_xfer_desc, &named->refcnt );
405         intf_init ( &named->resolv, &named_resolv_desc, &named->refcnt );
406         named->semantics = semantics;
407         if ( local ) {
408                 memcpy ( &named->local, local, sizeof ( named->local ) );
409                 named->have_local = 1;
410         }
411
412         DBGC ( named, "NAMED %p opening \"%s\"\n",
413                named, name );
414
415         /* Start name resolution */
416         if ( ( rc = resolv ( &named->resolv, name, peer ) ) != 0 )
417                 goto err;
418
419         /* Attach parent interface, mortalise self, and return */
420         intf_plug_plug ( &named->xfer, xfer );
421         ref_put ( &named->refcnt );
422         return 0;
423
424  err:
425         ref_put ( &named->refcnt );
426         return rc;
427 }