resolv.c File Reference

Name resolution. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <gpxe/in.h>
#include <gpxe/xfer.h>
#include <gpxe/open.h>
#include <gpxe/process.h>
#include <gpxe/resolv.h>

Go to the source code of this file.

Data Structures

struct  numeric_resolv
 A numeric name resolver. More...
struct  resolv_mux
 A name resolution multiplexer. More...
struct  named_socket
 A named socket. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER)
void resolv_done (struct resolv_interface *resolv, struct sockaddr *sa, int rc)
 Name resolution completed.
void ignore_resolv_done (struct resolv_interface *resolv __unused, struct sockaddr *sa __unused, int rc __unused)
 Ignore name resolution done() event.
static void numeric_step (struct process *process)
static int numeric_resolv (struct resolv_interface *resolv, const char *name, struct sockaddr *sa)
struct resolver numeric_resolver __resolver (RESOLV_NUMERIC)
static int resolv_mux_try (struct resolv_mux *mux)
 Try current child name resolver.
static void resolv_mux_done (struct resolv_interface *resolv, struct sockaddr *sa, int rc)
 Handle done() event from child name resolver.
int resolv (struct resolv_interface *resolv, const char *name, struct sockaddr *sa)
 Start name resolution.
static void named_done (struct named_socket *named, int rc)
 Finish using named socket.
static void named_xfer_close (struct xfer_interface *xfer, int rc)
 Handle close() event.
static void named_resolv_done (struct resolv_interface *resolv, struct sockaddr *sa, int rc)
 Handle done() event.
