Revision b5a2055f

b/src/charon/encoding/payloads/configuration_attribute.c
1 1
/*
2
 * Copyright (C) 2005-2006 Martin Willi
2
 * Copyright (C) 2005-2009 Martin Willi
3 3
 * Copyright (C) 2005 Jan Hutter
4 4
 * Hochschule fuer Technik Rapperswil
5 5
 *
......
38 38
	/**
39 39
	 * Type of the attribute.
40 40
	 */
41
	u_int16_t attribute_type;
41
	u_int16_t type;
42 42

  
43 43
	/**
44 44
	 * Length of the attribute.
45 45
	 */
46
	u_int16_t attribute_length;
46
	u_int16_t length;
47 47

  
48 48
	/**
49 49
	 * Attribute value as chunk.
50 50
	 */
51
	chunk_t attribute_value;
51
	chunk_t value;
52 52
};
53 53

  
54 54
/**
......
56 56
 *
57 57
 * The defined offsets are the positions in a object of type
58 58
 * private_configuration_attribute_t.
59
 *
60 59
 */
61 60
encoding_rule_t configuration_attribute_encodings[] = {
62 61

  
63
	{ RESERVED_BIT,	0																					},
62
	{ RESERVED_BIT,						0													},
64 63
	/* type of the attribute as 15 bit unsigned integer */
65
	{ ATTRIBUTE_TYPE,			offsetof(private_configuration_attribute_t, attribute_type)				},
64
	{ ATTRIBUTE_TYPE,					offsetof(private_configuration_attribute_t, type)	},
66 65
	/* Length of attribute value */
67
	{ CONFIGURATION_ATTRIBUTE_LENGTH,		offsetof(private_configuration_attribute_t, attribute_length)},
66
	{ CONFIGURATION_ATTRIBUTE_LENGTH,	offsetof(private_configuration_attribute_t, length)	},
68 67
	/* Value of attribute if attribute format flag is zero */
69
	{ CONFIGURATION_ATTRIBUTE_VALUE,		offsetof(private_configuration_attribute_t, attribute_value)}
68
	{ CONFIGURATION_ATTRIBUTE_VALUE,	offsetof(private_configuration_attribute_t, value)	}
70 69
};
71 70

  
72 71
/*
......
88 87
{
89 88
	bool failed = FALSE;
90 89

  
91
	if (this->attribute_length != this->attribute_value.len)
90
	if (this->length != this->value.len)
92 91
	{
93 92
		DBG1(DBG_ENC, "invalid attribute length");
94 93
		return FAILED;
95 94
	}
96 95

  
97
	switch (this->attribute_type)
96
	switch (this->type)
98 97
	{
99 98
		 case INTERNAL_IP4_ADDRESS:
100 99
		 case INTERNAL_IP4_NETMASK:
......
102 101
		 case INTERNAL_IP4_NBNS:
103 102
		 case INTERNAL_ADDRESS_EXPIRY:
104 103
		 case INTERNAL_IP4_DHCP:
105
			if (this->attribute_length != 0 && this->attribute_length != 4)
104
			if (this->length != 0 && this->length != 4)
106 105
			{
107 106
				failed = TRUE;
108 107
			}
109 108
			break;
110 109
		 case INTERNAL_IP4_SUBNET:
111
			if (this->attribute_length != 0 && this->attribute_length != 8)
110
			if (this->length != 0 && this->length != 8)
112 111
			{
113 112
				failed = TRUE;
114 113
			}
115 114
			break;
116 115
		 case INTERNAL_IP6_ADDRESS:
117 116
		 case INTERNAL_IP6_SUBNET:
118
			if (this->attribute_length != 0 && this->attribute_length != 17)
117
			if (this->length != 0 && this->length != 17)
119 118
			{
120 119
				failed = TRUE;
121 120
			}
......
123 122
		 case INTERNAL_IP6_DNS:
124 123
		 case INTERNAL_IP6_NBNS:
125 124
		 case INTERNAL_IP6_DHCP:
126
			if (this->attribute_length != 0 && this->attribute_length != 16)
125
			if (this->length != 0 && this->length != 16)
127 126
			{
128 127
				failed = TRUE;
129 128
			}
130 129
			break;
131 130
		 case SUPPORTED_ATTRIBUTES:
132
			if (this->attribute_length % 2)
131
			if (this->length % 2)
133 132
			{
134 133
				failed = TRUE;
135 134
			}
......
139 138
			break;
140 139
		 default:
141 140
			DBG1(DBG_ENC, "unknown attribute type %N",
142
				 configuration_attribute_type_names, this->attribute_type);
141
				 configuration_attribute_type_names, this->type);
143 142
			break;
144 143
	}
145 144

  
146 145
	if (failed)
147 146
	{
148 147
		DBG1(DBG_ENC, "invalid attribute length %d for %N",
149
			 this->attribute_length, configuration_attribute_type_names,
150
			 this->attribute_type);
148
			 this->length, configuration_attribute_type_names, this->type);
151 149
		return FAILED;
152 150
	}
153 151
	return SUCCESS;
......
156 154
/**
157 155
 * Implementation of payload_t.get_encoding_rules.
158 156
 */
159
static void get_encoding_rules(private_configuration_attribute_t *this, encoding_rule_t **rules, size_t *rule_count)
157
static void get_encoding_rules(private_configuration_attribute_t *this,
158
							   encoding_rule_t **rules, size_t *rule_count)
