From abbd69fdbc7b43229093a1ec57ea6d0dd952db8d Mon Sep 17 00:00:00 2001
From: yangchen <yangchen145@huawei.com>
Date: Fri, 26 Jan 2024 17:21:38 +0800
Subject: [PATCH] support netperf UDP_STREAM and UDP_RR

---
 src/lstack/api/lstack_rtw_api.c |  7 +++----
 src/lstack/api/lstack_wrap.c    |  1 +
 src/lstack/core/lstack_lwip.c   | 21 +++++++++++++++------
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/lstack/api/lstack_rtw_api.c b/src/lstack/api/lstack_rtw_api.c
index 04944d5..839d320 100644
--- a/src/lstack/api/lstack_rtw_api.c
+++ b/src/lstack/api/lstack_rtw_api.c
@@ -160,10 +160,10 @@ static ssize_t rtw_udp_recvfrom(int sockfd, void *buf, size_t len, int flags,
 
     while (1) {
         ret = do_lwip_read_from_stack(sockfd, buf, len, flags, addr, addrlen);
-        if (ret > 0) {
+        if (ret >= 0) {
             return ret;
         }
-        if (ret <= 0 && errno != EAGAIN) {
+        if (ret < 0 && errno != EAGAIN) {
             return -1;
         }
         sock = sock->listen_next;
@@ -205,7 +205,6 @@ ssize_t rtw_sendto(int sockfd, const void *buf, size_t len, int flags,
     return do_lwip_send_to_stack(sockfd, buf, len, flags, addr, addrlen);
 }
 
-
 int rtw_epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout)
 {
     return lstack_rtw_epoll_wait(epfd, events, maxevents, timeout);
@@ -234,7 +233,7 @@ int rtw_shutdown(int fd, int how)
 {
     struct lwip_sock *sock = get_socket_by_fd(fd);
     if (sock && sock->wakeup && sock->wakeup->epollfd == fd) {
-	GAZELLE_RETURN(ENOTSOCK);
+        GAZELLE_RETURN(ENOTSOCK);
     }
 
     return stack_broadcast_shutdown(fd, how);
diff --git a/src/lstack/api/lstack_wrap.c b/src/lstack/api/lstack_wrap.c
index 372e102..8992e39 100644
--- a/src/lstack/api/lstack_wrap.c
+++ b/src/lstack/api/lstack_wrap.c
@@ -375,6 +375,7 @@ static bool unsupport_optname(int32_t optname)
         optname == SO_RCVBUF    ||
         optname == TCP_INFO     ||
         optname == TCP_MAXSEG   ||
+        optname == SO_DONTROUTE ||
         optname == TCP_CONGESTION) {
         return true;
     }
diff --git a/src/lstack/core/lstack_lwip.c b/src/lstack/core/lstack_lwip.c
index a7201aa..22605dd 100644
--- a/src/lstack/core/lstack_lwip.c
+++ b/src/lstack/core/lstack_lwip.c
@@ -402,7 +402,7 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si
     }
 
     struct protocol_stack *stack = sock->stack;
-    if (!stack || len == 0) {
+    if (!stack) {
         return 0;
     }
 
@@ -421,6 +421,11 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si
     uint32_t write_avail = gazelle_ring_readable_count(sock->send_ring);
     struct wakeup_poll *wakeup = sock->wakeup;
 
+    /* if udp send 0 packet, set write_num to at least 1 */
+    if (NETCONN_IS_UDP(sock) && write_num == 0) {
+        write_num = 1;
+    }
+
     while (!netconn_is_nonblocking(sock->conn) && (write_avail < write_num)) {
         if (sock->errevent > 0) {
             GAZELLE_RETURN(ENOTCONN);
@@ -454,7 +459,7 @@ static ssize_t do_lwip_fill_sendring(struct lwip_sock *sock, const void *buf, si
     }
 
 END:
-    if (send_len == 0) {
+    if (send_len == 0 && !NETCONN_IS_UDP(sock)) {
         errno = EAGAIN;
         return -1;
     }
@@ -735,19 +740,18 @@ ssize_t do_lwip_send_to_stack(int32_t fd, const void *buf, size_t len, int32_t f
         GAZELLE_RETURN(EINVAL);
     }
 
-    if (len == 0) {
+    struct lwip_sock *sock = get_socket_by_fd(fd);
+    if (len == 0 && !NETCONN_IS_UDP(sock)) {
         return 0;
     }
 
-    struct lwip_sock *sock = get_socket_by_fd(fd);
-
     thread_bind_stack(sock);
 
     if (sock->same_node_tx_ring != NULL) {
         return gazelle_same_node_ring_send(sock, buf, len, flags);
     }
     ssize_t send = do_lwip_fill_sendring(sock, buf, len, addr, addrlen);
-    if (send <= 0) {
+    if (send < 0 || (send == 0 && !NETCONN_IS_UDP(sock))) {
         return send;
     }
 
@@ -852,6 +856,11 @@ ssize_t do_lwip_read_from_stack(int32_t fd, void *buf, size_t len, int32_t flags
             }
         }
 
+        /* if udp recv a packet whose len is 0, return 0 */
+        if (NETCONN_IS_UDP(sock) && pbuf->tot_len == 0) {
+            return 0;
+        }
+
         /* fin */
         if (unlikely(pbuf == NULL)) {
             if (recvd > 0) {
-- 
2.33.0