int xfer_open_named_socket (struct xfer_interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
 Open named socket.

Variables

struct resolv_interface_operations null_resolv_ops
 Null name resolution interface operations.
struct resolv_interface null_resolv
 Null name resolution interface.
static struct
resolv_interface_operations 
resolv_mux_child_ops
 Name resolution multiplexer operations.
static struct
xfer_interface_operations 
named_xfer_ops
 Named socket opener data transfer interface operations.
static struct
resolv_interface_operations 
named_resolv_ops
 Named socket opener name resolution interface operations.


Detailed Description

Name resolution.

Definition in file resolv.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

void resolv_done ( struct resolv_interface resolv,
struct sockaddr sa,
int  rc 
)

Name resolution completed.

Parameters:
resolv Name resolution interface
sa Completed socket address (if successful)
rc Final status code

Definition at line 51 of file resolv.c.

References dest, resolv_interface_operations::done, resolv_interface::op, resolv_get_dest(), resolv_put(), and resolv_unplug().

Referenced by dns_done(), numeric_step(), and resolv_mux_done().

00052                             {
00053         struct resolv_interface *dest = resolv_get_dest ( resolv );
00054 
00055         resolv_unplug ( resolv );
00056         dest->op->done ( dest, sa, rc );
00057         resolv_put ( dest );
00058 }

void ignore_resolv_done ( struct resolv_interface *resolv  __unused,
struct sockaddr *sa  __unused,
int rc  __unused 
)

Ignore name resolution done() event.

Parameters:
resolv Name resolution interface
sa Completed socket address (if successful)
rc Final status code

Definition at line 67 of file resolv.c.

00068                                                                           {
00069         /* Do nothing */
00070 }

static void numeric_step ( struct process process  )  [static]

Definition at line 107 of file resolv.c.

References container_of, process_del(), numeric_resolv::rc, numeric_resolv::resolv, resolv_done(), and numeric_resolv::sa.

Referenced by numeric_resolv().

00107                                                      {
00108         struct numeric_resolv *numeric =
00109                 container_of ( process, struct numeric_resolv, process );
00110         
00111         resolv_done ( &numeric->resolv, &numeric->sa, numeric->rc );
00112         process_del ( process );
00113 }

static int numeric_resolv ( struct resolv_interface resolv,
const char *  name,
struct sockaddr sa 
) [static]

Definition at line 115 of file resolv.c.

References AF_INET, DBGC, EINVAL, ENOMEM, inet_aton(), memcpy, numeric_step(), numeric_resolv::process, process_init(), numeric_resolv::rc, ref_put(), numeric_resolv::refcnt, numeric_resolv::resolv, resolv_init(), resolv_plug_plug(), numeric_resolv::sa, sockaddr_in::sin_addr, sockaddr_in::sin_family, and zalloc().

00116                                                                     {
00117         struct numeric_resolv *numeric;
00118         struct sockaddr_in *sin;
00119 
00120         /* Allocate and initialise structure */
00121         numeric = zalloc ( sizeof ( *numeric ) );
00122         if ( ! numeric )
00123                 return -ENOMEM;
00124         resolv_init ( &numeric->resolv, &null_resolv_ops, &numeric->refcnt );
00125         process_init ( &numeric->process, numeric_step, &numeric->refcnt );
00126         memcpy ( &numeric->sa, sa, sizeof ( numeric->sa ) );
00127 
00128         DBGC ( numeric, "NUMERIC %p attempting to resolve \"%s\"\n",
00129                numeric, name );
00130 
00131         /* Attempt to resolve name */
00132         sin = ( ( struct sockaddr_in * ) &numeric->sa );
00133         sin->sin_family = AF_INET;
00134         if ( inet_aton ( name, &sin->sin_addr ) == 0 )
00135                 numeric->rc = -EINVAL;
00136 
00137         /* Attach to parent interface, mortalise self, and return */
00138         resolv_plug_plug ( &numeric->resolv, resolv );
00139         ref_put ( &numeric->refcnt );
00140         return 0;
00141 }

struct resolver numeric_resolver __resolver ( RESOLV_NUMERIC   )  [read]

static int resolv_mux_try ( struct resolv_mux mux  )  [static]

Try current child name resolver.

Parameters:
mux Name resolution multiplexer
Return values:
rc Return status code

Definition at line 182 of file resolv.c.

References resolv_mux::child, DBGC, resolv_mux::name, resolver::name, resolver::resolv, resolv_mux::resolver, resolv_mux::sa, and strerror().

Referenced by resolv(), and resolv_mux_done().

00182                                                      {
00183         struct resolver *resolver = mux->resolver;
00184         int rc;
00185 
00186         DBGC ( mux, "RESOLV %p trying method %s\n", mux, resolver->name );
00187 
00188         if ( ( rc = resolver->resolv ( &mux->child, mux->name,
00189                                        &mux->sa ) ) != 0 ) {
00190                 DBGC ( mux, "RESOLV %p could not use method %s: %s\n",
00191                        mux, resolver->name, strerror ( rc ) );
00192                 return rc;
00193         }
00194 
00195         return 0;
00196 }

static void resolv_mux_done ( struct resolv_interface resolv,
struct sockaddr sa,
int  rc 
) [static]

Handle done() event from child name resolver.

Parameters:
resolv Child name resolution interface
sa Completed socket address (if successful)
rc Final status code

Definition at line 205 of file resolv.c.

References resolv_mux::child, container_of, DBGC, resolver::name, resolv_mux::parent, resolv_done(), resolv_mux_try(), resolv_unplug(), resolv_mux::resolver, RESOLVERS, and table_end.

00206                                                             {
00207         struct resolv_mux *mux =
00208                 container_of ( resolv, struct resolv_mux, child );
00209 
00210         /* Unplug child */
00211         resolv_unplug ( &mux->child );
00212 
00213         /* If this resolution succeeded, stop now */
00214         if ( rc == 0 ) {
00215                 DBGC ( mux, "RESOLV %p succeeded using method %s\n",
00216                        mux, mux->resolver->name );
00217                 goto finished;
00218         }
00219 
00220         /* Attempt next child resolver, if possible */
00221         mux->resolver++;
00222         if ( mux->resolver >= table_end ( RESOLVERS ) ) {
00223                 DBGC ( mux, "RESOLV %p failed to resolve name\n", mux );
00224                 goto finished;
00225         }
00226         if ( ( rc = resolv_mux_try ( mux ) ) != 0 )
00227                 goto finished;
00228 
00229         /* Next resolver is now running */
00230         return;
00231         
00232  finished:
00233         resolv_done ( &mux->parent, sa, rc );
00234 }

int resolv ( struct resolv_interface resolv,
const char *  name,
struct sockaddr sa 
)

Start name resolution.

Parameters:
resolv Name resolution interface
name Name to resolve
sa Socket address to complete
Return values:
rc Return status code

Definition at line 249 of file resolv.c.

References resolv_mux::child, DBGC, ENOMEM, memcpy, resolv_mux::name, resolv_mux::parent, ref_put(), resolv_mux::refcnt, resolv_init(), resolv_mux_try(), resolv_plug_plug(), resolv_mux::resolver, RESOLVERS, resolv_mux::sa, strlen(), table_start, and zalloc().

Referenced by comboot_resolv(), and xfer_open_named_socket().

00250                                    {
00251         struct resolv_mux *mux;
00252         size_t name_len = ( strlen ( name ) + 1 );
00253         int rc;
00254 
00255         /* Allocate and initialise structure */
00256         mux = zalloc ( sizeof ( *mux ) + name_len );
00257         if ( ! mux )
00258                 return -ENOMEM;
00259         resolv_init ( &mux->parent, &null_resolv_ops, &mux->refcnt );
00260         resolv_init ( &mux->child, &resolv_mux_child_ops, &mux->refcnt );
00261         mux->resolver = table_start ( RESOLVERS );
00262         memcpy ( &mux->sa, sa, sizeof ( mux->sa ) );
00263         memcpy ( mux->name, name, name_len );
00264 
00265         DBGC ( mux, "RESOLV %p attempting to resolve \"%s\"\n", mux, name );
00266 
00267         /* Start first resolver in chain.  There will always be at
00268          * least one resolver (the numeric resolver), so no need to
00269          * check for the zero-resolvers-available case.
00270          */
00271         if ( ( rc = resolv_mux_try ( mux ) ) != 0 )
00272                 goto err;
00273 
00274         /* Attach parent interface, mortalise self, and return */
00275         resolv_plug_plug ( &mux->parent, resolv );
00276         ref_put ( &mux->refcnt );
00277         return 0;
00278 
00279  err:
00280         ref_put ( &mux->refcnt );
00281         return rc;      
00282 }

static void named_done ( struct named_socket named,
int  rc 
) [static]

Finish using named socket.

Parameters:
named Named socket
rc Reason for finish

Definition at line 313 of file resolv.c.

References named_socket::resolv, resolv_nullify(), named_socket::xfer, and xfer_close().

Referenced by named_resolv_done(), and named_xfer_close().

00313                                                               {
00314 
00315         /* Close all interfaces */
00316         resolv_nullify ( &named->resolv );
00317         xfer_nullify ( &named->xfer );
00318         xfer_close ( &named->xfer, rc );
00319 }

static void named_xfer_close ( struct xfer_interface xfer,
int  rc 
) [static]

Handle close() event.

Parameters:
xfer Data transfer interface
rc Reason for close

Definition at line 327 of file resolv.c.

References container_of, and named_done().

00327                                                                      {
00328         struct named_socket *named =
00329                 container_of ( xfer, struct named_socket, xfer );
00330 
00331         named_done ( named, rc );
00332 }

static void named_resolv_done ( struct resolv_interface resolv,
struct sockaddr sa,
int  rc 
) [static]

Handle done() event.

Parameters:
resolv Name resolution interface
sa Completed socket address (if successful)
rc Final status code

Definition at line 351 of file resolv.c.

References container_of, named_socket::have_local, named_socket::local, LOCATION_SOCKET, named_done(), NULL, named_socket::semantics, named_socket::xfer, and xfer_redirect().

00352                                                               {
00353         struct named_socket *named =
00354                 container_of ( resolv, struct named_socket, resolv );
00355 
00356         /* Redirect if name resolution was successful */
00357         if ( rc == 0 ) {
00358                 rc = xfer_redirect ( &named->xfer, LOCATION_SOCKET,
00359                                      named->semantics, sa,
00360                                      ( named->have_local ?
00361                                        &named->local : NULL ) );
00362         }
00363 
00364         /* Terminate resolution */
00365         named_done ( named, rc );
00366 }

int xfer_open_named_socket ( struct xfer_interface xfer,
int  semantics,
struct sockaddr peer,
const char *  name,
struct sockaddr local 
)

Open named socket.

Parameters:
semantics Communication semantics (e.g. SOCK_STREAM)
peer Peer socket address to complete
name Name to resolve
local Local socket address, or NULL
Return values:
rc Return status code

Definition at line 382 of file resolv.c.

References DBGC, ENOMEM, named_socket::have_local, named_socket::local, memcpy, ref_put(), named_socket::refcnt, resolv(), named_socket::resolv, resolv_init(), named_socket::semantics, named_socket::xfer, xfer_init(), and zalloc().

Referenced by ftp_open(), http_open_filter(), iscsi_open_connection(), slam_open(), tcp_open_uri(), tftp_reopen(), and udp_open_uri().

00384                                                       {
00385         struct named_socket *named;
00386         int rc;
00387 
00388         /* Allocate and initialise structure */
00389         named = zalloc ( sizeof ( *named ) );
00390         if ( ! named )
00391                 return -ENOMEM;
00392         xfer_init ( &named->xfer, &named_xfer_ops, &named->refcnt );
00393         resolv_init ( &named->resolv, &named_resolv_ops, &named->refcnt );
00394         named->semantics = semantics;
00395         if ( local ) {
00396                 memcpy ( &named->local, local, sizeof ( named->local ) );
00397                 named->have_local = 1;
00398         }
00399 
00400         DBGC ( named, "RESOLV %p opening named socket \"%s\"\n",
00401                named, name );
00402 
00403         /* Start name resolution */
00404         if ( ( rc = resolv ( &named->resolv, name, peer ) ) != 0 )
00405                 goto err;
00406 
00407         /* Attach parent interface, mortalise self, and return */
00408         xfer_plug_plug ( &named->xfer, xfer );
00409         ref_put ( &named->refcnt );
00410         return 0;
00411 
00412  err:
00413         ref_put ( &named->refcnt );
00414         return rc;
00415 }


Variable Documentation

Initial value:

 {
        .done           = ignore_resolv_done,
}
Null name resolution interface operations.

Definition at line 73 of file resolv.c.

Referenced by dns_resolv(), and resolv_nullify().

Initial value:

 {
        .intf = {
                .dest = &null_resolv.intf,
                .refcnt = NULL,
        },
        .op = &null_resolv_ops,
}
Null name resolution interface.

Definition at line 78 of file resolv.c.

Referenced by resolv_init(), and resolv_unplug().

Initial value:

 {
        .done           = resolv_mux_done,
}
Name resolution multiplexer operations.

Definition at line 237 of file resolv.c.

Initial value:

 {
        .close          = named_xfer_close,
        .vredirect      = ignore_xfer_vredirect,
        .window         = no_xfer_window,
        .alloc_iob      = default_xfer_alloc_iob,
        .deliver_iob    = xfer_deliver_as_raw,
        .deliver_raw    = ignore_xfer_deliver_raw,
}
Named socket opener data transfer interface operations.

Definition at line 335 of file resolv.c.

Initial value:

 {
        .done           = named_resolv_done,
}
Named socket opener name resolution interface operations.

Definition at line 369 of file resolv.c.


Generated on Tue Apr 6 20:01:14 2010 for gPXE by  doxygen 1.5.7.1