orconn_event.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /* Copyright (c) 2007-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file orconn_event.c
  5. * \brief Publish state change messages for OR connections
  6. *
  7. * Implements a basic publish-subscribe framework for messages about
  8. * the state of OR connections. The publisher calls the subscriber
  9. * callback functions synchronously.
  10. *
  11. * Although the synchronous calls might not simplify the call graph,
  12. * this approach improves data isolation because the publisher doesn't
  13. * need knowledge about the internals of subscribing subsystems. It
  14. * also avoids race conditions that might occur in asynchronous
  15. * frameworks.
  16. **/
  17. #include "core/or/or.h"
  18. #include "lib/pubsub/pubsub.h"
  19. #include "lib/subsys/subsys.h"
  20. #define ORCONN_EVENT_PRIVATE
  21. #include "core/or/orconn_event.h"
  22. #include "core/or/orconn_event_sys.h"
  23. DECLARE_PUBLISH(orconn_state);
  24. DECLARE_PUBLISH(orconn_status);
  25. static void
  26. orconn_event_free(msg_aux_data_t u)
  27. {
  28. tor_free_(u.ptr);
  29. }
  30. static char *
  31. orconn_state_fmt(msg_aux_data_t u)
  32. {
  33. orconn_state_msg_t *msg = (orconn_state_msg_t *)u.ptr;
  34. char *s = NULL;
  35. tor_asprintf(&s, "<gid=%"PRIu64" chan=%"PRIu64" proxy_type=%d state=%d>",
  36. msg->gid, msg->chan, msg->proxy_type, msg->state);
  37. return s;
  38. }
  39. static char *
  40. orconn_status_fmt(msg_aux_data_t u)
  41. {
  42. orconn_status_msg_t *msg = (orconn_status_msg_t *)u.ptr;
  43. char *s = NULL;
  44. tor_asprintf(&s, "<gid=%"PRIu64" status=%d reason=%d>",
  45. msg->gid, msg->status, msg->reason);
  46. return s;
  47. }
  48. static dispatch_typefns_t orconn_state_fns = {
  49. .free_fn = orconn_event_free,
  50. .fmt_fn = orconn_state_fmt,
  51. };
  52. static dispatch_typefns_t orconn_status_fns = {
  53. .free_fn = orconn_event_free,
  54. .fmt_fn = orconn_status_fmt,
  55. };
  56. static int
  57. orconn_add_pubsub(struct pubsub_connector_t *connector)
  58. {
  59. if (DISPATCH_REGISTER_TYPE(connector, orconn_state, &orconn_state_fns))
  60. return -1;
  61. if (DISPATCH_REGISTER_TYPE(connector, orconn_status, &orconn_status_fns))
  62. return -1;
  63. if (DISPATCH_ADD_PUB(connector, orconn, orconn_state) != 0)
  64. return -1;
  65. if (DISPATCH_ADD_PUB(connector, orconn, orconn_status) != 0)
  66. return -1;
  67. return 0;
  68. }
  69. void
  70. orconn_state_publish(orconn_state_msg_t *msg)
  71. {
  72. PUBLISH(orconn_state, msg);
  73. }
  74. void
  75. orconn_status_publish(orconn_status_msg_t *msg)
  76. {
  77. PUBLISH(orconn_status, msg);
  78. }
  79. const subsys_fns_t sys_orconn_event = {
  80. .name = "orconn_event",
  81. .supported = true,
  82. .level = -33,
  83. .add_pubsub = orconn_add_pubsub,
  84. };