From c96933784643f63a73b3daa3963f032d2f2e9d54 Mon Sep 17 00:00:00 2001 From: lfeng Date: Tue, 22 Jul 2025 18:02:21 +0800 Subject: [PATCH] fix: udp server may fail to send data to client when kcp enabled. --- event/kcp/hkcp.c | 23 ++++++++++++----------- event/kcp/hkcp.h | 4 ++-- event/nio.c | 2 +- event/rudp.c | 4 ++-- event/rudp.h | 2 +- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/event/kcp/hkcp.c b/event/kcp/hkcp.c index 2c9fe6c23..229594a5a 100644 --- a/event/kcp/hkcp.c +++ b/event/kcp/hkcp.c @@ -42,8 +42,8 @@ int hio_set_kcp(hio_t* io, kcp_setting_t* setting) { return 0; } -kcp_t* hio_get_kcp(hio_t* io, uint32_t conv) { - rudp_entry_t* rudp = hio_get_rudp(io); +kcp_t* hio_get_kcp(hio_t* io, uint32_t conv, struct sockaddr* addr) { + rudp_entry_t* rudp = hio_get_rudp(io, addr); assert(rudp != NULL); kcp_t* kcp = &rudp->kcp; if (kcp->ikcp != NULL) return kcp; @@ -80,17 +80,18 @@ static void hio_write_kcp_event_cb(hevent_t* ev) { hio_t* io = (hio_t*)ev->userdata; hbuf_t* buf = (hbuf_t*)ev->privdata; - hio_write_kcp(io, buf->base, buf->len); + hio_write_kcp(io, buf->base + sizeof(sockaddr_u), buf->len - sizeof(sockaddr_u), (struct sockaddr*)buf->base); HV_FREE(buf); } -static int hio_write_kcp_async(hio_t* io, const void* data, size_t len) { +static int hio_write_kcp_async(hio_t* io, const void* data, size_t len, struct sockaddr* addr) { hbuf_t* buf = NULL; - HV_ALLOC(buf, sizeof(hbuf_t) + len); + HV_ALLOC(buf, sizeof(hbuf_t) + sizeof(sockaddr_u) + len); buf->base = (char*)buf + sizeof(hbuf_t); - buf->len = len; - memcpy(buf->base, data, len); + buf->len = len + sizeof(sockaddr_u); + memcpy(buf->base, addr, sizeof(sockaddr_u)); + memcpy(buf->base + sizeof(sockaddr_u), data, len); hevent_t ev; memset(&ev, 0, sizeof(ev)); @@ -101,12 +102,12 @@ static int hio_write_kcp_async(hio_t* io, const void* data, size_t len) { return len; } -int hio_write_kcp(hio_t* io, const void* buf, size_t len) { +int hio_write_kcp(hio_t* io, const void* buf, size_t len, struct sockaddr* addr) { if (hv_gettid() != io->loop->tid) { - return hio_write_kcp_async(io, buf, len); + return hio_write_kcp_async(io, buf, len, addr); } IUINT32 conv = io->kcp_setting ? io->kcp_setting->conv : 0; - kcp_t* kcp = hio_get_kcp(io, conv); + kcp_t* kcp = hio_get_kcp(io, conv, addr); // printf("hio_write_kcp conv=%u=%u\n", conv, kcp->conv); int nsend = ikcp_send(kcp->ikcp, (const char*)buf, len); // printf("ikcp_send len=%d nsend=%d\n", (int)len, nsend); @@ -120,7 +121,7 @@ int hio_write_kcp(hio_t* io, const void* buf, size_t len) { int hio_read_kcp (hio_t* io, void* buf, int readbytes) { IUINT32 conv = ikcp_getconv(buf); - kcp_t* kcp = hio_get_kcp(io, conv); + kcp_t* kcp = hio_get_kcp(io, conv, NULL); // printf("hio_read_kcp conv=%u=%u\n", conv, kcp->conv); if (kcp->conv != conv) { hloge("recv invalid kcp packet!"); diff --git a/event/kcp/hkcp.h b/event/kcp/hkcp.h index ca9a0615d..f70e08774 100644 --- a/event/kcp/hkcp.h +++ b/event/kcp/hkcp.h @@ -21,9 +21,9 @@ typedef struct kcp_s { // NOTE: kcp_create in hio_get_kcp void kcp_release(kcp_t* kcp); -kcp_t* hio_get_kcp (hio_t* io, uint32_t conv); +kcp_t* hio_get_kcp (hio_t* io, uint32_t conv, struct sockaddr* addr DEFAULT(NULL)); int hio_read_kcp (hio_t* io, void* buf, int readbytes); -int hio_write_kcp(hio_t* io, const void* buf, size_t len); +int hio_write_kcp(hio_t* io, const void* buf, size_t len, struct sockaddr* addr DEFAULT(NULL)); #endif diff --git a/event/nio.c b/event/nio.c index a71eeaa83..337299ac0 100644 --- a/event/nio.c +++ b/event/nio.c @@ -499,7 +499,7 @@ static int hio_write4 (hio_t* io, const void* buf, size_t len, struct sockaddr* hrecursive_mutex_lock(&io->write_mutex); #if WITH_KCP if (io->io_type == HIO_TYPE_KCP) { - nwrite = hio_write_kcp(io, buf, len); + nwrite = hio_write_kcp(io, buf, len, addr); // if (nwrite < 0) goto write_error; goto write_done; } diff --git a/event/rudp.c b/event/rudp.c index 6c7a6f373..76c29e554 100644 --- a/event/rudp.c +++ b/event/rudp.c @@ -136,8 +136,8 @@ void rudp_del(rudp_t* rudp, struct sockaddr* addr) { hmutex_unlock(&rudp->mutex); } -rudp_entry_t* hio_get_rudp(hio_t* io) { - rudp_entry_t* rudp = rudp_get(&io->rudp, io->peeraddr); +rudp_entry_t* hio_get_rudp(hio_t* io, struct sockaddr* addr) { + rudp_entry_t* rudp = rudp_get(&io->rudp, addr ? addr : io->peeraddr); rudp->io = io; return rudp; } diff --git a/event/rudp.h b/event/rudp.h index 0c30392ae..fbdedbe2b 100644 --- a/event/rudp.h +++ b/event/rudp.h @@ -45,7 +45,7 @@ rudp_entry_t* rudp_get(rudp_t* rudp, struct sockaddr* addr); void rudp_del(rudp_t* rudp, struct sockaddr* addr); // rudp_get(&io->rudp, io->peeraddr) -rudp_entry_t* hio_get_rudp(hio_t* io); +rudp_entry_t* hio_get_rudp(hio_t* io, struct sockaddr* addr DEFAULT(NULL)); #endif // WITH_RUDP