From ebffb995c6581724b0b6760bf0c68f0f9d0c4160 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Thu, 12 Dec 2024 06:44:47 +0800 Subject: Use uint32 for SIDs, uint64 for CIDs --- clients.go | 41 ++++++++++++++++++----------------------- cmd_cap.go | 3 +++ errors.go | 1 + main.go | 2 +- msg.go | 24 ++---------------------- panics.go | 3 ++- servers.go | 6 +++--- 7 files changed, 30 insertions(+), 50 deletions(-) diff --git a/clients.go b/clients.go index 1c3f8e0..abf7283 100644 --- a/clients.go +++ b/clients.go @@ -1,16 +1,14 @@ package main import ( - "crypto/rand" "log/slog" - "math/big" "net" "sync" ) type Client struct { conn *net.Conn - CID string + CID uint64 Nick string Ident string Gecos string @@ -45,7 +43,7 @@ func (client *Client) ClientSource() string { return client.Nick + "!" + client.Ident + "@" + client.Host } -func (client *Client) ServerSource() string { +func (client *Client) ServerSource() uint64 { return client.CID } @@ -64,6 +62,16 @@ func (client *Client) Teardown() { } func NewLocalClient(conn *net.Conn) (*Client, error) { + var cidPart uint32 + { + cidPartCountLock.Lock() + defer cidPartCountLock.Unlock() + if cidPartCount == ^uint32(0) { // UINT32_MAX + return nil, ErrFullClients + } + cidPartCount++ + cidPart = cidPartCount + } client := &Client{ conn: conn, Server: self, @@ -71,24 +79,9 @@ func NewLocalClient(conn *net.Conn) (*Client, error) { Nick: "*", Caps: make(map[string]struct{}), Extra: make(map[string]any), + CID: uint64(self.SID)<<32 | uint64(cidPart), } - for range 10 { - cid_ := []byte(self.SID) - for range 6 { - randint, err := rand.Int(rand.Reader, big.NewInt(26)) - if err != nil { - return nil, err - } - cid_ = append(cid_, byte(65+randint.Uint64())) - } - cid := string(cid_) - _, exists := cidToClient.LoadOrStore(cid, client) - if !exists { - client.CID = cid - return client, nil - } - } - return nil, ErrCIDBusy + return client, nil } func (client *Client) checkRegistration() error { @@ -136,6 +129,8 @@ const ( ) var ( - cidToClient = sync.Map{} - nickToClient = sync.Map{} + cidToClient = sync.Map{} + nickToClient = sync.Map{} + cidPartCount uint32 + cidPartCountLock sync.Mutex ) diff --git a/cmd_cap.go b/cmd_cap.go index ce70abc..1f641f4 100644 --- a/cmd_cap.go +++ b/cmd_cap.go @@ -33,6 +33,9 @@ func handleClientCap(msg RMsg, client *Client) error { } else { err = client.Send(MakeMsg(self, "CAP", client.Nick, "LS", capls)) } + if err != nil { + return err + } } else { err = client.Send(MakeMsg(self, "CAP", client.Nick, "LS", capls)) } diff --git a/errors.go b/errors.go index 9cd41b5..98a81b3 100644 --- a/errors.go +++ b/errors.go @@ -17,4 +17,5 @@ var ( ErrInconsistentGlobal = errors.New("inconsistent global state") ErrInconsistentClient = errors.New("inconsistent client state") ErrRemoteClient = errors.New("operation not supported for a remote client") + ErrFullClients = errors.New("this server has/had too many clients") ) diff --git a/main.go b/main.go index b17c713..5fa4cad 100644 --- a/main.go +++ b/main.go @@ -18,7 +18,7 @@ func main() { self = &Server{ conn: nil, - SID: "001", + SID: 0, Name: "irc.runxiyu.org", } diff --git a/msg.go b/msg.go index 98ebc14..305add9 100644 --- a/msg.go +++ b/msg.go @@ -13,7 +13,7 @@ type RMsg struct { type Sourceable interface { ClientSource() string - ServerSource() string + ServerSource() uint64 } type SMsg struct { @@ -48,27 +48,7 @@ func (msg *SMsg) ClientSerialize() (final string) { } func (msg *SMsg) ServerSerialize() (final string) { - if len(msg.Tags) != 0 { - final = "@" - for k, v := range msg.Tags { - // TODO: Tag values must be escaped - final += k + "=" + v + ";" - } - final += " " - } - if msg.Source != nil { - final += ":" + msg.Source.ServerSource() + " " - } - final += msg.Command + " " - - if len(msg.Params) > 0 { - for i := 0; i < len(msg.Params)-1; i++ { - final += msg.Params[i] + " " - } - final += ":" + msg.Params[len(msg.Params)-1] - } - final += "\n" - return + panic(panicNotImplemented) } func MakeMsg(source Sourceable, command string, params ...string) (msg SMsg) { diff --git a/panics.go b/panics.go index 5bff91e..7f05d28 100644 --- a/panics.go +++ b/panics.go @@ -1,5 +1,6 @@ package main const ( - panicType = "type error" + panicType = "type error" + panicNotImplemented = "not implemented" ) diff --git a/servers.go b/servers.go index f9dd319..59ed979 100644 --- a/servers.go +++ b/servers.go @@ -7,7 +7,7 @@ import ( type Server struct { conn *net.Conn - SID string + SID uint32 Name string } @@ -38,8 +38,8 @@ func (server *Server) ClientSource() string { return server.Name } -func (server *Server) ServerSource() string { - return server.SID +func (server *Server) ServerSource() uint64 { + return uint64(server.SID) << 32 } var self *Server -- cgit v1.2.3