2 * Copyright (C) 2010-2016 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * HSR Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 #include "android_service.h"
22 #include "android_dns_proxy.h"
23 #include "../charonservice.h"
24 #include "../vpnservice_builder.h"
29 #include <processing/jobs/callback_job.h>
30 #include <threading/rwlock.h>
31 #include <threading/thread.h>
33 typedef struct private_android_service_t private_android_service_t
;
36 * private data of Android service
38 struct private_android_service_t
{
43 android_service_t
public;
48 android_creds_t
*creds
;
56 * configuration setttings
61 * lock to safely access the TUN device fd
66 * TUN device file descriptor
78 android_dns_proxy_t
*dns_proxy
;
81 * Whether to use the DNS proxy or not
89 static void send_esp(void *data
, esp_packet_t
*packet
)
91 charon
->sender
->send_no_marker(charon
->sender
, (packet_t
*)packet
);
97 static void deliver_plain(private_android_service_t
*this,
103 encoding
= packet
->get_encoding(packet
);
105 this->lock
->read_lock(this->lock
);
107 { /* the TUN device is already closed */
108 this->lock
->unlock(this->lock
);
109 packet
->destroy(packet
);
112 len
= write(this->tunfd
, encoding
.ptr
, encoding
.len
);
113 this->lock
->unlock(this->lock
);
115 if (len
< 0 || len
!= encoding
.len
)
117 DBG1(DBG_DMN
, "failed to write packet to TUN device: %s",
120 packet
->destroy(packet
);
126 static void receiver_esp_cb(void *data
, packet_t
*packet
)
128 esp_packet_t
*esp_packet
;
130 esp_packet
= esp_packet_create_from_packet(packet
);
131 ipsec
->processor
->queue_inbound(ipsec
->processor
, esp_packet
);
135 * Job handling outbound plaintext packets
137 static job_requeue_t
handle_plain(private_android_service_t
*this)
146 /* check every second if tunfd is still valid */
152 this->lock
->read_lock(this->lock
);
154 { /* the TUN device is already closed */
155 this->lock
->unlock(this->lock
);
156 return JOB_REQUEUE_NONE
;
160 /* cache this while we have the lock */
161 dns_proxy
= this->use_dns_proxy
;
162 this->lock
->unlock(this->lock
);
164 old
= thread_cancelability(TRUE
);
165 len
= select(tunfd
+ 1, &set
, NULL
, NULL
, &tv
);
166 thread_cancelability(old
);
171 { /* the TUN device got closed just before calling select(), retry */
172 return JOB_REQUEUE_FAIR
;
174 DBG1(DBG_DMN
, "select on TUN device failed: %s", strerror(errno
));
175 return JOB_REQUEUE_NONE
;
178 { /* timeout, check again right away */
179 return JOB_REQUEUE_DIRECT
;
182 raw
= chunk_alloc(this->mtu
);
183 len
= read(tunfd
, raw
.ptr
, raw
.len
);
186 DBG1(DBG_DMN
, "reading from TUN device failed: %s", strerror(errno
));
188 return JOB_REQUEUE_FAIR
;
192 packet
= ip_packet_create(raw
);
195 if (!dns_proxy
|| !this->dns_proxy
->handle(this->dns_proxy
, packet
))
197 ipsec
->processor
->queue_outbound(ipsec
->processor
, packet
);
202 DBG1(DBG_DMN
, "invalid IP packet read from TUN device");
204 return JOB_REQUEUE_DIRECT
;
208 * Add a route to the TUN device builder
210 static bool add_route(vpnservice_builder_t
*builder
, host_t
*net
,
213 /* if route is 0.0.0.0/0, split it into two routes 0.0.0.0/1 and
214 * 128.0.0.0/1 because otherwise it would conflict with the current default
215 * route. likewise for IPv6 with ::/0. */
216 if (net
->is_anyaddr(net
) && prefix
== 0)
220 success
= add_route(builder
, net
, 1);
221 if (net
->get_family(net
) == AF_INET
)
223 net
= host_create_from_string("128.0.0.0", 0);
227 net
= host_create_from_string("8000::", 0);
229 success
= success
&& add_route(builder
, net
, 1);
233 return builder
->add_route(builder
, net
, prefix
);
237 * Generate and set routes from installed IPsec policies
239 static bool add_routes(vpnservice_builder_t
*builder
, child_sa_t
*child_sa
)
241 traffic_selector_t
*src_ts
, *dst_ts
;
242 enumerator_t
*enumerator
;
245 enumerator
= child_sa
->create_policy_enumerator(child_sa
);
246 while (success
&& enumerator
->enumerate(enumerator
, &src_ts
, &dst_ts
))
251 dst_ts
->to_subnet(dst_ts
, &net
, &prefix
);
252 success
= add_route(builder
, net
, prefix
);
255 enumerator
->destroy(enumerator
);
260 * Setup a new TUN device for the supplied SAs, also queues a job that
261 * reads packets from this device.
262 * Additional information such as DNS servers are gathered in appropriate
263 * listeners asynchronously. To be sure every required bit of information is
264 * available this should be called after the CHILD_SA has been established.
266 static bool setup_tun_device(private_android_service_t
*this,
267 ike_sa_t
*ike_sa
, child_sa_t
*child_sa
)
269 vpnservice_builder_t
*builder
;
270 enumerator_t
*enumerator
;
271 bool vip_found
= FALSE
, already_registered
= FALSE
;
275 DBG1(DBG_DMN
, "setting up TUN device for CHILD_SA %s{%u}",
276 child_sa
->get_name(child_sa
), child_sa
->get_unique_id(child_sa
));
278 builder
= charonservice
->get_vpnservice_builder(charonservice
);
280 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, TRUE
);
281 while (enumerator
->enumerate(enumerator
, &vip
))
283 if (!vip
->is_anyaddr(vip
))
285 if (!builder
->add_address(builder
, vip
))
292 enumerator
->destroy(enumerator
);
296 DBG1(DBG_DMN
, "setting up TUN device failed, no virtual IP found");
299 if (!add_routes(builder
, child_sa
) ||
300 !builder
->set_mtu(builder
, this->mtu
))
305 tunfd
= builder
->establish(builder
);
311 this->lock
->write_lock(this->lock
);
313 { /* close previously opened TUN device */
315 already_registered
= true;
318 this->lock
->unlock(this->lock
);
320 DBG1(DBG_DMN
, "successfully created TUN device");
322 if (!already_registered
)
324 charon
->receiver
->add_esp_cb(charon
->receiver
,
325 (receiver_esp_cb_t
)receiver_esp_cb
, NULL
);
326 ipsec
->processor
->register_inbound(ipsec
->processor
,
327 (ipsec_inbound_cb_t
)deliver_plain
, this);
328 ipsec
->processor
->register_outbound(ipsec
->processor
,
329 (ipsec_outbound_cb_t
)send_esp
, NULL
);
330 this->dns_proxy
->register_cb(this->dns_proxy
,
331 (dns_proxy_response_cb_t
)deliver_plain
, this);
333 lib
->processor
->queue_job(lib
->processor
,
334 (job_t
*)callback_job_create((callback_job_cb_t
)handle_plain
, this,
335 NULL
, (callback_job_cancel_t
)return_false
));
341 * Setup a new TUN device based on the existing one, but without DNS server.
343 static bool setup_tun_device_without_dns(private_android_service_t
*this)
345 vpnservice_builder_t
*builder
;
348 DBG1(DBG_DMN
, "setting up TUN device without DNS");
350 builder
= charonservice
->get_vpnservice_builder(charonservice
);
352 tunfd
= builder
->establish_no_dns(builder
);
358 this->lock
->write_lock(this->lock
);
360 { /* close previously opened TUN device, this should always be the case */
364 this->lock
->unlock(this->lock
);
366 DBG1(DBG_DMN
, "successfully created TUN device without DNS");
371 * Close the current tun device
373 static void close_tun_device(private_android_service_t
*this)
377 this->lock
->write_lock(this->lock
);
379 { /* already closed (or never created) */
380 this->lock
->unlock(this->lock
);
385 this->lock
->unlock(this->lock
);
387 this->dns_proxy
->unregister_cb(this->dns_proxy
,
388 (dns_proxy_response_cb_t
)deliver_plain
);
389 ipsec
->processor
->unregister_outbound(ipsec
->processor
,
390 (ipsec_outbound_cb_t
)send_esp
);
391 ipsec
->processor
->unregister_inbound(ipsec
->processor
,
392 (ipsec_inbound_cb_t
)deliver_plain
);
393 charon
->receiver
->del_esp_cb(charon
->receiver
,
394 (receiver_esp_cb_t
)receiver_esp_cb
);
399 * Terminate the IKE_SA with the given unique ID
401 CALLBACK(terminate
, job_requeue_t
,
404 charon
->controller
->terminate_ike(charon
->controller
, *id
,
405 controller_cb_empty
, NULL
, 0);
406 return JOB_REQUEUE_NONE
;
410 * Reestablish the IKE_SA with the given unique ID
412 CALLBACK(reestablish
, job_requeue_t
,
417 ike_sa
= charon
->ike_sa_manager
->checkout_by_id(charon
->ike_sa_manager
, *id
);
420 if (ike_sa
->reauth(ike_sa
) == DESTROY_ME
)
422 charon
->ike_sa_manager
->checkin_and_destroy(charon
->ike_sa_manager
,
427 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, ike_sa
);
430 return JOB_REQUEUE_NONE
;
433 METHOD(listener_t
, ike_updown
, bool,
434 private_android_service_t
*this, ike_sa_t
*ike_sa
, bool up
)
436 /* this callback is only registered during initiation, so if the IKE_SA
437 * goes down we assume some kind of authentication error, more specific
438 * errors are caught in the alert() handler */
439 if (this->ike_sa
== ike_sa
&& !up
)
441 charonservice
->update_status(charonservice
,
442 CHARONSERVICE_AUTH_ERROR
);
448 METHOD(listener_t
, ike_rekey
, bool,
449 private_android_service_t
*this, ike_sa_t
*old
, ike_sa_t
*new)
451 if (this->ike_sa
== old
)
458 METHOD(listener_t
, ike_reestablish_post_redirect
, bool,
459 private_android_service_t
*this, ike_sa_t
*old
, ike_sa_t
*new,
462 if (this->ike_sa
== old
&& initiated
)
463 { /* if we get redirected during IKE_AUTH we just migrate to the new SA,
464 * we don't have a TUN device yet, so reinstalling it without DNS would
465 * fail (and using the DNS proxy is not required anyway) */
471 METHOD(listener_t
, ike_reestablish_pre
, bool,
472 private_android_service_t
*this, ike_sa_t
*old
, ike_sa_t
*new)
474 if (this->ike_sa
== old
)
476 /* enable DNS proxy so hosts are properly resolved while the TUN device
478 this->lock
->write_lock(this->lock
);
479 this->use_dns_proxy
= TRUE
;
480 this->lock
->unlock(this->lock
);
481 /* if DNS servers are installed that are only reachable through the VPN
482 * the DNS proxy doesn't help, so uninstall DNS servers */
483 if (!setup_tun_device_without_dns(this))
485 DBG1(DBG_DMN
, "failed to setup TUN device without DNS");
486 charonservice
->update_status(charonservice
,
487 CHARONSERVICE_GENERIC_ERROR
);
493 METHOD(listener_t
, ike_reestablish_post
, bool,
494 private_android_service_t
*this, ike_sa_t
*old
, ike_sa_t
*new,
497 if (this->ike_sa
== old
&& initiated
)
500 /* re-register hook to detect initiation failures */
501 this->public.listener
.ike_updown
= _ike_updown
;
502 /* if the IKE_SA got deleted by the responder we get the child_down()
503 * event on the old IKE_SA after this hook has been called, so they
504 * get ignored and thus we trigger the event here */
505 charonservice
->update_status(charonservice
,
506 CHARONSERVICE_CHILD_STATE_DOWN
);
511 METHOD(listener_t
, child_updown
, bool,
512 private_android_service_t
*this, ike_sa_t
*ike_sa
, child_sa_t
*child_sa
,
515 if (this->ike_sa
== ike_sa
)
519 /* disable the hooks registered to catch initiation failures */
520 this->public.listener
.ike_updown
= NULL
;
521 /* enable hooks to handle reauthentications */
522 this->public.listener
.ike_reestablish_pre
= _ike_reestablish_pre
;
523 this->public.listener
.ike_reestablish_post
= _ike_reestablish_post
;
524 /* CHILD_SA is up so we can disable the DNS proxy we enabled to
525 * reestablish the SA */
526 this->lock
->write_lock(this->lock
);
527 this->use_dns_proxy
= FALSE
;
528 this->lock
->unlock(this->lock
);
529 if (!setup_tun_device(this, ike_sa
, child_sa
))
531 DBG1(DBG_DMN
, "failed to setup TUN device");
532 charonservice
->update_status(charonservice
,
533 CHARONSERVICE_GENERIC_ERROR
);
537 charonservice
->update_status(charonservice
,
538 CHARONSERVICE_CHILD_STATE_UP
);
542 charonservice
->update_status(charonservice
,
543 CHARONSERVICE_CHILD_STATE_DOWN
);
549 METHOD(listener_t
, alert
, bool,
550 private_android_service_t
*this, ike_sa_t
*ike_sa
, alert_t alert
,
553 bool stay_registered
= TRUE
;
555 if (this->ike_sa
== ike_sa
)
559 case ALERT_PEER_ADDR_FAILED
:
560 charonservice
->update_status(charonservice
,
561 CHARONSERVICE_LOOKUP_ERROR
);
564 case ALERT_PEER_AUTH_FAILED
:
565 charonservice
->update_status(charonservice
,
566 CHARONSERVICE_PEER_AUTH_ERROR
);
569 case ALERT_KEEP_ON_CHILD_SA_FAILURE
:
571 uint32_t *id
= malloc_thing(uint32_t);
573 /* because close_ike_on_child_failure is set this is only
574 * triggered when CHILD_SA rekeying failed. reestablish it in
575 * the hope that the initial setup works again. */
576 *id
= ike_sa
->get_unique_id(ike_sa
);
577 lib
->processor
->queue_job(lib
->processor
,
578 (job_t
*)callback_job_create_with_prio(
579 (callback_job_cb_t
)reestablish
, id
, free
,
580 (callback_job_cancel_t
)return_false
, JOB_PRIO_HIGH
));
583 case ALERT_PEER_INIT_UNREACHABLE
:
584 this->lock
->read_lock(this->lock
);
587 uint32_t *id
= malloc_thing(uint32_t);
589 /* always fail if we are not able to initiate the IKE_SA
591 charonservice
->update_status(charonservice
,
592 CHARONSERVICE_UNREACHABLE_ERROR
);
593 /* terminate the IKE_SA so no further keying tries are
595 *id
= ike_sa
->get_unique_id(ike_sa
);
596 lib
->processor
->queue_job(lib
->processor
,
597 (job_t
*)callback_job_create_with_prio(
598 (callback_job_cb_t
)terminate
, id
, free
,
599 (callback_job_cancel_t
)return_false
, JOB_PRIO_HIGH
));
600 stay_registered
= FALSE
;
604 peer_cfg_t
*peer_cfg
;
607 /* when reestablishing and if keyingtries is not %forever
608 * the IKE_SA is destroyed after the set number of tries,
609 * so notify the GUI */
610 peer_cfg
= ike_sa
->get_peer_cfg(ike_sa
);
611 tries
= peer_cfg
->get_keyingtries(peer_cfg
);
612 try = va_arg(args
, uint32_t);
613 if (tries
!= 0 && try == tries
-1)
615 charonservice
->update_status(charonservice
,
616 CHARONSERVICE_UNREACHABLE_ERROR
);
617 stay_registered
= FALSE
;
620 this->lock
->unlock(this->lock
);
626 return stay_registered
;
629 static void add_auth_cfg_pw(private_android_service_t
*this,
630 peer_cfg_t
*peer_cfg
, bool byod
)
632 identification_t
*user
, *id
= NULL
;
634 char *username
, *password
, *local_id
;
636 auth
= auth_cfg_create();
637 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_EAP
);
639 { /* use EAP-TTLS if BYOD is enabled */
640 auth
->add(auth
, AUTH_RULE_EAP_TYPE
, EAP_TTLS
);
643 username
= this->settings
->get_str(this->settings
, "connection.username",
645 password
= this->settings
->get_str(this->settings
, "connection.password",
647 local_id
= this->settings
->get_str(this->settings
, "connection.local_id",
649 user
= identification_create_from_string(username
);
650 auth
->add(auth
, AUTH_RULE_EAP_IDENTITY
, user
);
653 id
= identification_create_from_string(local_id
);
657 id
= user
->clone(user
);
659 auth
->add(auth
, AUTH_RULE_IDENTITY
, id
);
661 this->creds
->add_username_password(this->creds
, username
, password
);
662 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, TRUE
);
665 static bool add_auth_cfg_cert(private_android_service_t
*this,
666 peer_cfg_t
*peer_cfg
)
669 identification_t
*id
= NULL
;
671 char *type
, *local_id
;
673 cert
= this->creds
->load_user_certificate(this->creds
);
679 type
= this->settings
->get_str(this->settings
, "connection.type", NULL
);
680 auth
= auth_cfg_create();
681 if (strpfx("ikev2-eap-tls", type
))
683 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_EAP
);
684 auth
->add(auth
, AUTH_RULE_EAP_TYPE
, EAP_TLS
);
685 auth
->add(auth
, AUTH_RULE_AAA_IDENTITY
,
686 identification_create_from_string("%any"));
690 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PUBKEY
);
692 auth
->add(auth
, AUTH_RULE_SUBJECT_CERT
, cert
);
694 local_id
= this->settings
->get_str(this->settings
, "connection.local_id",
698 id
= identification_create_from_string(local_id
);
702 id
= cert
->get_subject(cert
);
705 auth
->add(auth
, AUTH_RULE_IDENTITY
, id
);
706 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, TRUE
);
710 static job_requeue_t
initiate(private_android_service_t
*this)
712 identification_t
*gateway
= NULL
;
714 peer_cfg_t
*peer_cfg
;
715 child_cfg_t
*child_cfg
;
716 traffic_selector_t
*ts
;
719 peer_cfg_create_t peer
= {
720 .cert_policy
= CERT_SEND_IF_ASKED
,
721 .unique
= UNIQUE_REPLACE
,
722 .rekey_time
= 36000, /* 10h */
723 .jitter_time
= 600, /* 10min */
724 .over_time
= 600, /* 10min */
726 child_cfg_create_t child
= {
729 .life
= 3600, /* 1h */
730 .rekey
= 3000, /* 50min */
731 .jitter
= 300 /* 5min */
735 .dpd_action
= ACTION_RESTART
,
736 .close_action
= ACTION_RESTART
,
738 char *type
, *server
, *remote_id
;
742 server
= this->settings
->get_str(this->settings
, "connection.server", NULL
);
743 port
= this->settings
->get_int(this->settings
, "connection.port",
745 certreq
= this->settings
->get_bool(this->settings
, "connection.certreq",
747 ike_cfg
= ike_cfg_create(IKEV2
, certreq
, TRUE
, "0.0.0.0",
748 charon
->socket
->get_port(charon
->socket
, FALSE
),
749 server
, port
, FRAGMENTATION_YES
, 0);
750 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default(PROTO_IKE
));
751 ike_cfg
->add_proposal(ike_cfg
, proposal_create_default_aead(PROTO_IKE
));
753 peer_cfg
= peer_cfg_create("android", ike_cfg
, &peer
);
754 peer_cfg
->add_virtual_ip(peer_cfg
, host_create_any(AF_INET
));
755 peer_cfg
->add_virtual_ip(peer_cfg
, host_create_any(AF_INET6
));
757 type
= this->settings
->get_str(this->settings
, "connection.type", NULL
);
758 /* local auth config */
759 if (streq("ikev2-cert", type
) ||
760 streq("ikev2-cert-eap", type
) ||
761 streq("ikev2-eap-tls", type
))
763 if (!add_auth_cfg_cert(this, peer_cfg
))
765 peer_cfg
->destroy(peer_cfg
);
766 charonservice
->update_status(charonservice
,
767 CHARONSERVICE_GENERIC_ERROR
);
768 return JOB_REQUEUE_NONE
;
771 if (streq("ikev2-eap", type
) ||
772 streq("ikev2-cert-eap", type
) ||
773 streq("ikev2-byod-eap", type
))
775 add_auth_cfg_pw(this, peer_cfg
, strpfx(type
, "ikev2-byod"));
778 /* remote auth config */
779 auth
= auth_cfg_create();
780 remote_id
= this->settings
->get_str(this->settings
, "connection.remote_id",
784 gateway
= identification_create_from_string(remote_id
);
786 if (!gateway
|| gateway
->get_type(gateway
) == ID_ANY
)
789 gateway
= identification_create_from_string(server
);
790 /* only use this if remote ID was not configured explicitly */
791 auth
->add(auth
, AUTH_RULE_IDENTITY_LOOSE
, TRUE
);
793 auth
->add(auth
, AUTH_RULE_IDENTITY
, gateway
);
794 auth
->add(auth
, AUTH_RULE_AUTH_CLASS
, AUTH_CLASS_PUBKEY
);
795 peer_cfg
->add_auth_cfg(peer_cfg
, auth
, FALSE
);
797 child_cfg
= child_cfg_create("android", &child
);
798 /* create ESP proposals with and without DH groups, let responder decide
800 child_cfg
->add_proposal(child_cfg
, proposal_create_from_string(PROTO_ESP
,
801 "aes128gcm16-aes256gcm16-chacha20poly1305-"
802 "curve25519-ecp256-modp3072"));
803 child_cfg
->add_proposal(child_cfg
, proposal_create_from_string(PROTO_ESP
,
804 "aes128-sha256-curve25519-ecp256-modp3072"));
805 child_cfg
->add_proposal(child_cfg
, proposal_create_from_string(PROTO_ESP
,
806 "aes256-sha384-ecp521-modp8192"));
807 child_cfg
->add_proposal(child_cfg
, proposal_create_from_string(PROTO_ESP
,
808 "aes128-aes192-aes256-sha1-sha256-sha384-sha512-"
809 "curve25519-ecp256-ecp384-ecp521-"
810 "modp2048-modp3072-modp4096"));
811 child_cfg
->add_proposal(child_cfg
, proposal_create_from_string(PROTO_ESP
,
812 "aes128gcm16-aes256gcm16-chacha20poly1305"));
813 child_cfg
->add_proposal(child_cfg
, proposal_create_from_string(PROTO_ESP
,
815 child_cfg
->add_proposal(child_cfg
, proposal_create_from_string(PROTO_ESP
,
817 child_cfg
->add_proposal(child_cfg
, proposal_create_from_string(PROTO_ESP
,
818 "aes128-aes192-aes256-sha1-sha256-sha384-sha512"));
819 ts
= traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
820 child_cfg
->add_traffic_selector(child_cfg
, TRUE
, ts
);
821 ts
= traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
822 child_cfg
->add_traffic_selector(child_cfg
, FALSE
, ts
);
823 ts
= traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
824 child_cfg
->add_traffic_selector(child_cfg
, TRUE
, ts
);
825 ts
= traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
826 child_cfg
->add_traffic_selector(child_cfg
, FALSE
, ts
);
827 peer_cfg
->add_child_cfg(peer_cfg
, child_cfg
);
829 /* get us an IKE_SA */
830 ike_sa
= charon
->ike_sa_manager
->checkout_by_config(charon
->ike_sa_manager
,
834 peer_cfg
->destroy(peer_cfg
);
835 charonservice
->update_status(charonservice
,
836 CHARONSERVICE_GENERIC_ERROR
);
837 return JOB_REQUEUE_NONE
;
839 if (!ike_sa
->get_peer_cfg(ike_sa
))
841 ike_sa
->set_peer_cfg(ike_sa
, peer_cfg
);
843 peer_cfg
->destroy(peer_cfg
);
845 /* store the IKE_SA so we can track its progress */
846 this->ike_sa
= ike_sa
;
848 /* get an additional reference because initiate consumes one */
849 child_cfg
->get_ref(child_cfg
);
850 if (ike_sa
->initiate(ike_sa
, child_cfg
, 0, NULL
, NULL
) != SUCCESS
)
852 DBG1(DBG_CFG
, "failed to initiate tunnel");
853 charon
->ike_sa_manager
->checkin_and_destroy(charon
->ike_sa_manager
,
855 return JOB_REQUEUE_NONE
;
857 charon
->ike_sa_manager
->checkin(charon
->ike_sa_manager
, ike_sa
);
858 return JOB_REQUEUE_NONE
;
861 METHOD(android_service_t
, destroy
, void,
862 private_android_service_t
*this)
864 charon
->bus
->remove_listener(charon
->bus
, &this->public.listener
);
865 /* make sure the tun device is actually closed */
866 close_tun_device(this);
867 this->dns_proxy
->destroy(this->dns_proxy
);
868 this->lock
->destroy(this->lock
);
869 this->settings
->destroy(this->settings
);
876 android_service_t
*android_service_create(android_creds_t
*creds
,
877 settings_t
*settings
)
879 private_android_service_t
*this;
884 .ike_rekey
= _ike_rekey
,
885 .ike_reestablish_post
= _ike_reestablish_post_redirect
,
886 .ike_updown
= _ike_updown
,
887 .child_updown
= _child_updown
,
892 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
893 .dns_proxy
= android_dns_proxy_create(),
894 .settings
= settings
,
897 .mtu
= settings
->get_int(settings
, "global.mtu", ANDROID_DEFAULT_MTU
),
899 /* only allow queries for the VPN gateway */
900 this->dns_proxy
->add_hostname(this->dns_proxy
,
901 this->settings
->get_str(this->settings
, "connection.server", NULL
));
903 charon
->bus
->add_listener(charon
->bus
, &this->public.listener
);
905 lib
->processor
->queue_job(lib
->processor
,
906 (job_t
*)callback_job_create((callback_job_cb_t
)initiate
, this,
908 return &this->public;