@@ -33,27 +33,34 @@ void tcp_send_packet(Context* ctx, TcpFlow* flow, uint8_t flags, const uint8_t*
3333 return ;
3434 }
3535
36+ constexpr uint8_t TCP_OPT_NOP = 1 ;
37+ constexpr uint8_t TCP_OPT_MSS = 2 ;
38+ constexpr uint8_t TCP_OPT_MSS_LEN = 4 ;
39+ constexpr uint8_t TCP_OPT_WSCALE = 3 ;
40+ constexpr uint8_t TCP_OPT_WSCALE_LEN = 3 ;
41+
3642 size_t opt_len = 0 ;
3743 uint8_t options[40 ];
3844 if (flags & NSTUN_TCP_FLAG_SYN ) {
3945 /* Add MSS option (Kind=2, Length=4, MSS=65495) */
40- options[opt_len++] = 2 ;
41- options[opt_len++] = 4 ;
46+ options[opt_len++] = TCP_OPT_MSS ;
47+ options[opt_len++] = TCP_OPT_MSS_LEN ;
4248 uint16_t mss = htons (65495 );
4349 memcpy (&options[opt_len], &mss, 2 );
4450 opt_len += 2 ;
4551
46- /* Add NOP (Kind=1) for 32-bit alignment */
47- options[opt_len++] = 1 ;
52+ /* Add NOP for 32-bit alignment */
53+ options[opt_len++] = TCP_OPT_NOP ;
4854
4955 /* Add Window Scale option (Kind=3, Length=3, Shift=8) */
50- options[opt_len++] = 3 ;
51- options[opt_len++] = 3 ;
56+ options[opt_len++] = TCP_OPT_WSCALE ;
57+ options[opt_len++] = TCP_OPT_WSCALE_LEN ;
5258 options[opt_len++] = 8 ;
5359 }
5460
5561 size_t frame_len = sizeof (ip4_hdr) + sizeof (tcp_hdr) + opt_len + len;
56- uint8_t frame_buf[sizeof (ip4_hdr) + sizeof (tcp_hdr) + sizeof (options) + NSTUN_MTU ];
62+ /* Single-threaded network loop: use static buffer to avoid 63KB stack allocation */
63+ static thread_local uint8_t frame_buf[sizeof (ip4_hdr) + sizeof (tcp_hdr) + 40 + NSTUN_MTU ];
5764
5865 ip4_hdr* r_ip = reinterpret_cast <ip4_hdr*>(frame_buf);
5966 tcp_hdr* r_tcp = reinterpret_cast <tcp_hdr*>(frame_buf + sizeof (ip4_hdr));
@@ -496,6 +503,10 @@ void handle_tcp(Context* ctx, const ip4_hdr* ip, const uint8_t* payload, size_t
496503
497504 if (flow->state == TcpState::ESTABLISHED ) {
498505 flow->state = TcpState::CLOSE_WAIT ;
506+ } else if (flow->state == TcpState::FIN_WAIT_1 ) {
507+ flow->state = TcpState::CLOSING ;
508+ } else if (flow->state == TcpState::FIN_WAIT_2 ) {
509+ flow->state = TcpState::TIME_WAIT ;
499510 }
500511
501512 push_to_guest (ctx, flow);
@@ -630,7 +641,6 @@ void handle_host_tcp_data(Context* ctx, TcpFlow* flow, int fd) {
630641 (flow->inbound && flow->state == TcpState::SYN_SENT )) {
631642 uint8_t buf[65536 ];
632643 ssize_t recv_len = recv (fd, buf, sizeof (buf), 0 );
633- LOG_D (" recv_len=%zd errno=%d" , recv_len, errno);
634644 if (recv_len == 0 ) goto eof;
635645 if (recv_len < 0 ) {
636646 if (errno == EAGAIN || errno == EWOULDBLOCK ) return ;
@@ -757,6 +767,10 @@ void handle_host_tcp_accept(Context* ctx, int listen_fd, const nstun_rule_t& rul
757767 }
758768
759769 LOG_D (" Accepted fd=%d" , fd);
770+
771+ int opt = 1 ;
772+ setsockopt (fd, IPPROTO_TCP , TCP_NODELAY , &opt, sizeof (opt));
773+
760774 struct sockaddr_in server_addr = {};
761775 socklen_t servlen = sizeof (server_addr);
762776 getsockname (fd, (struct sockaddr *)&server_addr, &servlen);
0 commit comments