diff options
| author | bt <bt@rctt.net> | 2026-03-14 23:11:15 +0100 |
|---|---|---|
| committer | bt <bt@rctt.net> | 2026-03-18 16:21:58 +0100 |
| commit | 54ddec67c477a6fd73b0f623258c0849ba695b88 (patch) | |
| tree | 3a34b67e62b8788f0611abc4f9f8cfe7954aae46 /core | |
| parent | 8932846aa4d29d59fd208f40bbfd44d1bb9cf1ff (diff) | |
| download | solec-54ddec67c477a6fd73b0f623258c0849ba695b88.tar.gz solec-54ddec67c477a6fd73b0f623258c0849ba695b88.zip | |
Basic server implementation
Diffstat (limited to 'core')
| -rw-r--r-- | core/data.go | 30 | ||||
| -rw-r--r-- | core/data_test.go | 3 | ||||
| -rw-r--r-- | core/network.go | 23 | ||||
| -rw-r--r-- | core/payload.go | 95 |
4 files changed, 116 insertions, 35 deletions
diff --git a/core/data.go b/core/data.go index 16775db..b25b853 100644 --- a/core/data.go +++ b/core/data.go @@ -16,13 +16,21 @@ type PayloadType uint8 const ( PayloadUnknown PayloadType = 0x00 - PayloadHandshake = 0x01 - PayloadPing = 0x02 - PayloadPong = 0x03 - PayloadMessage = 0x04 + PayloadSuccess = 0x01 + PayloadError = 0x02 + PayloadHandshake = 0x03 + PayloadAuth = 0x04 + PayloadMessage = 0x05 PayloadTest = 0xFF ) +type ErrorType uint8 + +const ( + ErrorUnknown ErrorType = 0x00 + ErrorAuthFailed = 0x01 +) + type Frame struct { Length uint16 Type PayloadType @@ -41,12 +49,13 @@ func Encode(w Wrapper) ([]byte, error) { for _, p := range payload { switch v := p.(type) { case string: - err := binary.Write(buf, binary.BigEndian, uint16(len(v))) + strBytes := []byte(v) + err := binary.Write(buf, binary.BigEndian, uint16(len(strBytes))) if err != nil { return []byte{}, fmt.Errorf("cannot encode string length: %v", err) } - _, err = buf.WriteString(v) + _, err = buf.Write(strBytes) if err != nil { return []byte{}, fmt.Errorf("cannot encode string: %v", err) } @@ -100,11 +109,16 @@ func Decode(buf io.Reader) (any, error) { } switch pType { + case PayloadSuccess: + return Success{}, nil + case PayloadError: + return DecodeError(buf) case PayloadHandshake: return DecodeHandshake(buf) - case PayloadPing: - case PayloadPong: + case PayloadAuth: + return DecodeAuth(buf) case PayloadMessage: + return DecodeMessage(buf) case PayloadTest: return DecodeTest(buf) default: diff --git a/core/data_test.go b/core/data_test.go index 1275ef4..af986cc 100644 --- a/core/data_test.go +++ b/core/data_test.go @@ -1,6 +1,7 @@ package core import ( + "bytes" "testing" "time" @@ -24,7 +25,7 @@ func TestEncoder(t *testing.T) { t.Error(err) } - out, err := Decode(data) + out, err := Decode(bytes.NewBuffer(data)) if err != nil { t.Error(err) } diff --git a/core/network.go b/core/network.go index c182e7f..932cdca 100644 --- a/core/network.go +++ b/core/network.go @@ -1,24 +1,19 @@ package core import ( - "fmt" "net" ) -func ReadConnection(conn net.Conn) { - for { - payload, err := Decode(conn) - if err != nil { - panic(err) - } - - if err := handle(payload); err != nil { - panic(err) - } +func Send(conn net.Conn, payload Wrapper) error { + data, err := Encode(payload) + if err != nil { + return err } + + _, err = conn.Write(data) + return err } -func handle(payload any) error { - fmt.Println(payload) - return nil +func Read(conn net.Conn) (any, error) { + return Decode(conn) } diff --git a/core/payload.go b/core/payload.go index 0711040..b8e8b9f 100644 --- a/core/payload.go +++ b/core/payload.go @@ -5,6 +5,35 @@ import ( "time" ) +type Success struct{} + +func (s Success) Wrap() (PayloadType, []any) { + return PayloadSuccess, []any{} +} + +type Error struct { + ErrorType ErrorType +} + +func (e Error) Wrap() (PayloadType, []any) { + return PayloadError, []any{e.ErrorType} +} + +func DecodeError(buf io.Reader) (Error, error) { + var ( + errorData uint8 + e Error + ) + + err := decodeNumeric(buf, &errorData) + if err != nil { + return e, err + } + + e.ErrorType = ErrorType(errorData) + return e, nil +} + type Handshake struct { Major, Minor uint8 } @@ -31,30 +60,72 @@ func DecodeHandshake(buf io.Reader) (Handshake, error) { return h, nil } -type Ping struct{} +type Auth struct { + Name string + Pass string +} -func (p Ping) Wrap() (PayloadType, []any) { - return PayloadPing, []any{} +func (a Auth) Wrap() (PayloadType, []any) { + return PayloadAuth, []any{ + a.Name, a.Pass, + } } -type Pong struct { +func DecodeAuth(buf io.Reader) (Auth, error) { + var a Auth + err := decodeString(buf, &a.Name) + if err != nil { + return a, err + } + + err = decodeString(buf, &a.Pass) + if err != nil { + return a, err + } + + return a, nil +} + +type Message struct { + Source string + Target string Timestamp time.Time + Content string } -func (p Pong) Wrap() (PayloadType, []any) { - return PayloadPong, []any{ - p.Timestamp, +func (m Message) Wrap() (PayloadType, []any) { + return PayloadMessage, []any{ + m.Source, + m.Target, + m.Timestamp, + m.Content, } } -func DecodePong(buf io.Reader) (Pong, error) { - var p Pong - err := decodeTime(buf, &p.Timestamp) +func DecodeMessage(buf io.Reader) (Message, error) { + var m Message + + err := decodeString(buf, &m.Source) + if err != nil { + return m, err + } + + err = decodeString(buf, &m.Target) + if err != nil { + return m, err + } + + err = decodeTime(buf, &m.Timestamp) + if err != nil { + return m, err + } + + err = decodeString(buf, &m.Content) if err != nil { - return p, err + return m, err } - return p, nil + return m, nil } type Test struct { |
