Introduce name resolution interface and named socket opener.
[people/dverkamp/gpxe.git] / src / include / gpxe / resolv.h
index 7136401..4a4de4c 100644 (file)
  *
  */
 
+#include <gpxe/refcnt.h>
+#include <gpxe/interface.h>
+#include <gpxe/tables.h>
+
 struct sockaddr;
+struct resolv_interface;
 
-#include <gpxe/async.h>
-#include <gpxe/tables.h>
+/** 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 {
@@ -18,30 +134,26 @@ struct resolver {
        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 */