160 159
{
161 160
	*rules = configuration_attribute_encodings;
162 161
	*rule_count = sizeof(configuration_attribute_encodings) / sizeof(encoding_rule_t);
......
175 174
 */
176 175
static payload_type_t get_next_type(private_configuration_attribute_t *this)
177 176
{
178
	return (NO_PAYLOAD);
177
	return NO_PAYLOAD;
179 178
}
180 179

  
181 180
/**
182 181
 * Implementation of payload_t.set_next_type.
183 182
 */
184
static void set_next_type(private_configuration_attribute_t *this,payload_type_t type)
183
static void set_next_type(private_configuration_attribute_t *this,
184
						  payload_type_t type)
185 185
{
186 186
}
187 187

  
......
190 190
 */
191 191
static size_t get_length(private_configuration_attribute_t *this)
192 192
{
193
	return (this->attribute_value.len + CONFIGURATION_ATTRIBUTE_HEADER_LENGTH);
193
	return this->value.len + CONFIGURATION_ATTRIBUTE_HEADER_LENGTH;
194 194
}
195 195

  
196 196
/**
197
 * Implementation of configuration_attribute_t.set_value.
197
 * Implementation of configuration_attribute_t.get_type.
198 198
 */
199
static void set_value(private_configuration_attribute_t *this, chunk_t value)
199
static configuration_attribute_type_t get_configuration_attribute_type(
200
									private_configuration_attribute_t *this)
200 201
{
201
	if (this->attribute_value.ptr != NULL)
202
	{
203
		/* free existing value */
204
		chunk_free(&(this->attribute_value));
205
	}
206

  
207
	this->attribute_value.ptr = clalloc(value.ptr,value.len);
208
	this->attribute_value.len = value.len;
209

  
210
	this->attribute_length = this->attribute_value.len;
202
	return this->type;
211 203
}
212 204

  
213 205
/**
214 206
 * Implementation of configuration_attribute_t.get_value.
215 207
 */
216
static chunk_t get_value (private_configuration_attribute_t *this)
208
static chunk_t get_value(private_configuration_attribute_t *this)
217 209
{
218
	return this->attribute_value;
210
	return this->value;
219 211
}
220 212

  
221 213
/**
222
 * Implementation of configuration_attribute_t.set_type.
214
 * Implementation of configuration_attribute_t.destroy and payload_t.destroy.
223 215
 */
224
static void set_attribute_type (private_configuration_attribute_t *this, u_int16_t type)
216
static void destroy(private_configuration_attribute_t *this)
225 217
{
226
	this->attribute_type = type & 0x7FFF;
218
	free(this->value.ptr);
219
	free(this);
227 220
}
228 221

  
229
/**
230
 * Implementation of configuration_attribute_t.get_type.
222
/*
223
 * Described in header.
231 224
 */
232
static u_int16_t get_attribute_type (private_configuration_attribute_t *this)
225
configuration_attribute_t *configuration_attribute_create()
233 226
{
234
	return this->attribute_type;
227
	private_configuration_attribute_t *this;
228

  
229
	this = malloc_thing(private_configuration_attribute_t);
230
	this->public.payload_interface.verify = (status_t(*)(payload_t *))verify;
231
	this->public.payload_interface.get_encoding_rules = (void(*)(payload_t *, encoding_rule_t **, size_t *) )get_encoding_rules;
232
	this->public.payload_interface.get_length = (size_t(*)(payload_t *))get_length;
233
	this->public.payload_interface.get_next_type = (payload_type_t(*)(payload_t *))get_next_type;
234
	this->public.payload_interface.set_next_type = (void(*)(payload_t *,payload_type_t))set_next_type;
235
	this->public.payload_interface.get_type = (payload_type_t(*)(payload_t *))get_type;
236
	this->public.payload_interface.destroy = (void(*)(payload_t*))destroy;
237

  
238
	this->public.get_value = (chunk_t(*)(configuration_attribute_t *))get_value;
239
	this->public.get_type = (configuration_attribute_type_t(*)(configuration_attribute_t *))get_configuration_attribute_type;
240
	this->public.destroy = (void (*)(configuration_attribute_t*))destroy;
241

  
242
	this->type = 0;
243
	this->value = chunk_empty;
244
	this->length = 0;
245

  
246
	return &this->public;
235 247
}
236 248

  
237
/**
238
 * Implementation of configuration_attribute_t.get_length.
249
/*
250
 * Described in header.
239 251
 */
240
static u_int16_t get_attribute_length (private_configuration_attribute_t *this)
252
configuration_attribute_t *configuration_attribute_create_value(
253
							configuration_attribute_type_t type, chunk_t value)
241 254
{
242
	return this->attribute_length;
243
}
255
	private_configuration_attribute_t *this;
244 256

  
257
	this = (private_configuration_attribute_t*)configuration_attribute_create();
258
	this->type = ((u_int16_t)type) & 0x7FFF;
259
	this->value = chunk_clone(value);
260
	this->length = value.len;
245 261

  
246
/**
247
 * Implementation of configuration_attribute_t.destroy and payload_t.destroy.
248
 */
249
static void destroy(private_configuration_attribute_t *this)
250
{
251
	if (this->attribute_value.ptr != NULL)
252
	{
253
		free(this->attribute_value.ptr);
254
	}
255
	free(this);
262
	return &this->public;
256 263
}
257 264

  
258
/*
259
 * Described in header.
260
 */
261
configuration_attribute_t *configuration_attribute_create()
262
{
263
	private_configuration_attribute_t *this = malloc_thing(private_configuration_attribute_t);
264

  
265
	/* payload interface */
266
	this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
267
	this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
268
	this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
269
	this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
270
	this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
271
	this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
272
	this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
273

  
274
	/* public functions */
275
	this->public.set_value = (void (*) (configuration_attribute_t *,chunk_t)) set_value;
276
	this->public.get_value = (chunk_t (*) (configuration_attribute_t *)) get_value;
277
	this->public.set_type = (void (*) (configuration_attribute_t *,u_int16_t type)) set_attribute_type;
278
	this->public.get_type = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_type;
279
	this->public.get_length = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_length;
280
	this->public.destroy = (void (*) (configuration_attribute_t *)) destroy;
281

  
282
	/* set default values of the fields */
283
	this->attribute_type = 0;
284
	this->attribute_value = chunk_empty;
285
	this->attribute_length = 0;
286

  
287
	return (&(this->public));
288
}
b/src/charon/encoding/payloads/configuration_attribute.h
1 1
/*
2
 * Copyright (C) 2005-2006 Martin Willi
2
 * Copyright (C) 2005-2009 Martin Willi
3 3
 * Copyright (C) 2005 Jan Hutter
4 4
 * Hochschule fuer Technik Rapperswil
5 5
 *
......
28 28
#include <attributes/attributes.h>
29 29
#include <encoding/payloads/payload.h>
30 30

  
31

  
32 31
/**
33 32
 * Configuration attribute header length in bytes.
34 33
 */
......
40 39
 * The CONFIGURATION ATTRIBUTE format is described in RFC section 3.15.1.
41 40
 */
42 41
struct configuration_attribute_t {
43
	/**
44
	 * The payload_t interface.
45
	 */
46
	payload_t payload_interface;
47

  
48
	/**
49
	 * Returns the currently set value of the attribute.
50
	 *
51
	 * @warning Returned data are not copied.
52
	 *
53
	 * @return 		chunk_t pointing to the value
54
	 */
55
	chunk_t (*get_value) (configuration_attribute_t *this);
56

  
57
	/**
58
	 * Sets the value of the attribute.
59
	 *
60
	 * Value is getting copied.
61
	 *
62
	 * @param value chunk_t pointing to the value to set
63
	 */
64
	void (*set_value) (configuration_attribute_t *this, chunk_t value);
65 42

  
66 43
	/**
67
	 * Sets the type of the attribute.
68
	 *
69
	 * @param type	type to set (most significant bit is set to zero)
44
	 * Implements payload_t interface.
70 45
	 */
71
	void (*set_type) (configuration_attribute_t *this, u_int16_t type);
46
	payload_t payload_interface;
72 47

  
73 48
	/**
74
	 * get the type of the attribute.
49
	 * Get the type of the attribute.
75 50
	 *
76
	 * @return 		type of the value
51
	 * @return 		type of the configuration attribute
77 52
	 */
78
	u_int16_t (*get_type) (configuration_attribute_t *this);
53
	configuration_attribute_type_t (*get_type)(configuration_attribute_t *this);
79 54

  
80 55
	/**
81
	 * get the length of an attribute.
56
	 * Returns the value of the attribute.
82 57
	 *
83
	 * @return 		type of the value
58
	 * @return 		chunk_t pointing to the internal value
84 59
	 */
85
	u_int16_t (*get_length) (configuration_attribute_t *this);
60
	chunk_t (*get_value) (configuration_attribute_t *this);
86 61

  
87 62
	/**
88 63
	 * Destroys an configuration_attribute_t object.
......
91 66
};
92 67

  
93 68
/**
94
 * Creates an empty configuration_attribute_t object.
69
 * Creates an empty configuration attribute.
70
 *
71
 * @return		created configuration attribute
72
 */
73
configuration_attribute_t *configuration_attribute_create();
74

  
75
/**
76
 * Creates a configuration attribute with type and value.
95 77
 *
96
 * @return			created configuration_attribute_t object
78
 * @param type	type of configuration attribute
79
 * @param value	value, gets cloned
80
 * @return		created configuration attribute
97 81
 */
98
configuration_attribute_t *configuration_attribute_create(void);
82
configuration_attribute_t *configuration_attribute_create_value(
83
							configuration_attribute_type_t type, chunk_t value);
99 84

  
100 85
#endif /** CONFIGURATION_ATTRIBUTE_H_ @}*/
b/src/charon/encoding/payloads/cp_payload.c
1 1
/*
2
 * Copyright (C) 2005-2006 Martin Willi
2
 * Copyright (C) 2005-2009 Martin Willi
3 3
 * Copyright (C) 2005 Jan Hutter
4 4
 * Hochschule fuer Technik Rapperswil
5 5
 *
......
56 56
	u_int16_t payload_length;
57 57

  
58 58
	/**
59
	 * Configuration Attributes in this payload are stored in a linked_list_t.
59
	 * List of attributes, as configuration_attribute_t
60 60
	 */
61
	linked_list_t * attributes;
61
	linked_list_t *attributes;
62 62

  
63 63
	/**
64 64
	 * Config Type.
65 65
	 */
66
	u_int8_t config_type;
66
	u_int8_t type;
67 67
};
68 68

  
69 69
/**
......
90 90
	{ PAYLOAD_LENGTH,		offsetof(private_cp_payload_t, payload_length) 	},
91 91
	/* Proposals are stored in a proposal substructure,
92 92
	   offset points to a linked_list_t pointer */
93
	{ U_INT_8,		offsetof(private_cp_payload_t, config_type)				},
93
	{ U_INT_8,				offsetof(private_cp_payload_t, type)			},
94 94
	{ RESERVED_BYTE,0 														},
95 95
	{ RESERVED_BYTE,0														},
96 96
	{ RESERVED_BYTE,0														},
......
117 117
static status_t verify(private_cp_payload_t *this)
118 118
{
119 119
	status_t status = SUCCESS;
120
	iterator_t *iterator;
121
	configuration_attribute_t *attribute;
120
	enumerator_t *enumerator;
121
	payload_t *attribute;
122 122

  
123
	iterator = this->attributes->create_iterator(this->attributes,TRUE);
124
	while(iterator->iterate(iterator, (void**)&attribute))
123
	enumerator = this->attributes->create_enumerator(this->attributes);
124
	while (enumerator->enumerate(enumerator, &attribute))
125 125
	{
126
		status = attribute->payload_interface.verify(&attribute->payload_interface);
126
		status = attribute->verify(attribute);
127 127
		if (status != SUCCESS)
128 128
		{
129 129
			break;
130 130
		}
131 131
	}
132
	iterator->destroy(iterator);
132
	enumerator->destroy(enumerator);
133 133
	return status;
134 134
}
135 135

  
136 136
/**
137 137
 * Implementation of payload_t.get_encoding_rules.
138 138
 */
139
static void get_encoding_rules(private_cp_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
139
static void get_encoding_rules(private_cp_payload_t *this,
140
							   encoding_rule_t **rules, size_t *rule_count)
140 141
{
141 142
	*rules = cp_payload_encodings;
142 143
	*rule_count = sizeof(cp_payload_encodings) / sizeof(encoding_rule_t);
......
155 156
 */
156 157
static payload_type_t get_next_type(private_cp_payload_t *this)
157 158
{
158
	return (this->next_payload);
159
	return this->next_payload;
159 160
}
160 161

  
161 162
/**
......
171 172
 */
172 173
static void compute_length(private_cp_payload_t *this)
173 174
{
174
	iterator_t *iterator;
175
	payload_t *current_attribute;
176
	size_t length = CP_PAYLOAD_HEADER_LENGTH;
175
	enumerator_t *enumerator;
176
	payload_t *attribute;
177 177

  
178
	iterator = this->attributes->create_iterator(this->attributes,TRUE);
179
	while (iterator->iterate(iterator, (void**)&current_attribute))
178
	this->payload_length = CP_PAYLOAD_HEADER_LENGTH;
179

  
180
	enumerator = this->attributes->create_enumerator(this->attributes);
181
	while (enumerator->enumerate(enumerator, &attribute))
180 182
	{
181
		length += current_attribute->get_length(current_attribute);
183
		this->payload_length += attribute->get_length(attribute);
182 184
	}
183
	iterator->destroy(iterator);
184

  
185
	this->payload_length = length;
185
	enumerator->destroy(enumerator);
186 186
}
187 187

  
188 188
/**
......
190 190
 */
191 191
static size_t get_length(private_cp_payload_t *this)
192 192
{
193
	compute_length(this);
194 193
	return this->payload_length;
195 194
}
196 195

  
197 196
/**
198
 * Implementation of cp_payload_t.create_configuration_attribute_iterator.
197
 * Implementation of cp_payload_t.create_attribute_enumerator.
199 198
 */
200
static iterator_t *create_attribute_iterator (private_cp_payload_t *this)
199
static enumerator_t *create_attribute_enumerator(private_cp_payload_t *this)
201 200
{
202
	return this->attributes->create_iterator(this->attributes, TRUE);
201
	return this->attributes->create_enumerator(this->attributes);
203 202
}
204 203

  
205 204
/**
206
 * Implementation of cp_payload_t.add_proposal_substructure.
205
 * Implementation of cp_payload_t.add_attribute.
207 206
 */
208
static void add_configuration_attribute (private_cp_payload_t *this,configuration_attribute_t *attribute)
207
static void add_attribute(private_cp_payload_t *this,
208
						  configuration_attribute_t *attribute)
209 209
{
210
	this->attributes->insert_last(this->attributes,(void *) attribute);
210
	this->attributes->insert_last(this->attributes, attribute);
211 211
	compute_length(this);
212 212
}
213 213

  
214 214
/**
215
 * Implementation of cp_payload_t.set_config_type.
216
 */
217
static void set_config_type (private_cp_payload_t *this,config_type_t config_type)
218
{
219
	this->config_type = config_type;
220
}
221

  
222
/**
223
 * Implementation of cp_payload_t.get_config_type.
215
 * Implementation of cp_payload_t.get_type.
224 216
 */
225
static config_type_t get_config_type (private_cp_payload_t *this)
217
static config_type_t get_config_type(private_cp_payload_t *this)
226 218
{
227
	return this->config_type;
219
	return this->type;
228 220
}
229 221

  
230 222
/**
......
233 225
static void destroy(private_cp_payload_t *this)
234 226
{
235 227
	this->attributes->destroy_offset(this->attributes,
236
									 offsetof(configuration_attribute_t, destroy));
228
								offsetof(configuration_attribute_t, destroy));
237 229
	free(this);
238 230
}
239 231

  
......
244 236
{
245 237
	private_cp_payload_t *this = malloc_thing(private_cp_payload_t);
246 238

  
247
	/* public interface */
248 239
	this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
249 240
	this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
250 241
	this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
......
253 244
	this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
254 245
	this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
255 246

  
256
	/* public functions */
257
	this->public.create_attribute_iterator = (iterator_t* (*) (cp_payload_t *)) create_attribute_iterator;
258
	this->public.add_configuration_attribute = (void (*) (cp_payload_t *,configuration_attribute_t *)) add_configuration_attribute;
259
	this->public.set_config_type = (void (*) (cp_payload_t *, config_type_t)) set_config_type;
260
	this->public.get_config_type = (config_type_t (*) (cp_payload_t *)) get_config_type;
261
	this->public.destroy = (void (*) (cp_payload_t *)) destroy;
247
	this->public.create_attribute_enumerator = (enumerator_t*(*)(cp_payload_t *))create_attribute_enumerator;
248
	this->public.add_attribute = (void (*) (cp_payload_t *,configuration_attribute_t*))add_attribute;
249
	this->public.get_type = (config_type_t (*) (cp_payload_t *))get_config_type;
250
	this->public.destroy = (void (*)(cp_payload_t *))destroy;
262 251

  
263 252
	/* set default values of the fields */
264 253
	this->critical = FALSE;
265 254
	this->next_payload = NO_PAYLOAD;
266 255
	this->payload_length = CP_PAYLOAD_HEADER_LENGTH;
267

  
268 256
	this->attributes = linked_list_create();
269
	return (&(this->public));
257
	this->type = CFG_REQUEST;
258

  
259
	return &this->public;
260
}
261

  
262
/*
263
 * Described in header.
264
 */
265
cp_payload_t *cp_payload_create_type(config_type_t type)
266
{
267
	private_cp_payload_t *this = (private_cp_payload_t*)cp_payload_create();
268

  
269
	this->type = type;
270

  
271
	return &this->public;
270 272
}
273

  
b/src/charon/encoding/payloads/cp_payload.h
1 1
/*
2
 * Copyright (C) 2005-2006 Martin Willi
2
 * Copyright (C) 2005-2009 Martin Willi
3 3
 * Copyright (C) 2005 Jan Hutter
4 4
 * Hochschule fuer Technik Rapperswil
5 5
 *
......
28 28
#include <library.h>
29 29
#include <encoding/payloads/payload.h>
30 30
#include <encoding/payloads/configuration_attribute.h>
31
#include <utils/linked_list.h>
31
#include <utils/enumerator.h>
32 32

  
33 33
/**
34 34
 * CP_PAYLOAD length in bytes without any proposal substructure.
......
56 56
 * The CP Payload format is described in RFC section 3.15.
57 57
 */
58 58
struct cp_payload_t {
59

  
59 60
	/**
60 61
	 * The payload_t interface.
61 62
	 */
......
64 65
	/**
65 66
	 * Creates an iterator of stored configuration_attribute_t objects.
66 67
	 *
67
	 * When deleting an attribute using this iterator, the length of this
68
	 * configuration_attribute_t has to be refreshed by calling get_length()!
69
	 *
70
	 * @return				created iterator_t object
68
	 * @return			enumerator over configration_attribute_T
71 69
	 */
72
	iterator_t *(*create_attribute_iterator) (cp_payload_t *this);
70
	enumerator_t *(*create_attribute_enumerator) (cp_payload_t *this);
73 71

  
74 72
	/**
75
	 * Adds a configuration_attribute_t object to this object.
76
	 *
77
	 * The added configuration_attribute_t object is getting destroyed in
78
	 * destroy function of cp_payload_t.
73
	 * Adds a configuration attribute to the configuration payload.
79 74
	 *
80
	 * @param attribute		configuration_attribute_t object to add
75
	 * @param attribute	attribute to add
81 76
	 */
82
	void (*add_configuration_attribute) (cp_payload_t *this, configuration_attribute_t *attribute);
77
	void (*add_attribute)(cp_payload_t *this,
78
						  configuration_attribute_t *attribute);
83 79

  
84 80
	/**
85
	 * Set the config type.
81
	 * Get the configuration payload type.
86 82
	 *
87
	 * @param config_type	config_type_t to set
83
	 * @return			type of configuration payload
88 84
	 */
89
	void (*set_config_type) (cp_payload_t *this,config_type_t config_type);
90

  
91
	/**
92
	 * Get the config type.
93
	 *
94
	 * @return				config_type_t
95
	 */
96
	config_type_t (*get_config_type) (cp_payload_t *this);
85
	config_type_t (*get_type) (cp_payload_t *this);
97 86

  
98 87
	/**
99 88
	 * Destroys an cp_payload_t object.
......
102 91
};
103 92

  
104 93
/**
105
 * Creates an empty cp_payload_t object
94
 * Creates an empty configuration payload
95
 *
96
 * @return		empty configuration payload
97
 */
98
cp_payload_t *cp_payload_create();
99

  
100
/**
101
 * Creates an cp_payload_t with type and value
106 102
 *
107
 * @return cp_payload_t object
103
 * @param type	type of configuration payload to create
104
 * @return		created configuration payload
108 105
 */
109
cp_payload_t *cp_payload_create(void);
106
cp_payload_t *cp_payload_create_type(config_type_t config_type);
110 107

  
111 108
#endif /** CP_PAYLOAD_H_ @}*/
b/src/charon/plugins/attr/attr_provider.c
61 61
/**
62 62
 * Implementation of attribute_provider_t.create_attribute_enumerator
63 63
 */
64
static enumerator_t* create_attribute_enumerator(
65
					private_attr_provider_t *this, identification_t *id)
64
static enumerator_t* create_attribute_enumerator(private_attr_provider_t *this,
65
											identification_t *id, host_t *vip)
66 66
{
67
	return enumerator_create_filter(
67
	if (vip)
68
	{
69
		return enumerator_create_filter(
68 70
						this->attributes->create_enumerator(this->attributes),
69 71
						(void*)attr_enum_filter, NULL, NULL);
72
	}
73
	return enumerator_create_empty();
70 74
}
71 75

  
72 76
/**
......
138 142

  
139 143
	this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *, host_t *))return_null;
140 144
	this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))return_false;
141
	this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))create_attribute_enumerator;
145
	this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id, host_t *vip))create_attribute_enumerator;
142 146
	this->public.destroy = (void(*)(attr_provider_t*))destroy;
143 147

  
144 148
	this->attributes = linked_list_create();
b/src/charon/plugins/nm/nm_handler.c
68 68
}
69 69

  
70 70
/**
71
 * Implementation of create_attribute_enumerator().enumerate() for WINS
72
 */
73
static bool enumerate_nbns(enumerator_t *this,
74
						   configuration_attribute_type_t *type, chunk_t *data)
75
{
76
	*type = INTERNAL_IP4_NBNS;
77
	*data = chunk_empty;
78
	/* done */
79
	this->enumerate = (void*)return_false;
80
	return TRUE;
81
}
82

  
83
/**
84
 * Implementation of create_attribute_enumerator().enumerate() for DNS
85
 */
86
static bool enumerate_dns(enumerator_t *this,
87
						  configuration_attribute_type_t *type, chunk_t *data)
88
{
89
	*type = INTERNAL_IP4_DNS;
90
	*data = chunk_empty;
91
	/* enumerate WINS server as next attribute ... */
92
	this->enumerate = (void*)enumerate_nbns;
93
	return TRUE;
94
}
95

  
96
/**
97
 * Implementation of attribute_handler_t.create_attribute_enumerator
98
 */
99
static enumerator_t* create_attribute_enumerator(private_nm_handler_t *this,
100
										identification_t *server, host_t *vip)
101
{
102
	if (vip && vip->get_family(vip) == AF_INET)
103
	{	/* no IPv6 attributes yet */
104
		enumerator_t *enumerator = malloc_thing(enumerator_t);
105
		/* enumerate DNS attribute first ... */
106
		enumerator->enumerate = (void*)enumerate_dns;
107
		enumerator->destroy = (void*)free;
108

  
109
		return enumerator;
110
	}
111
	return enumerator_create_empty();
112
}
113

  
114
/**
71 115
 * convert plain byte ptrs to handy chunk during enumeration
72 116
 */
73 117
static bool filter_chunks(void* null, char **in, chunk_t *out)
......
136 180

  
137 181
	this->public.handler.handle = (bool(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle;
138 182
	this->public.handler.release = (void(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))nop;
183
	this->public.handler.create_attribute_enumerator = (enumerator_t*(*)(attribute_handler_t*, identification_t *server, host_t *vip))create_attribute_enumerator;
139 184
	this->public.create_enumerator = (enumerator_t*(*)(nm_handler_t*, configuration_attribute_type_t type))create_enumerator;
140 185
	this->public.reset = (void(*)(nm_handler_t*))reset;
141 186
	this->public.destroy = (void(*)(nm_handler_t*))destroy;
b/src/charon/plugins/resolve/resolve_handler.c
164 164
}
165 165

  
166 166
/**
167
 * Attribute enumerator implementation
168
 */
169
typedef struct {
170
	/** implements enumerator_t interface */
171
	enumerator_t public;
172
	/** virtual IP we are requesting */
173
	host_t *vip;
174
} attribute_enumerator_t;
175

  
176
/**
177
 * Implementation of create_attribute_enumerator().enumerate()
178
 */
179
static bool attribute_enumerate(attribute_enumerator_t *this,
180
						configuration_attribute_type_t *type, chunk_t *data)
181
{
182
	switch (this->vip->get_family(this->vip))
183
	{
184
		case AF_INET:
185
			*type = INTERNAL_IP4_DNS;
186
			break;
187
		case AF_INET6:
188
			*type = INTERNAL_IP6_DNS;
189
			break;
190
		default:
191
			return FALSE;
192
	}
193
	*data = chunk_empty;
194
	/* enumerate only once */
195
	this->public.enumerate = (void*)return_false;
196
	return TRUE;
197
}
198

  
199
/**
200
 * Implementation of attribute_handler_t.create_attribute_enumerator
201
 */
202
static enumerator_t* create_attribute_enumerator(private_resolve_handler_t *this,
203
										identification_t *server, host_t *vip)
204
{
205
	if (vip)
206
	{
207
		attribute_enumerator_t *enumerator;
208

  
209
		enumerator = malloc_thing(attribute_enumerator_t);
210
		enumerator->public.enumerate = (void*)attribute_enumerate;
211
		enumerator->public.destroy = (void*)free;
212
		enumerator->vip = vip;
213

  
214
		return &enumerator->public;
215
	}
216
	return enumerator_create_empty();
217
}
218

  
219
/**
167 220
 * Implementation of resolve_handler_t.destroy.
168 221
 */
169 222
static void destroy(private_resolve_handler_t *this)
......
181 234

  
182 235
	this->public.handler.handle = (bool(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle;
183 236
	this->public.handler.release = (void(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))release;
237
	this->public.handler.create_attribute_enumerator = (enumerator_t*(*)(attribute_handler_t*, identification_t *server, host_t *vip))create_attribute_enumerator;
184 238
	this->public.destroy = (void(*)(resolve_handler_t*))destroy;
185 239

  
186 240
	this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
b/src/charon/plugins/stroke/stroke_attribute.c
531 531

  
532 532
	this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,host_t *))acquire_address;
533 533
	this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
534
	this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))enumerator_create_empty;
534
	this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id, host_t *vip))enumerator_create_empty;
535 535
	this->public.add_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))add_pool;
