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