]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/server.go
Use fixed size array types in Transaction fields
[rbdr/mobius] / hotline / server.go
index f2a69ad735b31c4bcd0884b13ca49c99dd3bd525..5245c7bdda3a2c368bad00d9da7ecbbddcb120b8 100644 (file)
@@ -4,6 +4,7 @@ import (
        "bufio"
        "bytes"
        "context"
+       "crypto/rand"
        "encoding/binary"
        "errors"
        "fmt"
@@ -15,7 +16,6 @@ import (
        "log"
        "log/slog"
        "math/big"
-       "math/rand"
        "net"
        "os"
        "path"
@@ -92,12 +92,6 @@ type PrivateChat struct {
 }
 
 func (s *Server) ListenAndServe(ctx context.Context, cancelRoot context.CancelFunc) error {
-       s.Logger.Info("Hotline server started",
-               "version", VERSION,
-               "API port", fmt.Sprintf("%s:%v", s.NetInterface, s.Port),
-               "Transfer port", fmt.Sprintf("%s:%v", s.NetInterface, s.Port+1),
-       )
-
        var wg sync.WaitGroup
 
        wg.Add(1)
@@ -152,24 +146,19 @@ func (s *Server) ServeFileTransfers(ctx context.Context, ln net.Listener) error
 func (s *Server) sendTransaction(t Transaction) error {
        clientID, err := byteToInt(*t.clientID)
        if err != nil {
-               return err
+               return fmt.Errorf("invalid client ID: %v", err)
        }
 
        s.mux.Lock()
-       client := s.Clients[uint16(clientID)]
+       client, ok := s.Clients[uint16(clientID)]
        s.mux.Unlock()
-       if client == nil {
+       if !ok || client == nil {
                return fmt.Errorf("invalid client id %v", *t.clientID)
        }
 
-       b, err := t.MarshalBinary()
-       if err != nil {
-               return err
-       }
-
-       _, err = client.Connection.Write(b)
+       _, err = io.Copy(client.Connection, &t)
        if err != nil {
-               return err
+               return fmt.Errorf("failed to send transaction to client %v: %v", clientID, err)
        }
 
        return nil
@@ -257,7 +246,7 @@ func NewServer(configDir, netInterface string, netPort int, logger *slog.Logger,
        _ = server.loadBanList(filepath.Join(configDir, "Banlist.yaml"))
 
        if err := server.loadThreadedNews(filepath.Join(configDir, "ThreadedNews.yaml")); err != nil {
-               return nil, err
+               return nil, fmt.Errorf("error loading threaded news: %w", err)
        }
 
        if err := server.loadConfig(filepath.Join(configDir, "config.yaml")); err != nil {
@@ -620,12 +609,7 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
                                NewField(FieldChatOptions, []byte{0, 0}),
                        )
 
-                       b, err := t.MarshalBinary()
-                       if err != nil {
-                               return err
-                       }
-
-                       _, err = rwc.Write(b)
+                       _, err := io.Copy(rwc, t)
                        if err != nil {
                                return err
                        }
@@ -642,12 +626,8 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
                                NewField(FieldData, []byte("You are temporarily banned on this server")),
                                NewField(FieldChatOptions, []byte{0, 0}),
                        )
-                       b, err := t.MarshalBinary()
-                       if err != nil {
-                               return err
-                       }
 
-                       _, err = rwc.Write(b)
+                       _, err := io.Copy(rwc, t)
                        if err != nil {
                                return err
                        }
@@ -677,13 +657,11 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
        // If authentication fails, send error reply and close connection
        if !c.Authenticate(login, encodedPassword) {
                t := c.NewErrReply(&clientLogin, "Incorrect login.")
-               b, err := t.MarshalBinary()
+
+               _, err := io.Copy(rwc, &t)
                if err != nil {
                        return err
                }
-               if _, err := rwc.Write(b); err != nil {
-                       return err
-               }
 
                c.logger.Info("Login failed", "clientVersion", fmt.Sprintf("%x", c.Version))
 
@@ -734,7 +712,7 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
        if len(c.UserName) != 0 {
                // Add the client username to the logger.  For 1.5+ clients, we don't have this information yet as it comes as
                // part of TranAgreed
-               c.logger = c.logger.With("name", string(c.UserName))
+               c.logger = c.logger.With("Name", string(c.UserName))
 
                c.logger.Info("Login successful", "clientVersion", "Not sent (probably 1.2.3)")
 
@@ -782,7 +760,8 @@ func (s *Server) NewPrivateChat(cc *ClientConn) []byte {
        defer s.PrivateChatsMu.Unlock()
 
        randID := make([]byte, 4)
-       rand.Read(randID)
+       _, _ = rand.Read(randID)
+
        data := binary.BigEndian.Uint32(randID)
 
        s.PrivateChats[data] = &PrivateChat{
@@ -838,7 +817,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
        rLogger := s.Logger.With(
                "remoteAddr", ctx.Value(contextKeyReq).(requestCtx).remoteAddr,
                "login", fileTransfer.ClientConn.Account.Login,
-               "name", string(fileTransfer.ClientConn.UserName),
+               "Name", string(fileTransfer.ClientConn.UserName),
        )
 
        fullPath, err := readPath(s.Config.FileRoot, fileTransfer.FilePath, fileTransfer.FileName)