Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement protocol handshake #4

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 56 additions & 7 deletions server.cob
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ PROGRAM-ID. server.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 PORT PIC X(5) VALUE "25565".
01 LISTEN PIC X(4).
01 HNDL PIC X(4).
01 ERRNO PIC 9(3) VALUE 0.
*> State of the player (0 = handshake, 1 = status, 2 = login, 3 = play, 255 = disconnect)
01 CLIENT-STATE PIC 9(3) VALUE 0.
01 PORT PIC X(5) VALUE "25565".
01 LISTEN PIC X(4).
01 HNDL PIC X(4).
01 ERRNO PIC 9(3) VALUE 0.
*> State of the player (0 = handshake, 1 = status, 2 = login, 3 = play, 255 = disconnect)
01 CLIENT-STATE PIC 9(3) VALUE 0.
*> Incoming packet data
01 BYTE-COUNT PIC 9(5).
01 PACKET-LENGTH PIC S9(10).
01 PACKET-ID PIC S9(10).
01 BUFFER PIC X(64000).

PROCEDURE DIVISION.

Expand All @@ -34,15 +39,59 @@ AcceptConnection.
STOP RUN.

ReceivePacket SECTION.
*> TODO: Implement packet handling
*> Read packet length
CALL "Read-VarInt" USING HNDL ERRNO BYTE-COUNT PACKET-LENGTH.
PERFORM HandleError.

*> Read packet ID
CALL "Read-VarInt" USING HNDL ERRNO BYTE-COUNT PACKET-ID.
PERFORM HandleError.
SUBTRACT BYTE-COUNT FROM PACKET-LENGTH GIVING PACKET-LENGTH.

DISPLAY "[state=" CLIENT-STATE "] Received packet ID: " PACKET-ID " with length " PACKET-LENGTH " bytes.".

*> Handshake
IF CLIENT-STATE = 0 THEN
PERFORM HandleHandshake
EXIT SECTION
END-IF

*> TODO: Implement login state, play state, etc.
DISPLAY "Login state not implemented."
MOVE 255 TO CLIENT-STATE.

EXIT SECTION.

HandleHandshake SECTION.
IF PACKET-ID NOT = 0 THEN
DISPLAY " Unexpected packet ID: " PACKET-ID
MOVE 255 TO CLIENT-STATE
EXIT SECTION
END-IF

*> Read payload. The final byte encodes the target state.
MOVE PACKET-LENGTH TO BYTE-COUNT
CALL "Read-Raw" USING HNDL BYTE-COUNT ERRNO BUFFER
PERFORM HandleError
MOVE FUNCTION ORD(BUFFER(BYTE-COUNT:1)) TO CLIENT-STATE
SUBTRACT 1 FROM CLIENT-STATE

*> Validate target state
IF CLIENT-STATE NOT = 1 AND CLIENT-STATE NOT = 2 THEN
DISPLAY " Invalid target state: " CLIENT-STATE
MOVE 255 TO CLIENT-STATE
ELSE
DISPLAY " Target state: " CLIENT-STATE
END-IF

EXIT SECTION.

HandleError SECTION.
IF ERRNO NOT = 0 THEN
DISPLAY "Error: " ERRNO
STOP RUN
END-IF.

EXIT SECTION.

END PROGRAM server.
67 changes: 67 additions & 0 deletions src/read.cob
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
*> --- Read-Raw ---
*> Read a raw byte array from the socket.
IDENTIFICATION DIVISION.
PROGRAM-ID. Read-Raw.

DATA DIVISION.
LINKAGE SECTION.
01 LK-HNDL PIC X(4).
01 LK-READ-COUNT PIC 9(5).
01 LK-ERRNO PIC 9(3).
01 LK-VALUE PIC X(64000).

PROCEDURE DIVISION USING BY REFERENCE LK-HNDL LK-READ-COUNT LK-ERRNO LK-VALUE.
IF LK-READ-COUNT < 1
MOVE 0 TO LK-ERRNO
EXIT PROGRAM
END-IF
CALL "CBL_GC_SOCKET" USING "04" LK-HNDL LK-READ-COUNT LK-VALUE GIVING LK-ERRNO.

END PROGRAM Read-Raw.

