1
0

rudp.c 4.3 KB

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