rudp.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "rudp.h"
  2. #if WITH_RUDP
  3. #include "hevent.h"
  4. #include "hsocket.h"
  5. void rudp_entry_free(rudp_entry_t* entry) {
  6. #if WITH_KCP
  7. kcp_release(&entry->kcp);
  8. #endif
  9. HV_FREE(entry);
  10. }
  11. void rudp_init(rudp_t* rudp) {
  12. // printf("rudp init\n");
  13. rudp->rb_root.rb_node = NULL;
  14. hmutex_init(&rudp->mutex);
  15. }
  16. void rudp_cleanup(rudp_t* rudp) {
  17. // printf("rudp cleaup\n");
  18. struct rb_node* n = NULL;
  19. rudp_entry_t* e = NULL;
  20. while ((n = rudp->rb_root.rb_node)) {
  21. e = rb_entry(n, rudp_entry_t, rb_node);
  22. rb_erase(n, &rudp->rb_root);
  23. rudp_entry_free(e);
  24. }
  25. hmutex_destroy(&rudp->mutex);
  26. }
  27. bool rudp_insert(rudp_t* rudp, rudp_entry_t* entry) {
  28. struct rb_node** n = &rudp->rb_root.rb_node;
  29. struct rb_node* parent = NULL;
  30. rudp_entry_t* e = NULL;
  31. int cmp = 0;
  32. bool exists = false;
  33. while (*n) {
  34. parent = *n;
  35. e = rb_entry(*n, rudp_entry_t, rb_node);
  36. cmp = sockaddr_compare(&entry->addr, &e->addr);
  37. if (cmp < 0) {
  38. n = &(*n)->rb_left;
  39. } else if (cmp > 0) {
  40. n = &(*n)->rb_right;
  41. } else {
  42. exists = true;
  43. break;
  44. }
  45. }
  46. if (!exists) {
  47. rb_link_node(&entry->rb_node, parent, n);
  48. rb_insert_color(&entry->rb_node, &rudp->rb_root);
  49. }
  50. return !exists;
  51. }
  52. rudp_entry_t* rudp_search(rudp_t* rudp, struct sockaddr* addr) {
  53. struct rb_node* n = rudp->rb_root.rb_node;
  54. rudp_entry_t* e = NULL;
  55. int cmp = 0;
  56. bool exists = false;
  57. while (n) {
  58. e = rb_entry(n, rudp_entry_t, rb_node);
  59. cmp = sockaddr_compare((sockaddr_u*)addr, &e->addr);
  60. if (cmp < 0) {
  61. n = n->rb_left;
  62. } else if (cmp > 0) {
  63. n = n->rb_right;
  64. } else {
  65. exists = true;
  66. break;
  67. }
  68. }
  69. return exists ? e : NULL;
  70. }
  71. rudp_entry_t* rudp_remove(rudp_t* rudp, struct sockaddr* addr) {
  72. hmutex_lock(&rudp->mutex);
  73. rudp_entry_t* e = rudp_search(rudp, addr);
  74. if (e) {
  75. // printf("rudp_remove ");
  76. // SOCKADDR_PRINT(addr);
  77. rb_erase(&e->rb_node, &rudp->rb_root);
  78. }
  79. hmutex_unlock(&rudp->mutex);
  80. return e;
  81. }
  82. rudp_entry_t* rudp_get(rudp_t* rudp, struct sockaddr* addr) {
  83. hmutex_lock(&rudp->mutex);
  84. struct rb_node** n = &rudp->rb_root.rb_node;
  85. struct rb_node* parent = NULL;
  86. rudp_entry_t* e = NULL;
  87. int cmp = 0;
  88. bool exists = false;
  89. // search
  90. while (*n) {
  91. parent = *n;
  92. e = rb_entry(*n, rudp_entry_t, rb_node);
  93. cmp = sockaddr_compare((sockaddr_u*)addr, &e->addr);
  94. if (cmp < 0) {
  95. n = &(*n)->rb_left;
  96. } else if (cmp > 0) {
  97. n = &(*n)->rb_right;
  98. } else {
  99. exists = true;
  100. break;
  101. }
  102. }
  103. if (!exists) {
  104. // insert
  105. // printf("rudp_insert ");
  106. // SOCKADDR_PRINT(addr);
  107. HV_ALLOC_SIZEOF(e);
  108. memcpy(&e->addr, addr, SOCKADDR_LEN(addr));
  109. rb_link_node(&e->rb_node, parent, n);
  110. rb_insert_color(&e->rb_node, &rudp->rb_root);
  111. }
  112. hmutex_unlock(&rudp->mutex);
  113. return e;
  114. }
  115. void rudp_del(rudp_t* rudp, struct sockaddr* addr) {
  116. hmutex_lock(&rudp->mutex);
  117. rudp_entry_t* e = rudp_search(rudp, addr);
  118. if (e) {
  119. // printf("rudp_remove ");
  120. // SOCKADDR_PRINT(addr);
  121. rb_erase(&e->rb_node, &rudp->rb_root);
  122. rudp_entry_free(e);
  123. }
  124. hmutex_unlock(&rudp->mutex);
  125. }
  126. rudp_entry_t* hio_get_rudp(hio_t* io, struct sockaddr* addr) {
  127. rudp_entry_t* rudp = rudp_get(&io->rudp, addr ? addr : io->peeraddr);
  128. rudp->io = io;
  129. return rudp;
  130. }
  131. static void hio_close_rudp_event_cb(hevent_t* ev) {
  132. rudp_entry_t* entry = (rudp_entry_t*)ev->userdata;
  133. rudp_del(&entry->io->rudp, (struct sockaddr*)&entry->addr);
  134. // rudp_entry_free(entry);
  135. }
  136. int hio_close_rudp(hio_t* io, struct sockaddr* peeraddr) {
  137. if (peeraddr == NULL) peeraddr = io->peeraddr;
  138. // NOTE: do rudp_del for thread-safe
  139. rudp_entry_t* entry = rudp_get(&io->rudp, peeraddr);
  140. // NOTE: just rudp_remove first, do rudp_entry_free async for safe.
  141. // rudp_entry_t* entry = rudp_remove(&io->rudp, peeraddr);
  142. if (entry) {
  143. hevent_t ev;
  144. memset(&ev, 0, sizeof(ev));
  145. ev.cb = hio_close_rudp_event_cb;
  146. ev.userdata = entry;
  147. ev.priority = HEVENT_HIGH_PRIORITY;
  148. hloop_post_event(io->loop, &ev);
  149. }
  150. return 0;
  151. }
  152. #endif