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 "quick_delete.h"
19 #include <encoding/payloads/delete_payload.h>
21 typedef struct private_quick_delete_t private_quick_delete_t
;
24 * Private members of a quick_delete_t task.
26 struct private_quick_delete_t
{
29 * Public methods and task_t interface.
31 quick_delete_t
public;
39 * Are we the initiator?
44 * Protocol of CHILD_SA to delete
46 protocol_id_t protocol
;
49 * Inbound SPI of CHILD_SA to delete
54 * Send delete even if SA does not exist
60 * Delete the specified CHILD_SA, if found
62 static bool delete_child(private_quick_delete_t
*this,
63 protocol_id_t protocol
, u_int32_t spi
)
65 u_int64_t bytes_in
, bytes_out
;
68 child_sa
= this->ike_sa
->get_child_sa(this->ike_sa
, protocol
, spi
, TRUE
);
70 { /* fallback and check for outbound SA */
71 child_sa
= this->ike_sa
->get_child_sa(this->ike_sa
, protocol
, spi
, FALSE
);
76 this->spi
= spi
= child_sa
->get_spi(child_sa
, TRUE
);
79 child_sa
->set_state(child_sa
, CHILD_DELETING
);
81 child_sa
->get_usestats(child_sa
, TRUE
, NULL
, &bytes_in
);
82 child_sa
->get_usestats(child_sa
, FALSE
, NULL
, &bytes_out
);
84 DBG0(DBG_IKE
, "closing CHILD_SA %s{%d} "
85 "with SPIs %.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R",
86 child_sa
->get_name(child_sa
), child_sa
->get_reqid(child_sa
),
87 ntohl(child_sa
->get_spi(child_sa
, TRUE
)), bytes_in
,
88 ntohl(child_sa
->get_spi(child_sa
, FALSE
)), bytes_out
,
89 child_sa
->get_traffic_selectors(child_sa
, TRUE
),
90 child_sa
->get_traffic_selectors(child_sa
, FALSE
));
92 charon
->bus
->child_updown(charon
->bus
, child_sa
, FALSE
);
94 this->ike_sa
->destroy_child_sa(this->ike_sa
, protocol
, spi
);
96 /* TODO-IKEv1: handle close action? */
101 METHOD(task_t
, build_i
, status_t
,
102 private_quick_delete_t
*this, message_t
*message
)
104 if (delete_child(this, this->protocol
, this->spi
) || this->force
)
106 delete_payload_t
*delete_payload
;
108 DBG1(DBG_IKE
, "sending DELETE for %N CHILD_SA with SPI %.8x",
109 protocol_id_names
, this->protocol
, ntohl(this->spi
));
111 delete_payload
= delete_payload_create(DELETE_V1
, PROTO_ESP
);
112 delete_payload
->add_spi(delete_payload
, this->spi
);
113 message
->add_payload(message
, &delete_payload
->payload_interface
);
120 METHOD(task_t
, process_i
, status_t
,
121 private_quick_delete_t
*this, message_t
*message
)
126 METHOD(task_t
, process_r
, status_t
,
127 private_quick_delete_t
*this, message_t
*message
)
129 enumerator_t
*payloads
, *spis
;
131 delete_payload_t
*delete_payload
;
132 protocol_id_t protocol
;
135 payloads
= message
->create_payload_enumerator(message
);
136 while (payloads
->enumerate(payloads
, &payload
))
138 if (payload
->get_type(payload
) == DELETE_V1
)
140 delete_payload
= (delete_payload_t
*)payload
;
141 protocol
= delete_payload
->get_protocol_id(delete_payload
);
142 if (protocol
!= PROTO_ESP
&& protocol
!= PROTO_AH
)
146 spis
= delete_payload
->create_spi_enumerator(delete_payload
);
147 while (spis
->enumerate(spis
, &spi
))
149 DBG1(DBG_IKE
, "received DELETE for %N CHILD_SA with SPI %.8x",
150 protocol_id_names
, protocol
, ntohl(spi
));
151 if (!delete_child(this, protocol
, spi
))
153 DBG1(DBG_IKE
, "CHILD_SA not found, ignored");
160 payloads
->destroy(payloads
);
165 METHOD(task_t
, build_r
, status_t
,
166 private_quick_delete_t
*this, message_t
*message
)
171 METHOD(task_t
, get_type
, task_type_t
,
172 private_quick_delete_t
*this)
174 return TASK_QUICK_DELETE
;
177 METHOD(task_t
, migrate
, void,
178 private_quick_delete_t
*this, ike_sa_t
*ike_sa
)
180 this->ike_sa
= ike_sa
;
183 METHOD(task_t
, destroy
, void,
184 private_quick_delete_t
*this)
190 * Described in header.
192 quick_delete_t
*quick_delete_create(ike_sa_t
*ike_sa
, protocol_id_t protocol
,
193 u_int32_t spi
, bool force
)
195 private_quick_delete_t
*this;
200 .get_type
= _get_type
,
206 .protocol
= protocol
,
211 if (protocol
!= PROTO_NONE
)
213 this->public.task
.build
= _build_i
;
214 this->public.task
.process
= _process_i
;
218 this->public.task
.build
= _build_r
;
219 this->public.task
.process
= _process_r
;
221 return &this->public;