536 536
	this->public.del_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))del_pool;
537 537
	this->public.create_pool_enumerator = (enumerator_t*(*)(stroke_attribute_t*))create_pool_enumerator;
b/src/charon/sa/ike_sa.c
1843 1843
 * Implementation of ike_sa_t.add_configuration_attribute
1844 1844
 */
1845 1845
static void add_configuration_attribute(private_ike_sa_t *this,
1846
							attribute_handler_t *handler,
1846 1847
							configuration_attribute_type_t type, chunk_t data)
1847 1848
{
1848
	attribute_entry_t *entry;
1849
	attribute_handler_t *handler;
1849
	attribute_entry_t *entry = malloc_thing(attribute_entry_t);
1850 1850

  
1851
	handler = lib->attributes->handle(lib->attributes, this->other_id,
1852
									  type, data);
1853
	if (handler)
1854
	{
1855
		entry = malloc_thing(attribute_entry_t);
1856
		entry->handler = handler;
1857
		entry->type = type;
1858
		entry->data = chunk_clone(data);
1851
	entry->handler = handler;
1852
	entry->type = type;
1853
	entry->data = chunk_clone(data);
1859 1854

  
1860
		this->attributes->insert_last(this->attributes, entry);
1861
	}
1855
	this->attributes->insert_last(this->attributes, entry);
1862 1856
}
1863 1857

  
1864 1858
/**
......
2091 2085
	this->public.get_unique_id = (u_int32_t (*)(ike_sa_t*))get_unique_id;
2092 2086
	this->public.set_virtual_ip = (void (*)(ike_sa_t*,bool,host_t*))set_virtual_ip;
2093 2087
	this->public.get_virtual_ip = (host_t* (*)(ike_sa_t*,bool))get_virtual_ip;
2094
	this->public.add_configuration_attribute = (void(*)(ike_sa_t*, configuration_attribute_type_t type, chunk_t data))add_configuration_attribute;
2088
	this->public.add_configuration_attribute = (void(*)(ike_sa_t*, attribute_handler_t *handler,configuration_attribute_type_t type, chunk_t data))add_configuration_attribute;
2095 2089
	this->public.set_kmaddress = (void (*)(ike_sa_t*,host_t*,host_t*))set_kmaddress;
2096 2090
#ifdef ME
2097 2091
	this->public.act_as_mediation_server = (void (*)(ike_sa_t*)) act_as_mediation_server;
b/src/charon/sa/ike_sa.h
855 855
	 * @param data			associated attribute data
856 856
	 */
