8dc32e62296c2c2d50e86cc5384d77b56c8f94ea
[strongswan.git] / src / frontends / android / jni / libandroidbridge / kernel / android_net.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
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>. *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 */
14
15 #include "android_net.h"
16
17 #include "../charonservice.h"
18 #include <hydra.h>
19 #include <utils/debug.h>
20 #include <processing/jobs/callback_job.h>
21 #include <threading/mutex.h>
22
23 /** delay before firing roam events (ms) */
24 #define ROAM_DELAY 100
25
26 typedef struct private_kernel_android_net_t private_kernel_android_net_t;
27
28 struct private_kernel_android_net_t {
29
30 /**
31 * Public kernel interface
32 */
33 kernel_android_net_t public;
34
35 /**
36 * Reference to NetworkManager object
37 */
38 network_manager_t *network_manager;
39
40 /**
41 * earliest time of the next roam event
42 */
43 timeval_t next_roam;
44
45 /**
46 * mutex to check and update roam event time
47 */
48 mutex_t *mutex;
49 };
50
51 /**
52 * callback function that raises the delayed roam event
53 */
54 static job_requeue_t roam_event()
55 {
56 /* this will fail if no connection is up */
57 charonservice->bypass_socket(charonservice, -1, 0);
58 hydra->kernel_interface->roam(hydra->kernel_interface, TRUE);
59 return JOB_REQUEUE_NONE;
60 }
61
62 /**
63 * Listen for connectivity change events and queue a roam event
64 */
65 static void connectivity_cb(private_kernel_android_net_t *this,
66 bool disconnected)
67 {
68 timeval_t now;
69 job_t *job;
70
71 time_monotonic(&now);
72 this->mutex->lock(this->mutex);
73 if (!timercmp(&now, &this->next_roam, >))
74 {
75 this->mutex->unlock(this->mutex);
76 return;
77 }
78 timeval_add_ms(&now, ROAM_DELAY);
79 this->next_roam = now;
80 this->mutex->unlock(this->mutex);
81
82 job = (job_t*)callback_job_create((callback_job_cb_t)roam_event, NULL,
83 NULL, NULL);
84 lib->scheduler->schedule_job_ms(lib->scheduler, job, ROAM_DELAY);
85 }
86
87 METHOD(kernel_net_t, get_source_addr, host_t*,
88 private_kernel_android_net_t *this, host_t *dest, host_t *src)
89 {
90 return this->network_manager->get_local_address(this->network_manager,
91 dest->get_family(dest) == AF_INET);
92 }
93
94 METHOD(kernel_net_t, add_ip, status_t,
95 private_kernel_android_net_t *this, host_t *virtual_ip, int prefix,
96 host_t *iface_ip)
97 {
98 /* we get the IP from the IKE_SA once the CHILD_SA is established */
99 return SUCCESS;
100 }
101
102 METHOD(kernel_net_t, destroy, void,
103 private_kernel_android_net_t *this)
104 {
105 this->network_manager->remove_connectivity_cb(this->network_manager,
106 (void*)connectivity_cb);
107 this->mutex->destroy(this->mutex);
108 free(this);
109 }
110
111 /*
112 * Described in header.
113 */
114 kernel_android_net_t *kernel_android_net_create()
115 {
116 private_kernel_android_net_t *this;
117
118 INIT(this,
119 .public = {
120 .interface = {
121 .get_source_addr = _get_source_addr,
122 .get_nexthop = (void*)return_null,
123 .get_interface = (void*)return_null,
124 .create_address_enumerator = (void*)enumerator_create_empty,
125 .add_ip = _add_ip,
126 .del_ip = (void*)return_failed,
127 .add_route = (void*)return_failed,
128 .del_route = (void*)return_failed,
129 .destroy = _destroy,
130 },
131 },
132 .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
133 .network_manager = charonservice->get_network_manager(charonservice),
134 );
135 timerclear(&this->next_roam);
136
137 this->network_manager->add_connectivity_cb(this->network_manager,
138 (void*)connectivity_cb, this);
139 return &this->public;
140 };