2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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
18 #include "ha_sync_child.h"
20 typedef struct private_ha_sync_child_t private_ha_sync_child_t
;
23 * Private data of an ha_sync_child_t object.
25 struct private_ha_sync_child_t
{
28 * Public ha_sync_child_t interface.
30 ha_sync_child_t
public;
33 * socket we use for syncing
35 ha_sync_socket_t
*socket
;
38 * synced and cached IKE_SA state
40 ha_sync_cache_t
*cache
;
44 * Implementation of listener_t.child_keys
46 static bool child_keys(private_ha_sync_child_t
*this, ike_sa_t
*ike_sa
,
47 child_sa_t
*child_sa
, diffie_hellman_t
*dh
,
48 chunk_t nonce_i
, chunk_t nonce_r
)
55 enumerator_t
*enumerator
;
56 traffic_selector_t
*ts
;
58 if (this->cache
->has_ike_sa(this->cache
, ike_sa
->get_id(ike_sa
)))
59 { /* IKE_SA is cached, do not sync */
63 m
= ha_sync_message_create(HA_SYNC_CHILD_ADD
);
65 m
->add_attribute(m
, HA_SYNC_IKE_ID
, ike_sa
->get_id(ike_sa
));
66 m
->add_attribute(m
, HA_SYNC_INBOUND_SPI
, child_sa
->get_spi(child_sa
, TRUE
));
67 m
->add_attribute(m
, HA_SYNC_OUTBOUND_SPI
, child_sa
->get_spi(child_sa
, FALSE
));
68 m
->add_attribute(m
, HA_SYNC_INBOUND_CPI
, child_sa
->get_cpi(child_sa
, TRUE
));
69 m
->add_attribute(m
, HA_SYNC_OUTBOUND_CPI
, child_sa
->get_cpi(child_sa
, FALSE
));
70 m
->add_attribute(m
, HA_SYNC_IPSEC_MODE
, child_sa
->get_mode(child_sa
));
71 m
->add_attribute(m
, HA_SYNC_IPCOMP
, child_sa
->get_ipcomp(child_sa
));
72 m
->add_attribute(m
, HA_SYNC_CONFIG_NAME
, child_sa
->get_name(child_sa
));
74 proposal
= child_sa
->get_proposal(child_sa
);
75 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &alg
, &len
))
77 m
->add_attribute(m
, HA_SYNC_ALG_ENCR
, alg
);
80 m
->add_attribute(m
, HA_SYNC_ALG_ENCR_LEN
, len
);
83 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &alg
, NULL
))
85 m
->add_attribute(m
, HA_SYNC_ALG_INTEG
, alg
);
87 m
->add_attribute(m
, HA_SYNC_NONCE_I
, nonce_i
);
88 m
->add_attribute(m
, HA_SYNC_NONCE_R
, nonce_r
);
89 if (dh
&& dh
->get_shared_secret(dh
, &secret
) == SUCCESS
)
91 m
->add_attribute(m
, HA_SYNC_SECRET
, secret
);
95 list
= child_sa
->get_traffic_selectors(child_sa
, TRUE
);
96 enumerator
= list
->create_enumerator(list
);
97 while (enumerator
->enumerate(enumerator
, &ts
))
99 m
->add_attribute(m
, HA_SYNC_LOCAL_TS
, ts
);
101 enumerator
->destroy(enumerator
);
102 list
= child_sa
->get_traffic_selectors(child_sa
, FALSE
);
103 enumerator
= list
->create_enumerator(list
);
104 while (enumerator
->enumerate(enumerator
, &ts
))
106 m
->add_attribute(m
, HA_SYNC_REMOTE_TS
, ts
);
108 enumerator
->destroy(enumerator
);
110 this->socket
->push(this->socket
, m
);
117 * Implementation of listener_t.child_state_change
119 static bool child_state_change(private_ha_sync_child_t
*this, ike_sa_t
*ike_sa
,
120 child_sa_t
*child_sa
, child_sa_state_t state
)
122 if (this->cache
->has_ike_sa(this->cache
, ike_sa
->get_id(ike_sa
)))
123 { /* IKE_SA is cached, do not sync */
127 if (state
== CHILD_DESTROYING
)
129 ha_sync_message_t
*m
;
131 m
= ha_sync_message_create(HA_SYNC_CHILD_DELETE
);
133 m
->add_attribute(m
, HA_SYNC_IKE_ID
, ike_sa
->get_id(ike_sa
));
134 m
->add_attribute(m
, HA_SYNC_INBOUND_SPI
,
135 child_sa
->get_spi(child_sa
, TRUE
));
136 this->socket
->push(this->socket
, m
);
143 * Implementation of ha_sync_child_t.destroy.
145 static void destroy(private_ha_sync_child_t
*this)
153 ha_sync_child_t
*ha_sync_child_create(ha_sync_socket_t
*socket
,
154 ha_sync_cache_t
*cache
)
156 private_ha_sync_child_t
*this = malloc_thing(private_ha_sync_child_t
);
158 memset(&this->public.listener
, 0, sizeof(listener_t
));
159 this->public.listener
.child_keys
= (bool(*)(listener_t
*, ike_sa_t
*ike_sa
, child_sa_t
*child_sa
, diffie_hellman_t
*dh
, chunk_t nonce_i
, chunk_t nonce_r
))child_keys
;
160 this->public.listener
.child_state_change
= (bool(*)(listener_t
*,ike_sa_t
*ike_sa
, child_sa_t
*child_sa
, child_sa_state_t state
))child_state_change
;
161 this->public.destroy
= (void(*)(ha_sync_child_t
*))destroy
;
163 this->socket
= socket
;
166 return &this->public;