857 857
	void (*add_configuration_attribute)(ike_sa_t *this,
858
							attribute_handler_t *handler,
858 859
							configuration_attribute_type_t type, chunk_t data);
859 860

  
860 861
	/**
b/src/charon/sa/tasks/ike_config.c
19 19
#include <daemon.h>
20 20
#include <encoding/payloads/cp_payload.h>
21 21

  
22
#define DNS_SERVER_MAX		2
23
#define NBNS_SERVER_MAX		2
24

  
25 22
typedef struct private_ike_config_t private_ike_config_t;
26 23

  
27 24
/**
......
48 45
	 * virtual ip
49 46
	 */
50 47
	host_t *virtual_ip;
48

  
49
	/**
50
	 * list of attributes requested and its handler, entry_t
51
	 */
52
	linked_list_t *requested;
51 53
};
52 54

  
53 55
/**
54
 * build INTERNAL_IPV4/6_ADDRESS from virtual ip
56
 * Entry for a requested attribute and the requesting handler
57
 */
58
typedef struct {
59
	/** attribute requested */
60
	configuration_attribute_type_t type;
61
	/** handler requesting this attribute */
62
	attribute_handler_t *handler;
63
} entry_t;
64

  
65
/**
66
 * build INTERNAL_IPV4/6_ADDRESS attribute from virtual ip
55 67
 */
