/src/proxy.c

https://github.com/connectivity/connman-stable · C · 250 lines · 156 code · 60 blank · 34 comment · 35 complexity · 910d81b40bb30b649ba5503b5e9055df MD5 · raw file

  1. /*
  2. *
  3. * Connection Manager
  4. *
  5. * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
  6. *
  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
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  19. *
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <glib.h>
  25. #include "connman.h"
  26. static unsigned int next_lookup_token = 1;
  27. static GSList *driver_list = NULL;
  28. static GSList *lookup_list = NULL;
  29. struct proxy_lookup {
  30. unsigned int token;
  31. connman_proxy_lookup_cb cb;
  32. void *user_data;
  33. struct connman_service *service;
  34. char *url;
  35. guint watch;
  36. struct connman_proxy_driver *proxy;
  37. };
  38. static void remove_lookup(struct proxy_lookup *lookup)
  39. {
  40. lookup_list = g_slist_remove(lookup_list, lookup);
  41. g_free(lookup->url);
  42. g_free(lookup);
  43. }
  44. static void remove_lookups(GSList *lookups)
  45. {
  46. GSList *list;
  47. for (list = lookups; list; list = list->next) {
  48. struct proxy_lookup *lookup = list->data;
  49. remove_lookup(lookup);
  50. }
  51. g_slist_free(lookups);
  52. }
  53. static gboolean lookup_callback(gpointer user_data)
  54. {
  55. struct proxy_lookup *lookup = user_data;
  56. GSList *list;
  57. if (lookup == NULL)
  58. return FALSE;
  59. lookup->watch = 0;
  60. for (list = driver_list; list; list = list->next) {
  61. struct connman_proxy_driver *proxy = list->data;
  62. if (proxy->request_lookup == NULL)
  63. continue;
  64. lookup->proxy = proxy;
  65. break;
  66. }
  67. if (lookup->proxy == NULL ||
  68. lookup->proxy->request_lookup(lookup->service,
  69. lookup->url) < 0) {
  70. if (lookup->cb)
  71. lookup->cb(NULL, lookup->user_data);
  72. remove_lookup(lookup);
  73. }
  74. return FALSE;
  75. }
  76. unsigned int connman_proxy_lookup(const char *interface, const char *url,
  77. struct connman_service *service,
  78. connman_proxy_lookup_cb cb,
  79. void *user_data)
  80. {
  81. struct proxy_lookup *lookup;
  82. DBG("interface %s url %s", interface, url);
  83. if (interface == NULL)
  84. return 0;
  85. lookup = g_try_new0(struct proxy_lookup, 1);
  86. if (lookup == NULL)
  87. return 0;
  88. lookup->token = next_lookup_token++;
  89. lookup->cb = cb;
  90. lookup->user_data = user_data;
  91. lookup->url = g_strdup(url);
  92. lookup->service = service;
  93. lookup->watch = g_timeout_add_seconds(0, lookup_callback, lookup);
  94. if (lookup->watch == 0) {
  95. g_free(lookup->url);
  96. g_free(lookup);
  97. return 0;
  98. }
  99. DBG("token %u", lookup->token);
  100. lookup_list = g_slist_append(lookup_list, lookup);
  101. return lookup->token;
  102. }
  103. void connman_proxy_lookup_cancel(unsigned int token)
  104. {
  105. GSList *list;
  106. struct proxy_lookup *lookup = NULL;
  107. DBG("token %u", token);
  108. for (list = lookup_list; list; list = list->next) {
  109. lookup = list->data;
  110. if (lookup->token == token)
  111. break;
  112. }
  113. if (lookup != NULL) {
  114. if (lookup->watch > 0) {
  115. g_source_remove(lookup->watch);
  116. lookup->watch = 0;
  117. }
  118. if (lookup->proxy != NULL &&
  119. lookup->proxy->cancel_lookup != NULL)
  120. lookup->proxy->cancel_lookup(lookup->service,
  121. lookup->url);
  122. remove_lookup(lookup);
  123. }
  124. }
  125. void connman_proxy_driver_lookup_notify(struct connman_service *service,
  126. const char *url, const char *result)
  127. {
  128. GSList *list, *matches = NULL;
  129. DBG("service %p url %s result %s", service, url, result);
  130. for (list = lookup_list; list; list = list->next) {
  131. struct proxy_lookup *lookup = list->data;
  132. if (service != lookup->service)
  133. continue;
  134. if (g_strcmp0(lookup->url, url) == 0) {
  135. if (lookup->cb)
  136. lookup->cb(result, lookup->user_data);
  137. matches = g_slist_append(matches, lookup);
  138. }
  139. }
  140. if (matches != NULL)
  141. remove_lookups(matches);
  142. }
  143. static gint compare_priority(gconstpointer a, gconstpointer b)
  144. {
  145. const struct connman_proxy_driver *driver1 = a;
  146. const struct connman_proxy_driver *driver2 = b;
  147. return driver2->priority - driver1->priority;
  148. }
  149. /**
  150. * connman_proxy_driver_register:
  151. * @driver: Proxy driver definition
  152. *
  153. * Register a new proxy driver
  154. *
  155. * Returns: %0 on success
  156. */
  157. int connman_proxy_driver_register(struct connman_proxy_driver *driver)
  158. {
  159. DBG("driver %p name %s", driver, driver->name);
  160. driver_list = g_slist_insert_sorted(driver_list, driver,
  161. compare_priority);
  162. return 0;
  163. }
  164. /**
  165. * connman_proxy_driver_unregister:
  166. * @driver: Proxy driver definition
  167. *
  168. * Remove a previously registered proxy driver
  169. */
  170. void connman_proxy_driver_unregister(struct connman_proxy_driver *driver)
  171. {
  172. GSList *list;
  173. DBG("driver %p name %s", driver, driver->name);
  174. driver_list = g_slist_remove(driver_list, driver);
  175. for (list = lookup_list; list; list = list->next) {
  176. struct proxy_lookup *lookup = list->data;
  177. if (lookup->proxy == driver)
  178. lookup->proxy = NULL;
  179. }
  180. }
  181. int __connman_proxy_init(void)
  182. {
  183. DBG("");
  184. return 0;
  185. }
  186. void __connman_proxy_cleanup(void)
  187. {
  188. DBG("");
  189. remove_lookups(lookup_list);
  190. }