SessionReader reads fragmented data and blocks indefinitely #20

Open
opened 2026-03-26 18:49:58 +01:00 by lars.winzer · 2 comments
lars.winzer commented 2026-03-26 18:49:58 +01:00 (Migrated from git.scicore.unibas.ch)

Bug Report

Environment

  • Branch & Commit: First discovered after 4430ddb0f3, but still relevant
  • Operating system: macOS (15.7.1 (24G231))
  • How was execution started (Gradle task / IDE debug / IDE run): IDE debug
  • Java version: 25 (java 25 2025-09-16 LTS)
  • Gradle version: 9.3.1

Summary

The server expects each request to have the following format:

<4 byte size of payload><4 byte id><payload>

If a request violating this format is recieved, all future recieved requests are fragmented.

Expected Behavior

The SessionReader should throw an exception when the request is fragmented.

Actual Behavior

The SessionReader blocks until another request is recieved so that the remaining bytes can be read.

Luckly this only affects one client and all later components should be able to handle malformed data.

Even invalid data should only entail the crash of this specific SessionReader thread.

Steps to Reproduce

  1. Start server (git checkout 4b187fac27461ea958f8254fd8a81e4d8a09599c)
  2. Create simple TcpClient (see notes) to send malformed data to the server
  3. Observe that no log output is shown on the server
  4. Send additional malformed data to the server
  5. Observer that the log shows a fragmented payload

Stack Trace / Error Message

Relevant log output from the server:

18:36:28.887 DEBUG    ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager Accepted connection from /127.0.0.1:53995
18:36:28.888 DEBUG    class ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionReader-4721c392-3473-4d41-859f-bc4f8bcf9178 Recieved: RawPacket[requestId=1214344300, payload=o Welt
                          ]
18:36:28.889 ERROR    class ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionReader-4721c392-3473-4d41-859f-bc4f8bcf9178 Error occured while parsing request. RawPacket: RawPacket[requestId=1214344300, payload=o Welt
                                                                ]

Possible Cause / Notes

Used implementation of TcpClient:

package ch.unibas.dmi.dbis.cs108.casono.client;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class TcpClient {

    private String host;
    private int port;

    public TcpClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public static void main(String[] args) {
        TcpClient client = new TcpClient("localhost", 5123);
        client.run();
    }

    public void run() {
        try {
            // Establish connection
            Socket socket = new Socket(host, port);
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());

            String payload;
            byte[] rawPayload;

            // Send malformed data
            payload = "Hallo Welt";
            rawPayload = payload.getBytes(StandardCharsets.UTF_8);
            out.writeInt(rawPayload.length);
            out.write(rawPayload);
            out.flush();

            // Send additional malformed data
            payload = "Hello World";
            rawPayload = payload.getBytes(StandardCharsets.UTF_8);
            out.writeInt(rawPayload.length);
            out.write(rawPayload);
            out.flush();

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            socket.close();
        } catch (IOException e) {
            System.out.print(e);
        }
    }
}

Possible solutions could be to add an checksum after the payload.

If the calculated checksum mismatches with the recieved, the connection could be closed.

Checklist

  • I reproduced the problem using the steps above
  • I searched documentation docs for relevant information
  • I added relevant labels
## Bug Report <!--The reccommended type is: Issue--> ### Environment - **Branch & Commit:** First discovered after 4430ddb0f33c2d6766c2fe8f2de5169e6c5978c2, but still relevant - **Operating system:** macOS (`15.7.1 (24G231)`) - **How was execution started (Gradle task / IDE debug / IDE run):** IDE debug - **Java version:** `25 (java 25 2025-09-16 LTS)` - **Gradle version**: `9.3.1` ### Summary The server expects each request to have the following format: ``` <4 byte size of payload><4 byte id><payload> ``` If a request violating this format is recieved, all future recieved requests are fragmented. ### Expected Behavior The SessionReader should throw an exception when the request is fragmented. ### Actual Behavior The `SessionReader` blocks until another request is recieved so that the remaining bytes can be read. Luckly this only affects one client and all later components _should_ be able to handle malformed data. Even invalid data should only entail the crash of this specific `SessionReader` thread. ### Steps to Reproduce 1. Start server (`git checkout 4b187fac27461ea958f8254fd8a81e4d8a09599c`) 2. Create simple TcpClient (see notes) to send malformed data to the server 3. Observe that no log output is shown on the server 4. Send additional malformed data to the server 5. Observer that the log shows a fragmented payload ### Stack Trace / Error Message Relevant log output from the server: ``` 18:36:28.887 DEBUG ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager Accepted connection from /127.0.0.1:53995 18:36:28.888 DEBUG class ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionReader-4721c392-3473-4d41-859f-bc4f8bcf9178 Recieved: RawPacket[requestId=1214344300, payload=o Welt ] 18:36:28.889 ERROR class ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionReader-4721c392-3473-4d41-859f-bc4f8bcf9178 Error occured while parsing request. RawPacket: RawPacket[requestId=1214344300, payload=o Welt ] ``` ### Possible Cause / Notes Used implementation of TcpClient: ```java package ch.unibas.dmi.dbis.cs108.casono.client; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.nio.charset.StandardCharsets; public class TcpClient { private String host; private int port; public TcpClient(String host, int port) { this.host = host; this.port = port; } public static void main(String[] args) { TcpClient client = new TcpClient("localhost", 5123); client.run(); } public void run() { try { // Establish connection Socket socket = new Socket(host, port); DataOutputStream out = new DataOutputStream(socket.getOutputStream()); String payload; byte[] rawPayload; // Send malformed data payload = "Hallo Welt"; rawPayload = payload.getBytes(StandardCharsets.UTF_8); out.writeInt(rawPayload.length); out.write(rawPayload); out.flush(); // Send additional malformed data payload = "Hello World"; rawPayload = payload.getBytes(StandardCharsets.UTF_8); out.writeInt(rawPayload.length); out.write(rawPayload); out.flush(); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } socket.close(); } catch (IOException e) { System.out.print(e); } } } ``` Possible solutions could be to add an checksum after the payload. If the calculated checksum mismatches with the recieved, the connection could be closed. ### Checklist - [x] I reproduced the problem using the steps above - [x] I searched documentation docs for relevant information - [x] I added relevant labels
lars.winzer commented 2026-03-26 18:55:20 +01:00 (Migrated from git.scicore.unibas.ch)

added 5m of time spent at 2026-03-25 12:00:00 +0100

added 5m of time spent at 2026-03-25 12:00:00 +0100
lars.winzer commented 2026-03-26 18:55:46 +01:00 (Migrated from git.scicore.unibas.ch)

added 15m of time spent at 2026-03-26 12:00:00 +0100

added 15m of time spent at 2026-03-26 12:00:00 +0100
This repo is archived. You cannot comment on issues.
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: University-of-Basel-Studentprojects/Programmierprojekt#20