56
static void build_vip(private_ike_config_t *this, host_t *vip, cp_payload_t *cp)
68
static configuration_attribute_t *build_vip(host_t *vip)
57 69
{
58
	configuration_attribute_t *ca;
70
	configuration_attribute_type_t type;
59 71
	chunk_t chunk, prefix;
60 72

  
61
	ca = configuration_attribute_create();
62

  
63 73
	if (vip->get_family(vip) == AF_INET)
64 74
	{
65
		ca->set_type(ca, INTERNAL_IP4_ADDRESS);
75
		type = INTERNAL_IP4_ADDRESS;
66 76
		if (vip->is_anyaddr(vip))
67 77
		{
68 78
			chunk = chunk_empty;
......
74 84
	}
75 85
	else
76 86
	{
77
		ca->set_type(ca, INTERNAL_IP6_ADDRESS);
87
		type = INTERNAL_IP6_ADDRESS;
78 88
		if (vip->is_anyaddr(vip))
79 89
		{
80 90
			chunk = chunk_empty;
......
87 97
			chunk = chunk_cata("cc", chunk, prefix);
88 98
		}
89 99
	}
90
	ca->set_value(ca, chunk);
91
	cp->add_configuration_attribute(cp, ca);
100
	return configuration_attribute_create_value(type, chunk);
101
}
102

  
103
/**
104
 * Handle a received attribute as initiator
105
 */
106
static void handle_attribute(private_ike_config_t *this,
107
							 configuration_attribute_t *ca)
108
{
109
	attribute_handler_t *handler = NULL;
110
	enumerator_t *enumerator;
111
	entry_t *entry;
112

  
113
	/* find the handler which requested this attribute */
114
	enumerator = this->requested->create_enumerator(this->requested);
115
	while (enumerator->enumerate(enumerator, &entry))
116
	{
117
		if (entry->type == ca->get_type(ca))
118
		{
119
			handler = entry->handler;
120
			this->requested->remove_at(this->requested, enumerator);
121
			free(entry);
122
			break;
123
		}
124
	}
125

  
126
	/* and pass it to the handle function */
127
	handler = lib->attributes->handle(lib->attributes,
128
							this->ike_sa->get_other_id(this->ike_sa), handler,
129
							ca->get_type(ca), ca->get_value(ca));
130
	if (handler)
131
	{
132
		this->ike_sa->add_configuration_attribute(this->ike_sa,
133
				handler, ca->get_type(ca), ca->get_value(ca));
134
	}
92 135
}
93 136

  
94 137
/**
......
130 173
			break;
131 174
		}
132 175
		default:
176
		{
133 177
			if (this->initiator)
134 178
			{
135
				this->ike_sa->add_configuration_attribute(this->ike_sa,
136
										ca->get_type(ca), ca->get_value(ca));
137
			}
138
			else
139
			{
140
				/* we do not handle attribute requests other than for VIPs */
179
				handle_attribute(this, ca);
141 180
			}
