| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #include "rudp.h"
- #if WITH_RUDP
- #include "hevent.h"
- void rudp_entry_free(rudp_entry_t* entry) {
- #if WITH_KCP
- kcp_release(&entry->kcp);
- #endif
- HV_FREE(entry);
- }
- void rudp_init(rudp_t* rudp) {
- // printf("rudp init\n");
- rudp->rb_root.rb_node = NULL;
- hmutex_init(&rudp->mutex);
- }
- void rudp_cleanup(rudp_t* rudp) {
- // printf("rudp cleaup\n");
- struct rb_node* n = NULL;
- rudp_entry_t* e = NULL;
- while ((n = rudp->rb_root.rb_node)) {
- e = rb_entry(n, rudp_entry_t, rb_node);
- rb_erase(n, &rudp->rb_root);
- rudp_entry_free(e);
- }
- hmutex_destroy(&rudp->mutex);
- }
- bool rudp_insert(rudp_t* rudp, rudp_entry_t* entry) {
- struct rb_node** n = &rudp->rb_root.rb_node;
- struct rb_node* parent = NULL;
- rudp_entry_t* e = NULL;
- int cmp = 0;
- bool exists = false;
- while (*n) {
- parent = *n;
- e = rb_entry(*n, rudp_entry_t, rb_node);
- cmp = memcmp(&entry->addr, &e->addr, sizeof(sockaddr_u));
- if (cmp < 0) {
- n = &(*n)->rb_left;
- } else if (cmp > 0) {
- n = &(*n)->rb_right;
- } else {
- exists = true;
- break;
- }
- }
- if (!exists) {
- rb_link_node(&entry->rb_node, parent, n);
- rb_insert_color(&entry->rb_node, &rudp->rb_root);
- }
- return !exists;
- }
- rudp_entry_t* rudp_search(rudp_t* rudp, struct sockaddr* addr) {
- struct rb_node* n = rudp->rb_root.rb_node;
- rudp_entry_t* e = NULL;
- int cmp = 0;
- bool exists = false;
- while (n) {
- e = rb_entry(n, rudp_entry_t, rb_node);
- cmp = memcmp(addr, &e->addr, sizeof(sockaddr_u));
- if (cmp < 0) {
- n = n->rb_left;
- } else if (cmp > 0) {
- n = n->rb_right;
- } else {
- exists = true;
- break;
- }
- }
- return exists ? e : NULL;
- }
- rudp_entry_t* rudp_remove(rudp_t* rudp, struct sockaddr* addr) {
- hmutex_lock(&rudp->mutex);
- rudp_entry_t* e = rudp_search(rudp, addr);
- if (e) {
- // printf("rudp_remove ");
- // SOCKADDR_PRINT(addr);
- rb_erase(&e->rb_node, &rudp->rb_root);
- }
- hmutex_unlock(&rudp->mutex);
- return e;
- }
- rudp_entry_t* rudp_get(rudp_t* rudp, struct sockaddr* addr) {
- hmutex_lock(&rudp->mutex);
- struct rb_node** n = &rudp->rb_root.rb_node;
- struct rb_node* parent = NULL;
- rudp_entry_t* e = NULL;
- int cmp = 0;
- bool exists = false;
- // search
- while (*n) {
- parent = *n;
- e = rb_entry(*n, rudp_entry_t, rb_node);
- cmp = memcmp(addr, &e->addr, sizeof(sockaddr_u));
- if (cmp < 0) {
- n = &(*n)->rb_left;
- } else if (cmp > 0) {
- n = &(*n)->rb_right;
- } else {
- exists = true;
- break;
- }
- }
- if (!exists) {
- // insert
- // printf("rudp_insert ");
- // SOCKADDR_PRINT(addr);
- HV_ALLOC_SIZEOF(e);
- memcpy(&e->addr, addr, SOCKADDR_LEN(addr));
- rb_link_node(&e->rb_node, parent, n);
- rb_insert_color(&e->rb_node, &rudp->rb_root);
- }
- hmutex_unlock(&rudp->mutex);
- return e;
- }
- void rudp_del(rudp_t* rudp, struct sockaddr* addr) {
- hmutex_lock(&rudp->mutex);
- rudp_entry_t* e = rudp_search(rudp, addr);
- if (e) {
- // printf("rudp_remove ");
- // SOCKADDR_PRINT(addr);
- rb_erase(&e->rb_node, &rudp->rb_root);
- rudp_entry_free(e);
- }
- hmutex_unlock(&rudp->mutex);
- }
- rudp_entry_t* hio_get_rudp(hio_t* io) {
- rudp_entry_t* rudp = rudp_get(&io->rudp, io->peeraddr);
- rudp->io = io;
- return rudp;
- }
- static void hio_close_rudp_event_cb(hevent_t* ev) {
- rudp_entry_t* entry = (rudp_entry_t*)ev->userdata;
- rudp_del(&entry->io->rudp, (struct sockaddr*)&entry->addr);
- // rudp_entry_free(entry);
- }
- int hio_close_rudp(hio_t* io, struct sockaddr* peeraddr) {
- if (peeraddr == NULL) peeraddr = io->peeraddr;
- // NOTE: do rudp_del for thread-safe
- rudp_entry_t* entry = rudp_get(&io->rudp, peeraddr);
- // NOTE: just rudp_remove first, do rudp_entry_free async for safe.
- // rudp_entry_t* entry = rudp_remove(&io->rudp, peeraddr);
- if (entry) {
- hevent_t ev;
- memset(&ev, 0, sizeof(ev));
- ev.cb = hio_close_rudp_event_cb;
- ev.userdata = entry;
- ev.priority = HEVENT_HIGH_PRIORITY;
- hloop_post_event(io->loop, &ev);
- }
- return 0;
- }
- #endif
|