Compare commits

..
Author SHA1 Message Date
Leency ad36532d4f kernel/net: reset a TCP connection closed with unread data or fed after close
Check kernel codestyle / Check kernel codestyle (pull_request) Successful in 37s
Test PR / Build (en_US) (pull_request) Successful in 3m27s
Test PR / Build (es_ES) (pull_request) Successful in 3m27s
Test PR / Build (ru_RU) (pull_request) Successful in 3m55s
Data arriving on a socket the application had already closed was
accepted into its receive buffer as if someone would read it; the
advertised window shrank by a segment per ACK, reached zero and the
peer then probed it every few seconds for as long as it wanted
(tcp_input only reset the connection when the whole process was gone,
by testing SOCKET.PID). A download cancelled in a browser left such a
connection behind every time.

Mark the socket SS_NOFDREF in socket_close (and on process
termination) and let the existing "data after close" path in tcp_input
act on that flag: the connection is closed and the segment answered
with RST, as BSD does. Closing a socket that still holds unread data
now resets the connection instead of sending FIN (RFC 2525, 2.17), so
the peer is not led to believe the data was delivered and stops sending
at once.

The unlock before tcp_close (and edx kept for the reset reply) is the same as 115910307 on kernel-tcp-socket-list-locking, so the two merge cleanly.
2026-09-30 10:14:24 +03:00
8 changed files with 25 additions and 5689 deletions

No files matched your search

-1
View File
@@ -523,7 +523,6 @@ tup.append_table(img_files, {
{"LIB/RASTERWORKS.OBJ", VAR_PROGS .. "/develop/libraries/fontRasterWorks_unicode/RasterWorks.obj"},
{"LIB/SORT.OBJ", VAR_PROGS .. "/develop/libraries/sorter/sort.obj"},
{"LIB/TINYGL.OBJ", VAR_PROGS .. "/develop/libraries/TinyGL/asm_fork/tinygl.obj"},
{"LIB/XML.OBJ", VAR_PROGS .. "/develop/libraries/asm-xml/xml.obj"},
{"MEDIA/ANIMAGE", VAR_PROGS .. "/media/animage/animage"},
{"MEDIA/FILLSCR", VAR_PROGS .. "/media/FillScr/fillscr"},
{"MEDIA/KIV", VAR_PROGS .. "/media/kiv/kiv"},
+2
View File
@@ -780,6 +780,7 @@ socket_close:
cmp [eax + SOCKET.Protocol], IP_PROTO_TCP
jne .free
or [eax + SOCKET.state], SS_NOFDREF ; the application is gone
test [eax + SOCKET.state], SS_ISDISCONNECTING
jnz @f
call tcp_disconnect
@@ -2406,6 +2407,7 @@ socket_process_end:
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_process_end: killing socket %x\n", ebx
mov [ebx + SOCKET.PID], 0
or [ebx + SOCKET.state], SS_NOFDREF
mov eax, ebx
mov ebx, [ebx + SOCKET.NextPtr]
+13 -2
View File
@@ -722,17 +722,28 @@ endl
.no_duplicate:
;--------------------------------------------------
; Handle data that arrives after process terminates
; Handle data that arrives after the application closed the socket
cmp [ebx + SOCKET.PID], 0 ;;; TODO: use socket flags instead??
test [ebx + SOCKET.state], SS_NOFDREF
jnz .closed_by_app
cmp [ebx + SOCKET.PID], 0
jne .not_terminated
.closed_by_app:
cmp [ebx + TCP_SOCKET.t_state], TCPS_CLOSE_WAIT
jbe .not_terminated
test ecx, ecx
jz .not_terminated
; Unlock the socket, tcp_close frees it
pusha
lea ecx, [ebx + SOCKET.mutex]
call mutex_unlock
popa
mov eax, ebx
push edx
call tcp_close
pop edx
inc [TCPS_rcvafterclose]
jmp .respond_seg_reset
.not_terminated:
+10 -6
View File
@@ -192,13 +192,13 @@ tcp_disconnect:
; je TCP_drop
.nolinger:
call socket_is_disconnecting
push eax
add eax, STREAM_SOCKET.rcv
mov ecx, [eax + RING_BUFFER.size]
call socket_ring_free
pop eax
; Unread data: reset the connection instead of sending FIN (RFC 2525, 2.17)
cmp [eax + STREAM_SOCKET.rcv.size], 0
jne .reset
call socket_is_disconnecting
call tcp_usrclosed
@@ -210,6 +210,10 @@ tcp_disconnect:
@@:
ret
.reset:
mov ebx, ECONNRESET
jmp tcp_drop
;-----------------------------------------------------------------;
; ;
@@ -1,25 +0,0 @@
Copyright (c) 2007-2012, Marc Kerbiquet
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of AsmXml nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -1,2 +0,0 @@
if tup.getconfig("NO_FASM") ~= "" then return end
tup.rule("xml.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "xml.obj")
File diff suppressed because it is too large. Load diff
@@ -1,59 +0,0 @@
; SPDX-License-Identifier: GPL-2.0-only
;
; xml.obj - AsmXml parser as a KolibriOS library
; Copyright (C) KolibriOS team 2026
;
; asm-xml.asm and LICENSE.txt are the unmodified AsmXml 1.4 release
; by Marc Kerbiquet (BSD 3-clause), https://tibleiz.net/asm-xml/
format MS COFF
public EXPORTS
section '.flat' code readable align 16
; AsmXml calls malloc/free as cdecl, the heap functions given to lib_init
; are stdcall: the caller pops the argument they have already taken
lib_init:
mov [mem.alloc], eax
mov [mem.free], ebx
mov eax, malloc
mov ebx, free
jmp initialize
malloc:
push dword [esp + 4]
call [mem.alloc]
ret
free:
push dword [esp + 4]
call [mem.free]
ret
align 4
mem.alloc dd ?
mem.free dd ?
align 16
EXPORTS:
dd sz_lib_init, lib_init
dd sz_initializeParser, _initializeParser
dd sz_releaseParser, _releaseParser
dd sz_parse, _parse
dd sz_initializeClassParser, _initializeClassParser
dd sz_releaseClassParser, _releaseClassParser
dd sz_classFromElement, _classFromElement
dd sz_classFromString, _classFromString
dd 0, 0
sz_lib_init db 'lib_init', 0
sz_initializeParser db 'ax_initializeParser', 0
sz_releaseParser db 'ax_releaseParser', 0
sz_parse db 'ax_parse', 0
sz_initializeClassParser db 'ax_initializeClassParser', 0
sz_releaseClassParser db 'ax_releaseClassParser', 0
sz_classFromElement db 'ax_classFromElement', 0
sz_classFromString db 'ax_classFromString', 0
include 'asm-xml.asm'