2 * Copyright (C) 2011 Martin Willi
3 * Copyright (C) 2011 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "informational.h"
19 #include <sa/ikev1/tasks/isakmp_delete.h>
20 #include <sa/ikev1/tasks/quick_delete.h>
22 #include <encoding/payloads/delete_payload.h>
24 typedef struct private_informational_t private_informational_t
;
27 * Private members of a informational_t task.
29 struct private_informational_t
{
32 * Public methods and task_t interface.
34 informational_t
public;
42 * Notify payload to send
44 notify_payload_t
*notify
;
53 * Cancel active quick mode after receiving an error
55 static void cancel_quick_mode(private_informational_t
*this)
57 enumerator_t
*enumerator
;
60 enumerator
= this->ike_sa
->create_task_enumerator(this->ike_sa
,
62 while (enumerator
->enumerate(enumerator
, &task
))
64 if (task
->get_type(task
) == TASK_QUICK_MODE
)
66 this->ike_sa
->flush_queue(this->ike_sa
, TASK_QUEUE_ACTIVE
);
70 enumerator
->destroy(enumerator
);
73 METHOD(task_t
, build_i
, status_t
,
74 private_informational_t
*this, message_t
*message
)
76 message
->add_payload(message
, &this->notify
->payload_interface
);
81 METHOD(task_t
, process_r
, status_t
,
82 private_informational_t
*this, message_t
*message
)
84 enumerator_t
*enumerator
;
85 delete_payload_t
*delete;
86 notify_payload_t
*notify
;
89 status_t status
= SUCCESS
;
91 enumerator
= message
->create_payload_enumerator(message
);
92 while (enumerator
->enumerate(enumerator
, &payload
))
94 switch (payload
->get_type(payload
))
97 notify
= (notify_payload_t
*)payload
;
98 type
= notify
->get_notify_type(notify
);
100 if (type
== INITIAL_CONTACT_IKEV1
)
102 this->ike_sa
->set_condition(this->ike_sa
,
103 COND_INIT_CONTACT_SEEN
, TRUE
);
105 else if (type
== UNITY_LOAD_BALANCE
)
107 host_t
*redirect
, *me
;
110 data
= notify
->get_notification_data(notify
);
111 redirect
= host_create_from_chunk(AF_INET
, data
,
114 { /* treat the redirect as reauthentication */
115 DBG1(DBG_IKE
, "received %N notify. redirected to %H",
116 notify_type_names
, type
, redirect
);
117 /* Cisco boxes reject the first message from 4500 */
118 me
= this->ike_sa
->get_my_host(this->ike_sa
);
119 me
->set_port(me
, CHARON_UDP_PORT
);
120 this->ike_sa
->set_other_host(this->ike_sa
, redirect
);
121 this->ike_sa
->reauth(this->ike_sa
);
122 enumerator
->destroy(enumerator
);
127 DBG1(DBG_IKE
, "received %N notify, invalid address");
130 else if (type
< 16384)
132 DBG1(DBG_IKE
, "received %N error notify",
133 notify_type_names
, type
);
134 if (this->ike_sa
->get_state(this->ike_sa
) == IKE_CONNECTING
)
135 { /* only critical during main mode */
140 case INVALID_ID_INFORMATION
:
141 case NO_PROPOSAL_CHOSEN
:
142 cancel_quick_mode(this);
151 DBG1(DBG_IKE
, "received %N notify",
152 notify_type_names
, type
);
158 delete = (delete_payload_t
*)payload
;
159 if (delete->get_protocol_id(delete) == PROTO_IKE
)
161 this->del
= (task_t
*)isakmp_delete_create(this->ike_sa
,
166 this->del
= (task_t
*)quick_delete_create(this->ike_sa
,
167 PROTO_NONE
, 0, FALSE
, FALSE
);
176 enumerator
->destroy(enumerator
);
178 if (this->del
&& status
== SUCCESS
)
180 return this->del
->process(this->del
, message
);
185 METHOD(task_t
, build_r
, status_t
,
186 private_informational_t
*this, message_t
*message
)
190 return this->del
->build(this->del
, message
);
195 METHOD(task_t
, process_i
, status_t
,
196 private_informational_t
*this, message_t
*message
)
201 METHOD(task_t
, get_type
, task_type_t
,
202 private_informational_t
*this)
204 return TASK_INFORMATIONAL
;
207 METHOD(task_t
, migrate
, void,
208 private_informational_t
*this, ike_sa_t
*ike_sa
)
210 this->ike_sa
= ike_sa
;
213 METHOD(task_t
, destroy
, void,
214 private_informational_t
*this)
216 DESTROY_IF(this->notify
);
217 DESTROY_IF(this->del
);
222 * Described in header.
224 informational_t
*informational_create(ike_sa_t
*ike_sa
, notify_payload_t
*notify
)
226 private_informational_t
*this;
231 .get_type
= _get_type
,
242 this->public.task
.build
= _build_i
;
243 this->public.task
.process
= _process_i
;
247 this->public.task
.build
= _build_r
;
248 this->public.task
.process
= _process_r
;
251 return &this->public;