Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: plugins/portal_check.c

Issue 5167004: Enhance portal check code to return connectivity_state (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/flimflam.git@master
Patch Set: Maintain a little backward compatibility Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/service.h ('k') | src/service.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Portal Check - Determines if a user is in an IP restrict pool or behind a 2 * Portal Check - Determines if a user is in an IP restrict pool or behind a
3 * captive portal. 3 * captive portal.
4 * 4 *
5 * This file initially created by Google, Inc. 5 * This file initially created by Google, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 * 10 *
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 */ 80 */
81 static long get_http_code(CURL *curl_handle) 81 static long get_http_code(CURL *curl_handle)
82 { 82 {
83 long http_code = 0; 83 long http_code = 0;
84 curl_easy_getinfo (curl_handle, CURLINFO_RESPONSE_CODE, &http_code); 84 curl_easy_getinfo (curl_handle, CURLINFO_RESPONSE_CODE, &http_code);
85 _DBG_PORTAL("http response code is %d", (int) http_code); 85 _DBG_PORTAL("http response code is %d", (int) http_code);
86 return http_code; 86 return http_code;
87 } 87 }
88 88
89 /** 89 /**
90 * Returns true iff we received an HTTP 204. 90 * Returns a connectivity state based on the status of an HTTP request
91 * to kGoogle204Url
91 */ 92 */
92 static gboolean check_ip_pool(CURLMsg *request_status) 93 static enum connman_service_connectivity_state check_connectivity_state(
94 » CURLMsg *request_status)
93 { 95 {
94 » // Check the request state 96 » CURLcode code = (CURLcode)request_status->data.result;
97
98 » /* Check the request state */
95 _DBG_PORTAL("curl code is %d", (int)request_status->data.result); 99 _DBG_PORTAL("curl code is %d", (int)request_status->data.result);
96 » if (CURLE_OK == (CURLcode)request_status->data.result) { 100 » if (CURLE_COULDNT_RESOLVE_HOST == code) {
101 » » /*
102 » » * TODO(jglasgow): test resolving the address of the
103 » » * captive portal web server instead
104 » » */
105 » » _DBG_PORTAL("Cannot resolve %s", kGoogle204Url);
106 » » return CONNMAN_SERVICE_CONNECTIVITY_STATE_NONE;
107 » }
108
109 » if (CURLE_OK == code) {
97 if (get_http_code(request_status->easy_handle) == 204) { 110 if (get_http_code(request_status->easy_handle) == 204) {
98 _DBG_PORTAL("The user can route traffic"); 111 _DBG_PORTAL("The user can route traffic");
99 » » » return FALSE; 112 » » » return CONNMAN_SERVICE_CONNECTIVITY_STATE_UNRESTRICTED;
100 } 113 }
101 } 114 }
102 _DBG_PORTAL("We're in an IP restrict pool"); 115 _DBG_PORTAL("We're in an IP restrict pool");
103 » return TRUE; 116 » return CONNMAN_SERVICE_CONNECTIVITY_STATE_RESTRICTED;
104 } 117 }
105 118
106 /** 119 /**
107 * Calls curl_multi_perform until CURLM_CALL_MULTI_PERFORM is no longer 120 * Calls curl_multi_perform until CURLM_CALL_MULTI_PERFORM is no longer
108 * returned. 121 * returned.
109 */ 122 */
110 static void handle_multi_perform() 123 static void handle_multi_perform()
111 { 124 {
112 » // Multi perform may need to be called multiple times to set 125 » /*
113 » // the request up successfully. 126 » * Multi perform may need to be called multiple times to set
127 » * the request up successfully.
128 » */
114 CURLMcode err; 129 CURLMcode err;
115 do { 130 do {
116 err = curl_multi_perform(curl_multi_handle_, 131 err = curl_multi_perform(curl_multi_handle_,
117 &pending_requests_); 132 &pending_requests_);
118 _DBG_PORTAL("Calling multi perform"); 133 _DBG_PORTAL("Calling multi perform");
119 } while (CURLM_CALL_MULTI_PERFORM == err); 134 } while (CURLM_CALL_MULTI_PERFORM == err);
120 135
121 if (err != CURLM_OK) { 136 if (err != CURLM_OK) {
122 connman_error("%s: curl_multi_perform() = %s", __func__, 137 connman_error("%s: curl_multi_perform() = %s", __func__,
123 curl_multi_strerror(err)); 138 curl_multi_strerror(err));
124 } 139 }
125 } 140 }
126 141
127 /** 142 /**
128 * Processes all currently queued libcurl requests. 143 * Processes all currently queued libcurl requests.
129 * 144 *
130 * Returns TRUE if there are pending requests. Returning true re-arms 145 * Returns TRUE if there are pending requests. Returning true re-arms
131 * the timer and causes this function to be called again. 146 * the timer and causes this function to be called again.
132 */ 147 */
133 static gboolean pending_request_callback(gpointer data) 148 static gboolean pending_request_callback(gpointer data)
134 { 149 {
135 int remaining_updates; 150 int remaining_updates;
136 CURLMsg* request_status; 151 CURLMsg* request_status;
152 struct portal_request *portal_request = NULL;
153 struct connman_service *service;
137 154
138 _DBG_PORTAL("callback fired, %d jobs remain", pending_requests_); 155 _DBG_PORTAL("callback fired, %d jobs remain", pending_requests_);
139 156
140 handle_multi_perform(); 157 handle_multi_perform();
141 158
142 request_status = 159 request_status =
143 curl_multi_info_read(curl_multi_handle_, &remaining_updates); 160 curl_multi_info_read(curl_multi_handle_, &remaining_updates);
144 161
145 » if (request_status != NULL && CURLMSG_DONE == request_status->msg) { 162 » if (request_status == NULL || CURLMSG_DONE != request_status->msg) {
146 » » struct portal_request *portal_request = NULL; 163 » » _DBG_PORTAL("remaining status is %d", remaining_updates);
147 » » struct connman_service *service; 164 » » return TRUE;
165 » }
148 166
149 curl_easy_getinfo(request_status->easy_handle, CURLINFO_PRIVATE,
150 (char **)&portal_request);
151 service = portal_request->service;
152 167
153 » » _DBG_PORTAL("service = %s", 168 » curl_easy_getinfo(request_status->easy_handle, CURLINFO_PRIVATE,
154 » » » connman_service_get_identifier(service)); 169 » » » (char **)&portal_request);
170 » service = portal_request->service;
155 171
156 » » if (portal_request == latest_request) { 172 » _DBG_PORTAL("service = %s", connman_service_get_identifier(service));
157 » » » gboolean restricted = check_ip_pool(request_status);
158 173
159 » » » connman_service_set_restricted_pool(service, restricted) ; 174 » if (portal_request == latest_request) {
160 » » } else { 175 » » enum connman_service_connectivity_state state =
161 » » » _DBG_PORTAL("Ignoring stale results"); 176 » » » check_connectivity_state(request_status);
162 » » } 177
163 » » curl_multi_remove_handle(curl_multi_handle_, 178 » » connman_service_set_connectivity_state(service, state);
164 » » » » » request_status->easy_handle); 179
165 » » free_request(portal_request); 180 » } else {
166 » » _DBG_PORTAL("Cancelling the timer"); 181 » » _DBG_PORTAL("Ignoring stale results");
167 » » return FALSE;
168 } 182 }
169 » _DBG_PORTAL("remaining status is %d", remaining_updates); 183 » curl_multi_remove_handle(curl_multi_handle_,
170 » return TRUE; 184 » » » » request_status->easy_handle);
185 » free_request(portal_request);
186 » _DBG_PORTAL("Cancelling the timer");
187 » return FALSE;
171 } 188 }
172 189
173 /** 190 /**
174 * Returns TRUE if the new default route is connected via cellular. 191 * Returns TRUE if the new default route is connected via cellular.
175 */ 192 */
176 static gboolean should_process_request(struct connman_service *service) { 193 static gboolean should_process_request(struct connman_service *service) {
177 if (service == NULL) { 194 if (service == NULL) {
178 _DBG_PORTAL("Skipping portal check for NULL service"); 195 _DBG_PORTAL("Skipping portal check for NULL service");
179 return FALSE; 196 return FALSE;
180 } 197 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 293 }
277 294
278 mcode = curl_multi_add_handle(curl_multi_handle_, request_handle); 295 mcode = curl_multi_add_handle(curl_multi_handle_, request_handle);
279 if (mcode != CURLM_OK) { 296 if (mcode != CURLM_OK) {
280 connman_error("%s: curl_multi_add_handle() = %s", __func__, 297 connman_error("%s: curl_multi_add_handle() = %s", __func__,
281 curl_multi_strerror(mcode)); 298 curl_multi_strerror(mcode));
282 goto error; 299 goto error;
283 } 300 }
284 handle_multi_perform(); 301 handle_multi_perform();
285 302
286 » // The timer will fire once per second until the request 303 » /*
287 » // has been processed. 304 » * The timer will fire once per second until the request
288 » // 305 » * has been processed.
289 » // TODO(rtc): Consider using fd_sets instead. 306 » *
307 » * TODO(rtc): Consider using fd_sets instead.
308 » */
290 g_timeout_add_seconds(1, pending_request_callback, NULL); 309 g_timeout_add_seconds(1, pending_request_callback, NULL);
291 return; 310 return;
292 311
293 error: 312 error:
294 free_request(portal_request); 313 free_request(portal_request);
295 } 314 }
296 315
297 /** 316 /**
298 * If the service transitions to not ready clear the restricted IP 317 * If the service transitions to not ready clear the restricted IP
299 * pool flag. 318 * pool flag.
300 */ 319 */
301 void portal_service_state_changed(struct connman_service *service) 320 void portal_service_state_changed(struct connman_service *service)
302 { 321 {
303 const char *service_type = connman_service_get_type(service); 322 const char *service_type = connman_service_get_type(service);
304 const char *service_state = connman_service_get_state(service); 323 const char *service_state = connman_service_get_state(service);
305 324
306 if (g_strcmp0(service_type, "cellular") != 0) { 325 if (g_strcmp0(service_type, "cellular") != 0) {
307 return; 326 return;
308 } 327 }
309 328
310 if (g_strcmp0(service_state, "ready") != 0) { 329 if (g_strcmp0(service_state, "ready") != 0) {
311 » » _DBG_PORTAL("%s: Clearing restricted pool flag, not ready", 330 » » _DBG_PORTAL("%s: Setting connectivity state unknown, not ready",
312 connman_service_get_identifier(service)); 331 connman_service_get_identifier(service));
313 » » connman_service_set_restricted_pool(service, FALSE); 332 » » connman_service_set_connectivity_state(service,
333 » » » CONNMAN_SERVICE_CONNECTIVITY_STATE_UNKNOWN);
314 } 334 }
315 } 335 }
316 336
317 static struct connman_notifier portal_notifier = { 337 static struct connman_notifier portal_notifier = {
318 .name = "portal", 338 .name = "portal",
319 .priority = CONNMAN_NOTIFIER_PRIORITY_LOW, 339 .priority = CONNMAN_NOTIFIER_PRIORITY_LOW,
320 .default_changed = portal_default_changed, 340 .default_changed = portal_default_changed,
321 .service_state_changed = portal_service_state_changed, 341 .service_state_changed = portal_service_state_changed,
322 }; 342 };
323 343
(...skipping 15 matching lines...) Expand all
339 } 359 }
340 360
341 static void portal_finis(void) 361 static void portal_finis(void)
342 { 362 {
343 connman_notifier_unregister(&portal_notifier); 363 connman_notifier_unregister(&portal_notifier);
344 curl_multi_cleanup(curl_multi_handle_); 364 curl_multi_cleanup(curl_multi_handle_);
345 } 365 }
346 366
347 CONNMAN_PLUGIN_DEFINE(portal_check, "Chrome OS metrics plugin", VERSION, 367 CONNMAN_PLUGIN_DEFINE(portal_check, "Chrome OS metrics plugin", VERSION,
348 CONNMAN_PLUGIN_PRIORITY_DEFAULT, portal_init, portal_finis) 368 CONNMAN_PLUGIN_PRIORITY_DEFAULT, portal_init, portal_finis)
OLDNEW
« no previous file with comments | « include/service.h ('k') | src/service.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698