181
		}
142 182
	}
143 183
}
144 184

  
......
147 187
 */
148 188
static void process_payloads(private_ike_config_t *this, message_t *message)
149 189
{
150
	enumerator_t *enumerator;
151
	iterator_t *attributes;
190
	enumerator_t *enumerator, *attributes;
152 191
	payload_t *payload;
153 192

  
154 193
	enumerator = message->create_payload_enumerator(message);
......
158 197
		{
159 198
			cp_payload_t *cp = (cp_payload_t*)payload;
160 199
			configuration_attribute_t *ca;
161
			switch (cp->get_config_type(cp))
200

  
201
			switch (cp->get_type(cp))
162 202
			{
163 203
				case CFG_REQUEST:
164 204
				case CFG_REPLY:
165 205
				{
166
					attributes = cp->create_attribute_iterator(cp);
167
					while (attributes->iterate(attributes, (void**)&ca))
206
					attributes = cp->create_attribute_enumerator(cp);
207
					while (attributes->enumerate(attributes, &ca))
168 208
					{
169 209
						process_attribute(this, ca);
170 210
					}
......
173 213
				}
174 214
				default:
175 215
					DBG1(DBG_IKE, "ignoring %N config payload",
176
						 config_type_names, cp->get_config_type(cp));
216
						 config_type_names, cp->get_type(cp));
177 217
					break;
178 218
			}
179 219
		}
......
188 228
{
189 229
	if (message->get_message_id(message) == 1)
190 230
	{	/* in first IKE_AUTH only */
231
		cp_payload_t *cp = NULL;
232
		enumerator_t *enumerator;
233
		attribute_handler_t *handler;
191 234
		peer_cfg_t *config;
235
		configuration_attribute_type_t type;
236
		chunk_t data;
192 237
		host_t *vip;
193 238

  
194 239
		/* reuse virtual IP if we already have one */
......
200 245
		}
201 246
		if (vip)
202 247
		{
203
			configuration_attribute_t *ca;
204
			cp_payload_t *cp;
205

  
206
			cp = cp_payload_create();
207
			cp->set_config_type(cp, CFG_REQUEST);
248
			cp = cp_payload_create_type(CFG_REQUEST);
249
			cp->add_attribute(cp, build_vip(vip));
250
		}
208 251

  
209
			build_vip(this, vip, cp);
252
		enumerator = lib->attributes->create_initiator_enumerator(lib->attributes,
253
								this->ike_sa->get_other_id(this->ike_sa), vip);
254
		while (enumerator->enumerate(enumerator, &handler, &type, &data))
255
		{
256
			configuration_attribute_t *ca;
257
			entry_t *entry;
210 258

  
211
			/* we currently always add a DNS request if we request an IP */
212
			ca = configuration_attribute_create();
213
			if (vip->get_family(vip) == AF_INET)
214
			{
215
				ca->set_type(ca, INTERNAL_IP4_DNS);
216
			}
217
			else
259
			/* create configuration attribute */
260
			ca = configuration_attribute_create_value(type, data);
261
			if (!cp)
218 262
			{
219
				ca->set_type(ca, INTERNAL_IP6_DNS);
263
				cp = cp_payload_create_type(CFG_REQUEST);
220 264
			}
221
			cp->add_configuration_attribute(cp, ca);
265
			cp->add_attribute(cp, ca);
266

  
267
			/* save handler along with requested type */
268
			entry = malloc_thing(entry_t);
269
			entry->type = type;
270
			entry->handler = handler;
271

  
272
			this->requested->insert_last(this->requested, entry);
273
		}
274
		enumerator->destroy(enumerator);
275

  
276
		if (cp)
277
		{
222 278
			message->add_payload(message, (payload_t*)cp);
223 279
		}
224 280
	}