*> --- Read-VarInt ---
*> Read a VarInt from the socket into an S9(10) field.
IDENTIFICATION DIVISION.
PROGRAM-ID. Read-VarInt.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 BUFFER PIC X.
01 BYTE-COUNT PIC 9(5).
LOCAL-STORAGE SECTION.
01 VARINT-BYTE PIC 9(3) COMP VALUE 0.
01 VARINT-BYTE-VALUE PIC 9(3) COMP VALUE 0.
01 VARINT-MULTIPLIER PIC 9(10) COMP VALUE 1.
01 VARINT-CONTINUE PIC 9 COMP VALUE 1.
LINKAGE SECTION.
01 LK-HNDL PIC X(4).
01 LK-ERRNO PIC 9(3).
01 LK-READ-COUNT PIC 9(5).
01 LK-VALUE PIC S9(10).

PROCEDURE DIVISION USING BY REFERENCE LK-HNDL LK-ERRNO LK-READ-COUNT LK-VALUE.
MOVE 0 TO LK-VALUE.
MOVE 0 TO LK-READ-COUNT.
PERFORM UNTIL VARINT-CONTINUE = 0
*> Receive the next byte
MOVE 1 TO BYTE-COUNT
CALL "CBL_GC_SOCKET" USING "04" LK-HNDL BYTE-COUNT BUFFER GIVING LK-ERRNO
IF LK-ERRNO NOT = 0
EXIT PROGRAM
END-IF
ADD 1 TO LK-READ-COUNT
MOVE FUNCTION ORD(BUFFER(1:1)) TO VARINT-BYTE
SUBTRACT 1 FROM VARINT-BYTE
*> Extract the lower 7 bits
MOVE FUNCTION MOD(VARINT-BYTE, 128) TO VARINT-BYTE-VALUE
*> This yields the value when multiplied by the position multiplier
MULTIPLY VARINT-BYTE-VALUE BY VARINT-MULTIPLIER GIVING VARINT-BYTE-VALUE
ADD VARINT-BYTE-VALUE TO LK-VALUE
MULTIPLY VARINT-MULTIPLIER BY 128 GIVING VARINT-MULTIPLIER
*> Check if we need to continue (if the high bit is set and the maximum number of bytes has not been reached)
IF VARINT-BYTE < 128 OR LK-READ-COUNT >= 5
MOVE 0 TO VARINT-CONTINUE
END-IF
END-PERFORM.

END PROGRAM Read-VarInt.
16 changes: 8 additions & 8 deletions src/socket.cob
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ PROGRAM-ID. Socket-Listen.

DATA DIVISION.
LINKAGE SECTION.
01 LK-PORT PIC X(5).
01 LK-LISTEN PIC X(4).
01 LK-ERRNO PIC 9(3).
01 LK-PORT PIC X(5).
01 LK-LISTEN PIC X(4).
01 LK-ERRNO PIC 9(3).

PROCEDURE DIVISION USING BY REFERENCE LK-PORT LK-LISTEN LK-ERRNO.
CALL "CBL_GC_SOCKET" USING "00" LK-PORT LK-LISTEN GIVING LK-ERRNO.
Expand All @@ -19,9 +19,9 @@ PROGRAM-ID. Socket-Accept.

DATA DIVISION.
LINKAGE SECTION.
01 LK-LISTEN PIC X(4).
01 LK-HNDL PIC X(4).
01 LK-ERRNO PIC 9(3).
01 LK-LISTEN PIC X(4).
01 LK-HNDL PIC X(4).
01 LK-ERRNO PIC 9(3).

PROCEDURE DIVISION USING BY REFERENCE LK-LISTEN LK-HNDL LK-ERRNO.
CALL "CBL_GC_SOCKET" USING "07" LK-LISTEN LK-HNDL GIVING LK-ERRNO.
Expand All @@ -34,8 +34,8 @@ PROGRAM-ID. Socket-Close.

DATA DIVISION.
LINKAGE SECTION.
01 LK-HNDL PIC X(4).
01 LK-ERRNO PIC 9(3).
01 LK-HNDL PIC X(4).
01 LK-ERRNO PIC 9(3).

PROCEDURE DIVISION USING BY REFERENCE LK-HNDL LK-ERRNO.
CALL "CBL_GC_SOCKET" USING "06" LK-HNDL GIVING LK-ERRNO.
Expand Down