summaryrefslogtreecommitdiffstats
path: root/debian/grub-extras/disabled/gpxe/src/include/gpxe/resolv.h
blob: 33bb0986b9f1e5bdfea2f81c8f5b5f0d3e4cf1a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#ifndef _GPXE_RESOLV_H
#define _GPXE_RESOLV_H

/** @file
 *
 * Name resolution
 *
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include <gpxe/refcnt.h>
#include <gpxe/interface.h>
#include <gpxe/tables.h>
#include <gpxe/socket.h>

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 resolv		Name resolution interface
	 * @v name		Name to resolve
	 * @v sa		Socket address to complete
	 * @ret rc		Return status code
	 */
	int ( * resolv ) ( struct resolv_interface *resolv, const char *name,
			   struct sockaddr *sa );
};

/** Numeric resolver priority */
#define RESOLV_NUMERIC 01

/** Normal resolver priority */
#define RESOLV_NORMAL 02

/** Resolvers table */
#define RESOLVERS __table ( struct resolver, "resolvers" )

/** Register as a name resolver */
#define __resolver( resolv_order ) __table_entry ( RESOLVERS, resolv_order )

extern void resolv_done ( struct resolv_interface *resolv,
			  struct sockaddr *sa, int rc );
extern void ignore_resolv_done ( struct resolv_interface *resolv,
			  struct sockaddr *sa, int rc );
extern struct resolv_interface_operations null_resolv_ops;
extern struct resolv_interface null_resolv;

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

#endif /* _GPXE_RESOLV_H */