- cleaned up logging
[strongswan.git] / Source / charon / message.c
1 /**
2 * @file message.c
3 *
4 * @brief Class message_t. Object of this type represents an IKEv2-Message.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include <stdlib.h>
24
25 #include "message.h"
26
27 #include "types.h"
28 #include "globals.h"
29 #include "ike_sa_id.h"
30 #include "generator.h"
31 #include "utils/linked_list.h"
32 #include "utils/allocator.h"
33 #include "utils/logger_manager.h"
34 #include "payloads/encodings.h"
35 #include "payloads/payload.h"
36 #include "parser.h"
37
38
39 /**
40 * Supported payload entry used in message_rule_t
41 *
42 */
43 typedef struct supported_payload_entry_s supported_payload_entry_t;
44
45 struct supported_payload_entry_s {
46 /**
47 * Payload type
48 */
49 payload_type_t payload_type;
50
51 /**
52 * Minimal occurence of this payload
53 */
54 size_t min_occurence;
55
56 /**
57 * Max occurence of this payload
58 */
59 size_t max_occurence;
60 };
61
62 /**
63 * Message Rule used to find out which payloads are supported by each message type
64 *
65 */
66 typedef struct message_rule_s message_rule_t;
67
68 struct message_rule_s {
69 /**
70 * Type of message
71 */
72 exchange_type_t exchange_type;
73
74 /**
75 * Is message a request or response
76 */
77 bool is_request;
78 /**
79 * Number of supported payloads
80 */
81 size_t supported_payloads_count;
82 /**
83 * Pointer to first supported payload entry
84 */
85 supported_payload_entry_t *supported_payloads;
86 };
87
88 /**
89 * message rule for ike_sa_init from initiator
90 */
91 static supported_payload_entry_t supported_ike_sa_init_i_payloads[] =
92 {
93 {SECURITY_ASSOCIATION,1,1},
94 {KEY_EXCHANGE,1,1},
95 {NONCE,1,1},
96 };
97
98 /**
99 * message rule for ike_sa_init from responder
100 */
101 static supported_payload_entry_t supported_ike_sa_init_r_payloads[] =
102 {
103 {SECURITY_ASSOCIATION,1,1},
104 {KEY_EXCHANGE,1,1},
105 {NONCE,1,1},
106 };
107
108
109 /**
110 * message rules, defines allowed payloads
111 */
112 static message_rule_t message_rules[] = {
113 {IKE_SA_INIT,TRUE,(sizeof(supported_ike_sa_init_i_payloads)/sizeof(supported_payload_entry_t)),supported_ike_sa_init_i_payloads},
114 {IKE_SA_INIT,FALSE,(sizeof(supported_ike_sa_init_r_payloads)/sizeof(supported_payload_entry_t)),supported_ike_sa_init_r_payloads}
115 };
116
117 /**
118 * Entry for a payload in the internal used linked list
119 *
120 */
121 typedef struct payload_entry_s payload_entry_t;
122
123 struct payload_entry_s {
124 /**
125 * Type of payload
126 */
127 payload_type_t payload_type;
128 /**
129 * Data struct holding the data of given payload
130 */
131 void *data_struct;
132 };
133
134
135 /**
136 * Private data of an message_t object
137 */
138 typedef struct private_message_s private_message_t;
139
140 struct private_message_s {
141
142 /**
143 * Public part of a message_t object
144 */
145 message_t public;
146
147
148 /**
149 * Minor version of message
150 */
151 u_int8_t major_version;
152
153 /**
154 * Major version of message
155 */
156 u_int8_t minor_version;
157
158 /**
159 * First Payload in message
160 */
161 payload_type_t first_payload;
162
163 /**
164 * Assigned exchange type
165 */
166 exchange_type_t exchange_type;
167
168
169 /**
170 * TRUE if message is request.
171 * FALSE if message is reply.
172 */
173 bool is_request;
174
175 /**
176 * Message ID of this message
177 */
178 u_int32_t message_id;
179
180 /**
181 * ID of assigned IKE_SA
182 */
183 ike_sa_id_t *ike_sa_id;
184
185 /**
186 * Assigned UDP packet.
187 *
188 * Stores incoming packet or last generated one.
189 */
190 packet_t *packet;
191
192 /**
193 * Linked List where payload data are stored in
194 */
195 linked_list_t *payloads;
196
197 /**
198 * Assigned parser to parse Header and Body of this message
199 */
200 parser_t *parser;
201
202 /**
203 * logger for this message
204 */
205 logger_t *logger;
206
207 /**
208 * Gets a list of supported payloads of this message type
209 *
210 * @param this calling object
211 * @param[out] supported_payloads first entry of supported payloads
212 * @param[out] supported_payloads_count number of supported payload entries
213 *
214 * @return SUCCESS
215 * NOT_FOUND if no supported payload definition could be found
216 */
217 status_t (*get_supported_payloads) (private_message_t *this, supported_payload_entry_t **supported_payloads,size_t *supported_payloads_count);
218
219 };
220
221 /**
222 * Implements private_message_t's get_supported_payloads function.
223 * See #private_message_t.get_supported_payloads.
224 */
225 status_t get_supported_payloads (private_message_t *this, supported_payload_entry_t **supported_payloads,size_t *supported_payloads_count)
226 {
227 int i;
228 exchange_type_t exchange_type = this->public.get_exchange_type(&(this->public));
229 bool is_request = this->public.get_request(&(this->public));
230
231
232 for (i = 0; i < (sizeof(message_rules) / sizeof(message_rule_t)); i++)
233 {
234 if ((exchange_type == message_rules[i].exchange_type) &&
235 (is_request == message_rules[i].is_request))
236 {
237 /* found rule for given exchange_type*/
238 *supported_payloads = message_rules[i].supported_payloads;
239 *supported_payloads_count = message_rules[i].supported_payloads_count;
240
241 return SUCCESS;
242 }
243
244
245 }
246 *supported_payloads = NULL;
247 *supported_payloads_count = 0;
248 return NOT_FOUND;
249 }
250
251 /**
252 * Implements message_t's set_ike_sa_id function.
253 * See #message_s.set_ike_sa_id.
254 */
255 static status_t set_ike_sa_id (private_message_t *this,ike_sa_id_t *ike_sa_id)
256 {
257 status_t status;
258 status = ike_sa_id->clone(ike_sa_id,&(this->ike_sa_id));
259 return status;
260 }
261
262 /**
263 * Implements message_t's get_ike_sa_id function.
264 * See #message_s.get_ike_sa_id.
265 */
266 static status_t get_ike_sa_id (private_message_t *this,ike_sa_id_t **ike_sa_id)
267 {
268 status_t status;
269 if (this->ike_sa_id == NULL)
270 {
271 return FAILED;
272 }
273 status = this->ike_sa_id->clone(this->ike_sa_id,ike_sa_id);
274 return status;
275 }
276
277
278 /**
279 * Implements message_t's set_message_id function.
280 * See #message_s.set_message_id.
281 */
282 static status_t set_message_id (private_message_t *this,u_int32_t message_id)
283 {
284 this->message_id = message_id;
285 return SUCCESS;
286 }
287
288
289 /**
290 * Implements message_t's set_message_id function.
291 * See #message_s.set_message_id.
292 */
293 static u_int32_t get_message_id (private_message_t *this)
294 {
295 return this->message_id;
296 }
297
298 /**
299 * Implements message_t's set_major_version function.
300 * See #message_s.set_major_version.
301 */
302 static status_t set_major_version (private_message_t *this,u_int8_t major_version)
303 {
304 this->major_version = major_version;
305 return SUCCESS;
306 }
307
308
309 /**
310 * Implements message_t's get_major_version function.
311 * See #message_s.get_major_version.
312 */
313 static u_int8_t get_major_version (private_message_t *this)
314 {
315 return this->major_version;
316 }
317
318 /**
319 * Implements message_t's set_minor_version function.
320 * See #message_s.set_minor_version.
321 */
322 static status_t set_minor_version (private_message_t *this,u_int8_t minor_version)
323 {
324 this->minor_version = minor_version;
325 return SUCCESS;
326 }
327
328
329 /**
330 * Implements message_t's get_minor_version function.
331 * See #message_s.get_minor_version.
332 */
333 static u_int8_t get_minor_version (private_message_t *this)
334 {
335 return this->minor_version;
336 }
337
338 /**
339 * Implements message_t's set_exchange_type function.
340 * See #message_s.set_exchange_type.
341 */
342 static status_t set_exchange_type (private_message_t *this,exchange_type_t exchange_type)
343 {
344 this->exchange_type = exchange_type;
345 return SUCCESS;
346 }
347
348
349 /**
350 * Implements message_t's get_exchange_type function.
351 * See #message_s.get_exchange_type.
352 */
353 static exchange_type_t get_exchange_type (private_message_t *this)
354 {
355 return this->exchange_type;
356 }
357
358
359 /**
360 * Implements message_t's set_request function.
361 * See #message_s.set_request.
362 */
363 static status_t set_request (private_message_t *this,bool request)
364 {
365 this->is_request = request;
366 return SUCCESS;
367 }
368
369 /**
370 * Implements message_t's get_request function.
371 * See #message_s.get_request.
372 */
373 static exchange_type_t get_request (private_message_t *this)
374 {
375 return this->is_request;
376 }
377
378 static status_t add_payload(private_message_t *this, payload_t *payload)
379 {
380 payload_t *last_payload;
381 if ((this->payloads->get_count(this->payloads) > 0) &&
382 (this->payloads->get_last(this->payloads,(void **) &last_payload) != SUCCESS))
383 {
384 return OUT_OF_RES;
385 }
386
387 if (this->payloads->insert_last(this->payloads, payload) != SUCCESS)
388 {
389 return OUT_OF_RES;
390 }
391 if (this->payloads->get_count(this->payloads) == 1)
392 {
393 this->first_payload = payload->get_type(payload);
394 }
395 else
396 {
397 last_payload->set_next_type(last_payload,payload->get_type(payload));
398 }
399
400 this->logger->log(this->logger, CONTROL|MORE, "added payload of type %s to message",
401 mapping_find(payload_type_m, payload->get_type(payload)));
402
403 return SUCCESS;
404 }
405
406 static status_t set_source(private_message_t *this, host_t *host)
407 {
408 if (this->packet->source != NULL)
409 {
410 this->packet->source->destroy(this->packet->source);
411 }
412 this->packet->source = host;
413 return SUCCESS;
414 }
415
416 static status_t set_destination(private_message_t *this, host_t *host)
417 {
418 if (this->packet->destination != NULL)
419 {
420 this->packet->destination->destroy(this->packet->destination);
421 }
422 this->packet->destination = host;
423 return SUCCESS;
424 }
425
426 static status_t get_source(private_message_t *this, host_t **host)
427 {
428 *host = this->packet->source;
429 return SUCCESS;
430 }
431
432 static status_t get_destination(private_message_t *this, host_t **host)
433 {
434 *host = this->packet->destination;
435 return SUCCESS;
436 }
437
438
439 static status_t get_payload_iterator(private_message_t *this, linked_list_iterator_t **iterator)
440 {
441 return this->payloads->create_iterator(this->payloads, iterator, TRUE);
442 }
443
444
445 /**
446 * Implements message_t's generate function.
447 * See #message_s.generate.
448 */
449 static status_t generate(private_message_t *this, packet_t **packet)
450 {
451 generator_t *generator;
452 ike_header_t *ike_header;
453 payload_t *payload, *next_payload;
454 linked_list_iterator_t *iterator;
455 status_t status;
456
457
458 this->logger->log(this->logger, CONTROL, "generating message, contains %d payloads",
459 this->payloads->get_count(this->payloads));
460
461 if (this->packet != NULL)
462 {
463 /* already generated packet is just cloned */
464 this->packet->clone(this->packet, packet);
465 }
466
467 if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED)
468 {
469 this->logger->log(this->logger, ERROR, "exchange type is not defined");
470 return INVALID_STATE;
471 }
472
473 if (this->packet->source == NULL ||
474 this->packet->destination == NULL)
475 {
476 this->logger->log(this->logger, ERROR, "source/destination not defined");
477 return INVALID_STATE;
478 }
479
480
481 ike_header = ike_header_create();
482 if (ike_header == NULL)
483 {
484 return OUT_OF_RES;
485 }
486
487
488 ike_header->set_exchange_type(ike_header, this->exchange_type);
489 ike_header->set_message_id(ike_header, this->message_id);
490 ike_header->set_response_flag(ike_header, !this->is_request);
491 ike_header->set_initiator_flag(ike_header, this->ike_sa_id->is_initiator(this->ike_sa_id));
492 ike_header->set_initiator_spi(ike_header, this->ike_sa_id->get_initiator_spi(this->ike_sa_id));
493 ike_header->set_responder_spi(ike_header, this->ike_sa_id->get_responder_spi(this->ike_sa_id));
494
495 generator = generator_create();
496 if (generator == NULL)
497 {
498 return OUT_OF_RES;
499 }
500
501 payload = (payload_t*)ike_header;
502
503 if (this->payloads->create_iterator(this->payloads, &iterator, TRUE) != SUCCESS)
504 {
505 generator->destroy(generator);
506 ike_header->destroy(ike_header);
507 return OUT_OF_RES;
508 }
509 while(iterator->has_next(iterator))
510 {
511 iterator->current(iterator, (void**)&next_payload);
512 payload->set_next_type(payload, next_payload->get_type(next_payload));
513 status = generator->generate_payload(generator, payload);
514 if (status != SUCCESS)
515 {
516 generator->destroy(generator);
517 ike_header->destroy(ike_header);
518 return status;
519 }
520 payload = next_payload;
521 }
522 iterator->destroy(iterator);
523
524 payload->set_next_type(payload, NO_PAYLOAD);
525 status = generator->generate_payload(generator, payload);
526 if (status != SUCCESS)
527 {
528 generator->destroy(generator);
529 ike_header->destroy(ike_header);
530 return status;
531 }
532
533 ike_header->destroy(ike_header);
534
535
536
537 if (this->packet->data.ptr != NULL)
538 {
539 allocator_free(this->packet->data.ptr);
540 }
541
542 status = generator->write_to_chunk(generator, &(this->packet->data));
543 if (status != SUCCESS)
544 {
545 generator->destroy(generator);
546 return status;
547 }
548
549 this->packet->clone(this->packet, packet);
550
551 generator->destroy(generator);
552
553
554 this->logger->log(this->logger, CONTROL, "message generated successfully");
555 return SUCCESS;
556 }
557
558 /**
559 * Implements message_t's parse_header function.
560 * See #message_s.parse_header.
561 */
562 static status_t parse_header(private_message_t *this)
563 {
564 ike_header_t *ike_header;
565 status_t status;
566
567
568 this->logger->log(this->logger, CONTROL, "parsing header of message");
569
570 this->parser->reset_context(this->parser);
571 status = this->parser->parse_payload(this->parser,HEADER,(payload_t **) &ike_header);
572 if (status != SUCCESS)
573 {
574 this->logger->log(this->logger, ERROR, "Header could not be parsed");
575 return status;
576
577 }
578
579 /* verify payload */
580 status = ike_header->payload_interface.verify(&(ike_header->payload_interface));
581 if (status != SUCCESS)
582 {
583 this->logger->log(this->logger, ERROR, "Header verification failed");
584 return status;
585 }
586
587 if (this->ike_sa_id != NULL)
588 {
589 this->ike_sa_id->destroy(this->ike_sa_id);
590 }
591
592 this->ike_sa_id = ike_sa_id_create(ike_header->get_initiator_spi(ike_header),
593 ike_header->get_responder_spi(ike_header),
594 ike_header->get_initiator_flag(ike_header));
595 if (this->ike_sa_id == NULL)
596 {
597 this->logger->log(this->logger, ERROR, "could not create ike_sa_id object");
598 ike_header->destroy(ike_header);
599 return OUT_OF_RES;
600 }
601 this->exchange_type = ike_header->get_exchange_type(ike_header);
602 this->message_id = ike_header->get_message_id(ike_header);
603 this->is_request = (!(ike_header->get_response_flag(ike_header)));
604 this->major_version = ike_header->get_maj_version(ike_header);
605 this->minor_version = ike_header->get_min_version(ike_header);
606 this->first_payload = ike_header->payload_interface.get_next_type(&(ike_header->payload_interface));
607
608
609 this->logger->log(this->logger, CONTROL, "parsing header successfully");
610
611 ike_header->destroy(ike_header);
612 return SUCCESS;
613 }
614
615 /**
616 * Implements message_t's parse_body function.
617 * See #message_s.parse_body.
618 */
619 static status_t parse_body (private_message_t *this)
620 {
621 status_t status = SUCCESS;
622 int i;
623 payload_type_t current_payload_type = this->first_payload;
624 supported_payload_entry_t *supported_payloads;
625 size_t supported_payloads_count;
626
627
628 this->logger->log(this->logger, CONTROL, "parsing body of message");
629
630 if (this->get_supported_payloads (this, &supported_payloads, &supported_payloads_count) != SUCCESS)
631 {
632 this->logger->log(this->logger, ERROR, "could not get supported payloads");
633 return FAILED;
634 }
635
636 while (current_payload_type != NO_PAYLOAD)
637 {
638 payload_t *current_payload;
639 bool supported = FALSE;
640
641 this->logger->log(this->logger, CONTROL|MORE, "start parsing payload of type %s",
642 mapping_find(payload_type_m, current_payload_type));
643 for (i = 0; i < supported_payloads_count;i++)
644 {
645 if (supported_payloads[i].payload_type == current_payload_type)
646 {
647 supported = TRUE;
648 break;
649 }
650 }
651 if (!supported && (current_payload_type != NO_PAYLOAD))
652 {
653 /* type not supported */
654 status = NOT_SUPPORTED;
655 this->logger->log(this->logger, ERROR, "payload type %s not supported",mapping_find(payload_type_m,current_payload_type));
656 break;
657 }
658
659 status = this->parser->parse_payload(this->parser,current_payload_type,(payload_t **) &current_payload);
660 if (status != SUCCESS)
661 {
662 this->logger->log(this->logger, ERROR, "payload type %s could not be parsed",mapping_find(payload_type_m,current_payload_type));
663 break;
664 }
665
666 status = current_payload->verify(current_payload);
667 if (status != SUCCESS)
668 {
669 this->logger->log(this->logger, ERROR, "payload type %s could not be verified",mapping_find(payload_type_m,current_payload_type));
670 status = VERIFY_ERROR;
671 break;
672 }
673
674 /* get next payload type */
675 current_payload_type = current_payload->get_next_type(current_payload);
676
677 status = this->payloads->insert_last(this->payloads,current_payload);
678 if (status != SUCCESS)
679 {
680 this->logger->log(this->logger, ERROR, "Could not insert current payload to internal list cause of ressource exhausting");
681 break;
682 }
683
684 }
685 if (status != SUCCESS)
686 {
687 /* already parsed payload is destroyed later in destroy call from outside this object */
688 }
689 else
690 {
691 linked_list_iterator_t *iterator;
692
693 status = this->payloads->create_iterator(this->payloads,&iterator,TRUE);
694 if (status != SUCCESS)
695 {
696 this->logger->log(this->logger, ERROR, "Could not create iterator to check supported payloads");
697 return status;
698 }
699
700 /* check for payloads with wrong count*/
701 for (i = 0; i < supported_payloads_count;i++)
702 {
703 size_t min_occurence = supported_payloads[i].min_occurence;
704 size_t max_occurence = supported_payloads[i].max_occurence;
705 payload_type_t payload_type = supported_payloads[i].payload_type;
706 size_t found_payloads = 0;
707
708 iterator->reset(iterator);
709
710 while(iterator->has_next(iterator))
711 {
712 payload_t *current_payload;
713 status = iterator->current(iterator,(void **)&current_payload);
714 if (status != SUCCESS)
715 {
716 this->logger->log(this->logger, ERROR, "Could not get payload from internal list");
717 iterator->destroy(iterator);
718 return status;
719 }
720 if (current_payload->get_type(current_payload) == payload_type)
721 {
722 found_payloads++;
723 if (found_payloads > max_occurence)
724 {
725 this->logger->log(this->logger, ERROR, "Payload of type %s more than %d times (%d) occured in current message",
726 mapping_find(payload_type_m,current_payload->get_type(current_payload)),max_occurence,found_payloads);
727 iterator->destroy(iterator);
728 return NOT_SUPPORTED;
729 }
730 }
731
732 }
733 if (found_payloads < min_occurence)
734 {
735 this->logger->log(this->logger, ERROR, "Payload of type %s not occured %d times",
736 mapping_find(payload_type_m,payload_type),min_occurence);
737 iterator->destroy(iterator);
738 return NOT_SUPPORTED;
739 }
740
741 }
742 iterator->destroy(iterator);
743 }
744 return status;
745 }
746
747
748
749 /**
750 * Implements message_t's destroy function.
751 * See #message_s.destroy.
752 */
753 static status_t destroy (private_message_t *this)
754 {
755 linked_list_iterator_t *iterator;
756
757 if (this->packet != NULL)
758 {
759 this->packet->destroy(this->packet);
760 }
761 if (this->ike_sa_id != NULL)
762 {
763 this->ike_sa_id->destroy(this->ike_sa_id);
764 }
765
766 this->payloads->create_iterator(this->payloads, &iterator, TRUE);
767 while (iterator->has_next(iterator))
768 {
769 payload_t *payload;
770 iterator->current(iterator, (void**)&payload);
771 this->logger->log(this->logger, CONTROL|MOST, "Destroying payload of type %s",
772 mapping_find(payload_type_m, payload->get_type(payload)));
773 payload->destroy(payload);
774 }
775 iterator->destroy(iterator);
776 this->payloads->destroy(this->payloads);
777 this->parser->destroy(this->parser);
778 global_logger_manager->destroy_logger(global_logger_manager, this->logger);
779
780 allocator_free(this);
781 return SUCCESS;
782 }
783
784 /*
785 * Described in Header-File
786 */
787 message_t *message_create_from_packet(packet_t *packet)
788 {
789 private_message_t *this = allocator_alloc_thing(private_message_t);
790 if (this == NULL)
791 {
792 return NULL;
793 }
794
795 /* public functions */
796 this->public.set_major_version = (status_t(*)(message_t*, u_int8_t))set_major_version;
797 this->public.get_major_version = (u_int8_t(*)(message_t*))get_major_version;
798 this->public.set_minor_version = (status_t(*)(message_t*, u_int8_t))set_minor_version;
799 this->public.get_minor_version = (u_int8_t(*)(message_t*))get_minor_version;
800 this->public.set_message_id = (status_t(*)(message_t*, u_int32_t))set_message_id;
801 this->public.get_message_id = (u_int32_t(*)(message_t*))get_message_id;
802 this->public.set_ike_sa_id = (status_t(*)(message_t*, ike_sa_id_t *))set_ike_sa_id;
803 this->public.get_ike_sa_id = (status_t(*)(message_t*, ike_sa_id_t **))get_ike_sa_id;
804 this->public.set_exchange_type = (status_t(*)(message_t*, exchange_type_t))set_exchange_type;
805 this->public.get_exchange_type = (exchange_type_t(*)(message_t*))get_exchange_type;
806 this->public.set_request = (status_t(*)(message_t*, bool))set_request;
807 this->public.get_request = (bool(*)(message_t*))get_request;
808 this->public.add_payload = (status_t(*)(message_t*,payload_t*))add_payload;
809 this->public.generate = (status_t (*) (message_t *, packet_t**)) generate;
810 this->public.set_source = (status_t (*) (message_t*,host_t*)) set_source;
811 this->public.get_source = (status_t (*) (message_t*,host_t**)) get_source;
812 this->public.set_destination = (status_t (*) (message_t*,host_t*)) set_destination;
813 this->public.get_destination = (status_t (*) (message_t*,host_t**)) get_destination;
814 this->public.get_payload_iterator = (status_t (*) (message_t *, linked_list_iterator_t **)) get_payload_iterator;
815 this->public.parse_header = (status_t (*) (message_t *)) parse_header;
816 this->public.parse_body = (status_t (*) (message_t *)) parse_body;
817 this->public.destroy = (status_t(*)(message_t*))destroy;
818
819 /* public values */
820 this->exchange_type = EXCHANGE_TYPE_UNDEFINED;
821 this->is_request = TRUE;
822 this->ike_sa_id = NULL;
823 this->first_payload = NO_PAYLOAD;
824 this->message_id = 0;
825
826 /* private functions */
827 this->get_supported_payloads = get_supported_payloads;
828
829 /* private values */
830 if (packet == NULL)
831 {
832 packet = packet_create();
833 }
834 if (packet == NULL)
835 {
836 allocator_free(this);
837 return NULL;
838 }
839 this->packet = packet;
840 this->payloads = linked_list_create();
841 if (this->payloads == NULL)
842 {
843 allocator_free(this);
844 return NULL;
845 }
846
847 /* parser is created from data of packet */
848 this->parser = parser_create(this->packet->data);
849 if (this->parser == NULL)
850 {
851 this->payloads->destroy(this->payloads);
852 allocator_free(this);
853 return NULL;
854 }
855
856 this->logger = global_logger_manager->create_logger(global_logger_manager, MESSAGE, NULL);
857 if (this->logger == NULL)
858 {
859 this->parser->destroy(this->parser);
860 this->payloads->destroy(this->payloads);
861 allocator_free(this);
862 return NULL;
863 }
864
865 return (&this->public);
866 }
867
868 /*
869 * Described in Header-File
870 */
871 message_t *message_create()
872 {
873 return message_create_from_packet(NULL);
874 }