Introduce name resolution interface and named socket opener.

This commit is contained in:
Michael Brown
2007-05-27 01:07:00 +00:00
parent 1311b4194c
commit 63719deea9
3 changed files with 491 additions and 101 deletions

View File

@@ -7,41 +7,153 @@
*
*/
struct sockaddr;
#include <gpxe/async.h>
#include <gpxe/refcnt.h>
#include <gpxe/interface.h>
#include <gpxe/tables.h>
struct sockaddr;
struct resolv_interface;
/** Name resolution interface operations */
struct resolv_interface_operations {
/** Name resolution completed
*
* @v resolv Name resolution interface
* @v sa Completed socket address (if successful)
* @v rc Final status code
*/
void ( * done ) ( struct resolv_interface *resolv,
struct sockaddr *sa, int rc );
};
/** A name resolution interface */
struct resolv_interface {
/** Generic object communication interface */
struct interface intf;
/** Operations for received messages */
struct resolv_interface_operations *op;
};
extern struct resolv_interface null_resolv;
extern struct resolv_interface_operations null_resolv_ops;
/**
* Initialise a name resolution interface
*
* @v resolv Name resolution interface
* @v op Name resolution interface operations
* @v refcnt Containing object reference counter, or NULL
*/
static inline void resolv_init ( struct resolv_interface *resolv,
struct resolv_interface_operations *op,
struct refcnt *refcnt ) {
resolv->intf.dest = &null_resolv.intf;
resolv->intf.refcnt = refcnt;
resolv->op = op;
}
/**
* Get name resolution interface from generic object communication interface
*
* @v intf Generic object communication interface
* @ret resolv Name resolution interface
*/
static inline __attribute__ (( always_inline )) struct resolv_interface *
intf_to_resolv ( struct interface *intf ) {
return container_of ( intf, struct resolv_interface, intf );
}
/**
* Get reference to destination name resolution interface
*
* @v resolv Name resolution interface
* @ret dest Destination interface
*/
static inline __attribute__ (( always_inline )) struct resolv_interface *
resolv_get_dest ( struct resolv_interface *resolv ) {
return intf_to_resolv ( intf_get ( resolv->intf.dest ) );
}
/**
* Drop reference to name resolution interface
*
* @v resolv name resolution interface
*/
static inline __attribute__ (( always_inline )) void
resolv_put ( struct resolv_interface *resolv ) {
intf_put ( &resolv->intf );
}
/**
* Plug a name resolution interface into a new destination interface
*
* @v resolv Name resolution interface
* @v dest New destination interface
*/
static inline __attribute__ (( always_inline )) void
resolv_plug ( struct resolv_interface *resolv, struct resolv_interface *dest ) {
plug ( &resolv->intf, &dest->intf );
}
/**
* Plug two name resolution interfaces together
*
* @v a Name resolution interface A
* @v b Name resolution interface B
*/
static inline __attribute__ (( always_inline )) void
resolv_plug_plug ( struct resolv_interface *a, struct resolv_interface *b ) {
plug_plug ( &a->intf, &b->intf );
}
/**
* Unplug a name resolution interface
*
* @v resolv Name resolution interface
*/
static inline __attribute__ (( always_inline )) void
resolv_unplug ( struct resolv_interface *resolv ) {
plug ( &resolv->intf, &null_resolv.intf );
}
/**
* Stop using a name resolution interface
*
* @v resolv Name resolution interface
*
* After calling this method, no further messages will be received via
* the interface.
*/
static inline void resolv_nullify ( struct resolv_interface *resolv ) {
resolv->op = &null_resolv_ops;
};
/** A name resolver */
struct resolver {
/** Name of this resolver (e.g. "DNS") */
const char *name;
/** Start name resolution
*
* @v name Host name to resolve
* @v sa Socket address to fill in
* @v parent Parent asynchronous operation
* @v resolv Name resolution interface
* @v name Name to resolve
* @v sa Socket address to complete
* @ret rc Return status code
*
* The asynchronous process must be prepared to accept
* SIGKILL.
*/
int ( * resolv ) ( const char *name, struct sockaddr *sa,
struct async *parent );
int ( * resolv ) ( struct resolv_interface *resolv, const char *name,
struct sockaddr *sa );
};
/** A name resolution in progress */
struct resolution {
/** Asynchronous operation */
struct async async;
/** Numner of active child resolvers */
unsigned int pending;
};
/** Numeric resolver priority */
#define RESOLV_NUMERIC 01
/** Normal resolver priority */
#define RESOLV_NORMAL 02
/** Register as a name resolver */
#define __resolver __table ( struct resolver, resolvers, 01 )
#define __resolver( resolv_order ) \
__table ( struct resolver, resolvers, resolv_order )
extern int resolv ( const char *name, struct sockaddr *sa,
struct async *parent );
extern int resolv ( struct resolv_interface *resolv, const char *name,
struct sockaddr *sa );
#endif /* _GPXE_RESOLV_H */