......
244 300
{
245 301
	if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
246 302
	{	/* in last IKE_AUTH exchange */
247
		peer_cfg_t *config = this->ike_sa->get_peer_cfg(this->ike_sa);
303
		enumerator_t *enumerator;
304
		configuration_attribute_type_t type;
305
		chunk_t value;
306
		host_t *vip = NULL;
307
		cp_payload_t *cp = NULL;
308
		peer_cfg_t *config;
248 309

  
310
		config = this->ike_sa->get_peer_cfg(this->ike_sa);
249 311
		if (config && this->virtual_ip)
250 312
		{
251
			enumerator_t *enumerator;
252
			configuration_attribute_type_t type;
253
			configuration_attribute_t *ca;
254
			chunk_t value;
255
			cp_payload_t *cp;
256
			host_t *vip = NULL;
257

  
258 313
			DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
259 314
			if (config->get_pool(config))
260 315
			{
......
274 329
			DBG1(DBG_IKE, "assigning virtual IP %H to peer", vip);
275 330
			this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
276 331

  
277
			cp = cp_payload_create();
278
			cp->set_config_type(cp, CFG_REPLY);
279

  
280
			build_vip(this, vip, cp);
281
			vip->destroy(vip);
332
			cp = cp_payload_create_type(CFG_REPLY);
333
			cp->add_attribute(cp, build_vip(vip));
334
		}
282 335

  
283
			/* if we add an IP, we also look for other attributes */
284
			enumerator = lib->attributes->create_attribute_enumerator(
285
					lib->attributes, this->ike_sa->get_other_id(this->ike_sa));
286
			while (enumerator->enumerate(enumerator, &type, &value))
336
		/* query registered providers for additional attributes to include */
337
		enumerator = lib->attributes->create_responder_enumerator(
338
				lib->attributes, this->ike_sa->get_other_id(this->ike_sa), vip);
339
		while (enumerator->enumerate(enumerator, &type, &value))
340
		{
341
			if (!cp)
287 342
			{
288
				ca = configuration_attribute_create();
289
				ca->set_type(ca, type);
290
				ca->set_value(ca, value);
291
				cp->add_configuration_attribute(cp, ca);
343
				cp = cp_payload_create_type(CFG_REPLY);
292 344
			}
293
			enumerator->destroy(enumerator);
345
			cp->add_attribute(cp,
346
						configuration_attribute_create_value(type, value));
347
		}
348
		enumerator->destroy(enumerator);
294 349

  
350
		if (cp)
351
		{
295 352
			message->add_payload(message, (payload_t*)cp);
296 353
		}
354
		DESTROY_IF(vip);
297 355
		return SUCCESS;
298 356
	}
299 357
	return NEED_MORE;
......
335 393

  
336 394
	this->ike_sa = ike_sa;
337 395
	this->virtual_ip = NULL;
396
	this->requested->destroy_function(this->requested, free);
397
	this->requested = linked_list_create();
338 398
}
339 399

  
340 400
/**
......
343 403
static void destroy(private_ike_config_t *this)
344 404
{
345 405
	DESTROY_IF(this->virtual_ip);
406
	this->requested->destroy_function(this->requested, free);
346 407
	free(this);
347 408
}
348 409

  
......
360 421
	this->initiator = initiator;
361 422
	this->ike_sa = ike_sa;
362 423
	this->virtual_ip = NULL;
424
	this->requested = linked_list_create();
363 425

  
364 426
	if (initiator)
365 427
	{
b/src/libstrongswan/attributes/attribute_handler.h
22 22
#define ATTRIBUTE_HANDLER_H_
23 23

  
24 24
#include <chunk.h>
25
#include <utils/host.h>
25 26
#include <utils/identification.h>
26 27

  
27 28
#include "attributes.h"
......
56 57
	 */
57 58
	void (*release)(attribute_handler_t *this, identification_t *server,
58 59
					configuration_attribute_type_t type, chunk_t data);
60

  
61
	/**
62
	 * Enumerate attributes to request from a server.
63
	 *
64
	 * @param server		server identity to request attributes from
65
	 * @param vip			virtual IP we are requesting, if any
66
	 * @return				enumerator (configuration_attribute_type_t, chunk_t)
67
	 */
68
	enumerator_t* (*create_attribute_enumerator)(attribute_handler_t *this,
69
										identification_t *server, host_t *vip);
59 70
};
60 71

  
61 72
#endif /** ATTRIBUTE_HANDLER_H_ @}*/
b/src/libstrongswan/attributes/attribute_manager.c
48 48
};
49 49

  
50 50
/**
51
 * Data to pass to enumerator filters
52
 */
53
typedef struct {
54
	/** server/peer identity */
55
	identification_t *id;
56
	/** requesting/assigned virtual IP */
57
	host_t *vip;
58
} enum_data_t;
59

  
60
/**
51 61
 * Implementation of attribute_manager_t.acquire_address.
52 62
 */
53 63
static host_t* acquire_address(private_attribute_manager_t *this,
......
108 118
}
109 119

  
110 120
/**
111
 * inner enumerator constructor for attributes
121
 * inner enumerator constructor for responder attributes
112 122
 */
113
static enumerator_t *attrib_enum_create(attribute_provider_t *provider,
114
										identification_t *id)
123
static enumerator_t *responder_enum_create(attribute_provider_t *provider,
124
										   enum_data_t *data)
115 125
{
116
	return provider->create_attribute_enumerator(provider, id);
126
	return provider->create_attribute_enumerator(provider, data->id, data->vip);
117 127
}
118 128

  
119 129
/**
120
 * Implementation of attribute_manager_t.create_attribute_enumerator
130
 * Implementation of attribute_manager_t.create_responder_enumerator
121 131
 */
122
static enumerator_t* create_attribute_enumerator(
123
						private_attribute_manager_t *this, identification_t *id)
132
static enumerator_t* create_responder_enumerator(
133
			private_attribute_manager_t *this, identification_t *id, host_t *vip)
124 134
{
135
	enum_data_t *data = malloc_thing(enum_data_t);
136

  
137
	data->id = id;
138
	data->vip = vip;
125 139
	this->lock->read_lock(this->lock);
126 140
	return enumerator_create_cleaner(
127 141
				enumerator_create_nested(
128 142
					this->providers->create_enumerator(this->providers),
129
					(void*)attrib_enum_create, id, NULL),
143
					(void*)responder_enum_create, data, free),
130 144
				(void*)this->lock->unlock, this->lock);
