mirror of
https://github.com/ipxe/ipxe
synced 2025-12-21 20:40:25 +03:00
Introduce name resolution interface and named socket opener.
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user