From 087905492601a55ff53541ef469526051c30aa0b Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sun, 8 Dec 2024 10:40:08 +0800 Subject: Proper UID handling --- clients.go | 28 ++++++++++++++++++++++++++++ errors.go | 1 + main.go | 23 ++++++++++------------- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/clients.go b/clients.go index 15512c0..a1e0641 100644 --- a/clients.go +++ b/clients.go @@ -1,7 +1,9 @@ package main import ( + "crypto/rand" "log/slog" + "math/big" "net" "sync" ) @@ -58,6 +60,32 @@ func (client *Client) Teardown() { } } +func NewLocalClient(conn *net.Conn) (*Client, error) { + client := &Client{ + conn: conn, + Server: self, + State: ClientStatePreRegistration, + Nick: "*", + } + for _ = range 10 { + var uid_ = []byte(self.SID) + for _ = range 6 { + randint, err := rand.Int(rand.Reader, big.NewInt(26)) + if err != nil { + return nil, err + } + uid_ = append(uid_, byte(65 + randint.Uint64())) + } + uid := string(uid_) + _, exists := uidToClient.LoadOrStore(uid, client) + if !exists { + client.UID = uid + return client, nil + } + } + return nil, ErrUIDBusy +} + func (client *Client) checkRegistration() { if client.State != ClientStatePreRegistration { slog.Error("spurious call to checkRegistration", "client", client) diff --git a/errors.go b/errors.go index c8b053f..8ce604a 100644 --- a/errors.go +++ b/errors.go @@ -12,4 +12,5 @@ var ( ErrBodyTooLong = errors.New("body too long") ErrNotConnectedServer = errors.New("not connected server") ErrSendToSelf = errors.New("attempt to send message to self") + ErrUIDBusy = errors.New("too many busy uids") ) diff --git a/main.go b/main.go index b730b9d..15a885c 100644 --- a/main.go +++ b/main.go @@ -30,26 +30,23 @@ func main() { log.Fatal(err) } - client := &Client{ - conn: &conn, - Server: self, - State: ClientStatePreRegistration, - UID: "blah", - Nick: "*", - } - // TODO: Add to the UID table and make actually unique UIDs go func() { - defer func() { - client.Teardown() - (*client.conn).Close() - // TODO: Unified client clean-up - }() defer func() { raised := recover() if raised != nil { slog.Error("connection routine panicked", "raised", raised) } }() + defer func() { + conn.Close() + }() + client, err := NewLocalClient(&conn) + if err != nil { + slog.Error("cannot make new local client", "error", err) + } + defer func() { + client.Teardown() + }() client.handleConnection() }() } -- cgit v1.2.3