Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 true iff we received an HTTP 204. |
|
Sam Leffler
2010/11/19 16:06:52
stale comment
Jason Glasgow
2010/11/19 19:48:19
Done.
| |
| 91 */ | 91 */ |
| 92 static gboolean check_ip_pool(CURLMsg *request_status) | 92 static enum connman_service_connectivity_state check_connectivity_state( |
| 93 » CURLMsg *request_status) | |
| 93 { | 94 { |
| 94 » // Check the request state | 95 » CURLcode code = (CURLcode)request_status->data.result; |
| 96 | |
| 97 » /* Check the request state */ | |
| 95 _DBG_PORTAL("curl code is %d", (int)request_status->data.result); | 98 _DBG_PORTAL("curl code is %d", (int)request_status->data.result); |
| 96 » if (CURLE_OK == (CURLcode)request_status->data.result) { | 99 » if (CURLE_COULDNT_RESOLVE_HOST == code) { |
| 100 » » /* TODO(jglasgow): test resolving the olp instead */ | |
|
Sam Leffler
2010/11/19 16:06:52
don't know what "olp" is; please expand
| |
| 101 » » _DBG_PORTAL("Cannot resolve %s", kGoogle204Url); | |
| 102 » » return CONNMAN_SERVICE_CONNECTIVITY_STATE_NONE; | |
| 103 » } | |
| 104 | |
| 105 » if (CURLE_OK == code) { | |
| 97 if (get_http_code(request_status->easy_handle) == 204) { | 106 if (get_http_code(request_status->easy_handle) == 204) { |
| 98 _DBG_PORTAL("The user can route traffic"); | 107 _DBG_PORTAL("The user can route traffic"); |
| 99 » » » return FALSE; | 108 » » » return CONNMAN_SERVICE_CONNECTIVITY_STATE_UNRESTRICTED; |
| 100 } | 109 } |
| 101 } | 110 } |
| 102 _DBG_PORTAL("We're in an IP restrict pool"); | 111 _DBG_PORTAL("We're in an IP restrict pool"); |
| 103 » return TRUE; | 112 » return CONNMAN_SERVICE_CONNECTIVITY_STATE_RESTRICTED; |
| 104 } | 113 } |
| 105 | 114 |
| 106 /** | 115 /** |
| 107 * Calls curl_multi_perform until CURLM_CALL_MULTI_PERFORM is no longer | 116 * Calls curl_multi_perform until CURLM_CALL_MULTI_PERFORM is no longer |
| 108 * returned. | 117 * returned. |
| 109 */ | 118 */ |
| 110 static void handle_multi_perform() | 119 static void handle_multi_perform() |
| 111 { | 120 { |
| 112 » // Multi perform may need to be called multiple times to set | 121 » /* |
| 113 » // the request up successfully. | 122 » * Multi perform may need to be called multiple times to set |
| 123 » * the request up successfully. | |
| 124 » */ | |
| 114 CURLMcode err; | 125 CURLMcode err; |
| 115 do { | 126 do { |
| 116 err = curl_multi_perform(curl_multi_handle_, | 127 err = curl_multi_perform(curl_multi_handle_, |
| 117 &pending_requests_); | 128 &pending_requests_); |
| 118 _DBG_PORTAL("Calling multi perform"); | 129 _DBG_PORTAL("Calling multi perform"); |
| 119 } while (CURLM_CALL_MULTI_PERFORM == err); | 130 } while (CURLM_CALL_MULTI_PERFORM == err); |
| 120 | 131 |
| 121 if (err != CURLM_OK) { | 132 if (err != CURLM_OK) { |
| 122 connman_error("%s: curl_multi_perform() = %s", __func__, | 133 connman_error("%s: curl_multi_perform() = %s", __func__, |
| 123 curl_multi_strerror(err)); | 134 curl_multi_strerror(err)); |
| 124 } | 135 } |
| 125 } | 136 } |
| 126 | 137 |
| 127 /** | 138 /** |
| 128 * Processes all currently queued libcurl requests. | 139 * Processes all currently queued libcurl requests. |
| 129 * | 140 * |
| 130 * Returns TRUE if there are pending requests. Returning true re-arms | 141 * Returns TRUE if there are pending requests. Returning true re-arms |
| 131 * the timer and causes this function to be called again. | 142 * the timer and causes this function to be called again. |
| 132 */ | 143 */ |
| 133 static gboolean pending_request_callback(gpointer data) | 144 static gboolean pending_request_callback(gpointer data) |
| 134 { | 145 { |
| 135 int remaining_updates; | 146 int remaining_updates; |
| 136 CURLMsg* request_status; | 147 CURLMsg* request_status; |
| 148 struct portal_request *portal_request = NULL; | |
| 149 struct connman_service *service; | |
| 137 | 150 |
| 138 _DBG_PORTAL("callback fired, %d jobs remain", pending_requests_); | 151 _DBG_PORTAL("callback fired, %d jobs remain", pending_requests_); |
| 139 | 152 |
| 140 handle_multi_perform(); | 153 handle_multi_perform(); |
| 141 | 154 |
| 142 request_status = | 155 request_status = |
| 143 curl_multi_info_read(curl_multi_handle_, &remaining_updates); | 156 curl_multi_info_read(curl_multi_handle_, &remaining_updates); |
| 144 | 157 |
| 145 » if (request_status != NULL && CURLMSG_DONE == request_status->msg) { | 158 » if (request_status == NULL || CURLMSG_DONE != request_status->msg) { |
| 146 » » struct portal_request *portal_request = NULL; | 159 » » _DBG_PORTAL("remaining status is %d", remaining_updates); |
| 147 » » struct connman_service *service; | 160 » » return TRUE; |
| 161 » } | |
| 148 | 162 |
| 149 curl_easy_getinfo(request_status->easy_handle, CURLINFO_PRIVATE, | |
| 150 (char **)&portal_request); | |
| 151 service = portal_request->service; | |
| 152 | 163 |
| 153 » » _DBG_PORTAL("service = %s", | 164 » curl_easy_getinfo(request_status->easy_handle, CURLINFO_PRIVATE, |
| 154 » » » connman_service_get_identifier(service)); | 165 » » » (char **)&portal_request); |
| 166 » service = portal_request->service; | |
| 155 | 167 |
| 156 » » if (portal_request == latest_request) { | 168 » _DBG_PORTAL("service = %s", connman_service_get_identifier(service)); |
| 157 » » » gboolean restricted = check_ip_pool(request_status); | |
| 158 | 169 |
| 159 » » » connman_service_set_restricted_pool(service, restricted) ; | 170 » if (portal_request == latest_request) { |
| 160 » » } else { | 171 » » enum connman_service_connectivity_state state = |
| 161 » » » _DBG_PORTAL("Ignoring stale results"); | 172 » » » check_connectivity_state(request_status); |
| 162 » » } | 173 |
| 163 » » curl_multi_remove_handle(curl_multi_handle_, | 174 » » connman_service_set_connectivity_state(service, state); |
| 164 » » » » » request_status->easy_handle); | 175 |
| 165 » » free_request(portal_request); | 176 » } else { |
| 166 » » _DBG_PORTAL("Cancelling the timer"); | 177 » » _DBG_PORTAL("Ignoring stale results"); |
| 167 » » return FALSE; | |
| 168 } | 178 } |
| 169 » _DBG_PORTAL("remaining status is %d", remaining_updates); | 179 » curl_multi_remove_handle(curl_multi_handle_, |
| 170 » return TRUE; | 180 » » » » request_status->easy_handle); |
| 181 » free_request(portal_request); | |
| 182 » _DBG_PORTAL("Cancelling the timer"); | |
| 183 » return FALSE; | |
| 171 } | 184 } |
| 172 | 185 |
| 173 /** | 186 /** |
| 174 * Returns TRUE if the new default route is connected via cellular. | 187 * Returns TRUE if the new default route is connected via cellular. |
| 175 */ | 188 */ |
| 176 static gboolean should_process_request(struct connman_service *service) { | 189 static gboolean should_process_request(struct connman_service *service) { |
| 177 if (service == NULL) { | 190 if (service == NULL) { |
| 178 _DBG_PORTAL("Skipping portal check for NULL service"); | 191 _DBG_PORTAL("Skipping portal check for NULL service"); |
| 179 return FALSE; | 192 return FALSE; |
| 180 } | 193 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 } | 289 } |
| 277 | 290 |
| 278 mcode = curl_multi_add_handle(curl_multi_handle_, request_handle); | 291 mcode = curl_multi_add_handle(curl_multi_handle_, request_handle); |
| 279 if (mcode != CURLM_OK) { | 292 if (mcode != CURLM_OK) { |
| 280 connman_error("%s: curl_multi_add_handle() = %s", __func__, | 293 connman_error("%s: curl_multi_add_handle() = %s", __func__, |
| 281 curl_multi_strerror(mcode)); | 294 curl_multi_strerror(mcode)); |
| 282 goto error; | 295 goto error; |
| 283 } | 296 } |
| 284 handle_multi_perform(); | 297 handle_multi_perform(); |
| 285 | 298 |
| 286 » // The timer will fire once per second until the request | 299 » /* The timer will fire once per second until the request |
|
Eric Shienbrood
2010/11/19 17:52:56
Need newline after /*
Jason Glasgow
2010/11/19 19:48:19
Done.
| |
| 287 » // has been processed. | 300 » * has been processed. |
| 288 » // | 301 » * |
| 289 » // TODO(rtc): Consider using fd_sets instead. | 302 » * TODO(rtc): Consider using fd_sets instead. |
| 303 » */ | |
| 290 g_timeout_add_seconds(1, pending_request_callback, NULL); | 304 g_timeout_add_seconds(1, pending_request_callback, NULL); |
| 291 return; | 305 return; |
| 292 | 306 |
| 293 error: | 307 error: |
| 294 free_request(portal_request); | 308 free_request(portal_request); |
| 295 } | 309 } |
| 296 | 310 |
| 297 /** | 311 /** |
| 298 * If the service transitions to not ready clear the restricted IP | 312 * If the service transitions to not ready clear the restricted IP |
| 299 * pool flag. | 313 * pool flag. |
| 300 */ | 314 */ |
| 301 void portal_service_state_changed(struct connman_service *service) | 315 void portal_service_state_changed(struct connman_service *service) |
| 302 { | 316 { |
| 303 const char *service_type = connman_service_get_type(service); | 317 const char *service_type = connman_service_get_type(service); |
| 304 const char *service_state = connman_service_get_state(service); | 318 const char *service_state = connman_service_get_state(service); |
| 305 | 319 |
| 306 if (g_strcmp0(service_type, "cellular") != 0) { | 320 if (g_strcmp0(service_type, "cellular") != 0) { |
| 307 return; | 321 return; |
| 308 } | 322 } |
| 309 | 323 |
| 310 if (g_strcmp0(service_state, "ready") != 0) { | 324 if (g_strcmp0(service_state, "ready") != 0) { |
| 311 » » _DBG_PORTAL("%s: Clearing restricted pool flag, not ready", | 325 » » _DBG_PORTAL("%s: Setting connectivity state unknown, not ready", |
| 312 connman_service_get_identifier(service)); | 326 connman_service_get_identifier(service)); |
| 313 » » connman_service_set_restricted_pool(service, FALSE); | 327 » » connman_service_set_connectivity_state(service, |
| 328 » » » CONNMAN_SERVICE_CONNECTIVITY_STATE_UNKNOWN); | |
| 314 } | 329 } |
| 315 } | 330 } |
| 316 | 331 |
| 317 static struct connman_notifier portal_notifier = { | 332 static struct connman_notifier portal_notifier = { |
| 318 .name = "portal", | 333 .name = "portal", |
| 319 .priority = CONNMAN_NOTIFIER_PRIORITY_LOW, | 334 .priority = CONNMAN_NOTIFIER_PRIORITY_LOW, |
| 320 .default_changed = portal_default_changed, | 335 .default_changed = portal_default_changed, |
| 321 .service_state_changed = portal_service_state_changed, | 336 .service_state_changed = portal_service_state_changed, |
| 322 }; | 337 }; |
| 323 | 338 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 339 } | 354 } |
| 340 | 355 |
| 341 static void portal_finis(void) | 356 static void portal_finis(void) |
| 342 { | 357 { |
| 343 connman_notifier_unregister(&portal_notifier); | 358 connman_notifier_unregister(&portal_notifier); |
| 344 curl_multi_cleanup(curl_multi_handle_); | 359 curl_multi_cleanup(curl_multi_handle_); |
| 345 } | 360 } |
| 346 | 361 |
| 347 CONNMAN_PLUGIN_DEFINE(portal_check, "Chrome OS metrics plugin", VERSION, | 362 CONNMAN_PLUGIN_DEFINE(portal_check, "Chrome OS metrics plugin", VERSION, |
| 348 CONNMAN_PLUGIN_PRIORITY_DEFAULT, portal_init, portal_finis) | 363 CONNMAN_PLUGIN_PRIORITY_DEFAULT, portal_init, portal_finis) |
| OLD | NEW |