Skip to content

Commit

Permalink
feat: Implement protocol handshake (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
meyfa authored Apr 2, 2024
1 parent 1d1a87a commit da5030e
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 15 deletions.
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

0 comments on commit da5030e

Please sign in to comment.