131 145
}
132 146

  
......
156 170
 * Implementation of attribute_manager_t.handle
157 171
 */
158 172
static attribute_handler_t* handle(private_attribute_manager_t *this,
159
								   identification_t *server,
160
								   configuration_attribute_type_t type,
161
								   chunk_t data)
173
						identification_t *server, attribute_handler_t *handler,
174
						configuration_attribute_type_t type, chunk_t data)
162 175
{
163 176
	enumerator_t *enumerator;
164 177
	attribute_handler_t *current, *handled = NULL;
165 178

  
166 179
	this->lock->read_lock(this->lock);
180

  
181
	/* try to find the passed handler */
167 182
	enumerator = this->handlers->create_enumerator(this->handlers);
168 183
	while (enumerator->enumerate(enumerator, &current))
169 184
	{
170
		if (current->handle(current, server, type, data))
185
		if (current == handler && current->handle(current, server, type, data))
171 186
		{
172 187
			handled = current;
173 188
			break;
174 189
		}
175 190
	}
176 191
	enumerator->destroy(enumerator);
192
	if (!handled)
193
	{	/* handler requesting this attribute not found, try any other */
194
		enumerator = this->handlers->create_enumerator(this->handlers);
195
		while (enumerator->enumerate(enumerator, &current))
196
		{
197
			if (current->handle(current, server, type, data))
198
			{
199
				handled = current;
200
				break;
201
			}
202
		}
203
		enumerator->destroy(enumerator);
204
	}
177 205
	this->lock->unlock(this->lock);
178 206

  
179 207
	if (!handled)
......
210 238
}
211 239

  
212 240
/**
241
 * inner enumerator constructor for initiator attributes
242
 */
243
static enumerator_t *initiator_enum_create(attribute_handler_t *handler,
244
										   enum_data_t *data)
245
{
246
	return handler->create_attribute_enumerator(handler, data->id, data->vip);
247
}
248

  
249
/**
250
 * Implementation of attribute_manager_t.create_initiator_enumerator
251
 */
252
static enumerator_t* create_initiator_enumerator(
253
		private_attribute_manager_t *this, identification_t *id, host_t *vip)
254
{
255
	enum_data_t *data = malloc_thing(enum_data_t);
256

  
257
	data->id = id;
258
	data->vip = vip;
259
	this->lock->read_lock(this->lock);
260
	return enumerator_create_cleaner(
261
				enumerator_create_nested(
262
					this->handlers->create_enumerator(this->handlers),
263
					(void*)initiator_enum_create, data, free),
264
				(void*)this->lock->unlock, this->lock);
265
}
266

  
267
/**
213 268
 * Implementation of attribute_manager_t.add_handler
214 269
 */
215 270
static void add_handler(private_attribute_manager_t *this,
......
251 306

  
252 307
	this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,host_t*))acquire_address;
253 308
	this->public.release_address = (void(*)(attribute_manager_t*, char *, host_t*, identification_t*))release_address;
254
	this->public.create_attribute_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t*))create_attribute_enumerator;
309
	this->public.create_responder_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t*, host_t*))create_responder_enumerator;
255 310
	this->public.add_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))add_provider;
256 311
	this->public.remove_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))remove_provider;
257
	this->public.handle = (attribute_handler_t*(*)(attribute_manager_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle;
312
	this->public.handle = (attribute_handler_t*(*)(attribute_manager_t*,identification_t*, attribute_handler_t*, configuration_attribute_type_t, chunk_t))handle;
258 313
	this->public.release = (void(*)(attribute_manager_t*, attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))release;
314
	this->public.create_initiator_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t*, host_t*))create_initiator_enumerator;
259 315
	this->public.add_handler = (void(*)(attribute_manager_t*, attribute_handler_t*))add_handler;
260 316
	this->public.remove_handler = (void(*)(attribute_manager_t*, attribute_handler_t*))remove_handler;
261 317
	this->public.destroy = (void(*)(attribute_manager_t*))destroy;
b/src/libstrongswan/attributes/attribute_manager.h
62 62
	 * Create an enumerator over attributes to hand out to a peer.
63 63
	 *
64 64
	 * @param id			peer identity to hand out attributes to
65
	 * @param vip			virtual IP to assign to peer, if any
65 66
	 * @return				enumerator (configuration_attribute_type_t, chunk_t)
66 67
	 */
67
	enumerator_t* (*create_attribute_enumerator)(attribute_manager_t *this,
68
												 identification_t *id);
68
	enumerator_t* (*create_responder_enumerator)(attribute_manager_t *this,
69
											identification_t *id, host_t *vip);
69 70

  
70 71
	/**
71 72
	 * Register an attribute provider to the manager.
......
86 87
	 * Handle a configuration attribute by passing them to the handlers.
87 88
	 *
88 89
	 * @param server		server from which the attribute was received
90
	 * @param handler		handler we requested the attribute for, if any
89 91
	 * @param type			type of configuration attribute
90 92
	 * @param data			associated attribute data
91 93
	 * @return				handler which handled this attribute, NULL if none
92 94
	 */
93 95
	attribute_handler_t* (*handle)(attribute_manager_t *this,
94
							identification_t *server,
95
							configuration_attribute_type_t type, chunk_t data);
96
						identification_t *server, attribute_handler_t *handler,
97
						configuration_attribute_type_t type, chunk_t data);
96 98

  
97 99
	/**
98 100
	 * Release an attribute previously handle()d by a handler.
......
108 110
						chunk_t data);
109 111

  
110 112
	/**
113
	 * Create an enumerator over attributes to request from server.
114
	 *
115
	 * @param id			server identity to hand out attributes to
116
	 * @param vip			virtual IP going to request, if any
117
	 * @return				enumerator (attribute_handler_t, ca_type_t, chunk_t)
118
	 */
119
	enumerator_t* (*create_initiator_enumerator)(attribute_manager_t *this,
120
											identification_t *id, host_t *vip);
121

  
122
	/**
111 123
	 * Register an attribute handler to the manager.
112 124
	 *
113 125
	 * @param handler		attribute handler to register
b/src/libstrongswan/attributes/attribute_provider.h
57 57
	 * Create an enumerator over attributes to hand out to a peer.
58 58
	 *
59 59
	 * @param id			peer ID
60
	 * @param vip			virtual IP to assign to peer, if any
60 61
	 * @return				enumerator (configuration_attribute_type_t, chunk_t)
61 62
	 */
62 63
	enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this,
63
												 identification_t *id);
64
											identification_t *id, host_t *vip);
64 65
};
65 66

  
66 67
#endif /** ATTRIBUTE_PROVIDER_H_ @}*/
b/src/libstrongswan/plugins/attr_sql/sql_attribute.c
341 341

  
342 342
	this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *, host_t *))acquire_address;
343 343
	this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
344
	this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))enumerator_create_empty;
344
	this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id, host_t *host))enumerator_create_empty;
345 345
	this->public.destroy = (void(*)(sql_attribute_t*))destroy;
346 346

  
347 347
	this->db = db;

Also available in: Unified diff