X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/0db54aa79140c6656f99a851f582c84a0de04233..d29edb0a25c577f6490f21844fa13e13ba3e731e:/hotline/server.go diff --git a/hotline/server.go b/hotline/server.go index ab61e81..06a0695 100644 --- a/hotline/server.go +++ b/hotline/server.go @@ -18,7 +18,6 @@ import ( "net" "os" "path/filepath" - "runtime/debug" "strings" "sync" "time" @@ -43,18 +42,19 @@ const ( var nostalgiaVersion = []byte{0, 0, 2, 0x2c} // version ID used by the Nostalgia client type Server struct { - Port int - Accounts map[string]*Account - Agreement []byte - Clients map[uint16]*ClientConn - ThreadedNews *ThreadedNews - + Port int + Accounts map[string]*Account + Agreement []byte + Clients map[uint16]*ClientConn fileTransfers map[[4]byte]*FileTransfer - Config *Config - ConfigDir string - Logger *zap.SugaredLogger - PrivateChats map[uint32]*PrivateChat + Config *Config + ConfigDir string + Logger *zap.SugaredLogger + + PrivateChatsMu sync.Mutex + PrivateChats map[uint32]*PrivateChat + NextGuestID *uint16 TrackerPassID [4]byte Stats *Stats @@ -64,6 +64,9 @@ type Server struct { outbox chan Transaction mux sync.Mutex + threadedNewsMux sync.Mutex + ThreadedNews *ThreadedNews + flatNewsMux sync.Mutex FlatNews []byte @@ -277,7 +280,7 @@ func NewServer(configDir string, netPort int, logger *zap.SugaredLogger, FS File if err := register(t, tr); err != nil { server.Logger.Errorw("unable to register with tracker %v", "error", err) } - server.Logger.Infow("Sent Tracker registration", "data", tr) + server.Logger.Debugw("Sent Tracker registration", "addr", t) } time.Sleep(trackerUpdateFrequency * time.Second) @@ -342,14 +345,14 @@ func (s *Server) writeBanList() error { } func (s *Server) writeThreadedNews() error { - s.mux.Lock() - defer s.mux.Unlock() + s.threadedNewsMux.Lock() + defer s.threadedNewsMux.Unlock() out, err := yaml.Marshal(s.ThreadedNews) if err != nil { return err } - err = ioutil.WriteFile( + err = s.FS.WriteFile( filepath.Join(s.ConfigDir, "ThreadedNews.yaml"), out, 0666, @@ -541,14 +544,6 @@ func (s *Server) loadConfig(path string) error { return nil } -// dontPanic logs panics instead of crashing -func dontPanic(logger *zap.SugaredLogger) { - if r := recover(); r != nil { - fmt.Println("stacktrace from panic: \n" + string(debug.Stack())) - logger.Errorw("PANIC", "err", r, "trace", string(debug.Stack())) - } -} - // handleNewConnection takes a new net.Conn and performs the initial login sequence func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser, remoteAddr string) error { defer dontPanic(s.Logger) @@ -563,9 +558,9 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser scanner.Scan() - clientLogin, _, err := ReadTransaction(scanner.Bytes()) - if err != nil { - panic(err) + var clientLogin Transaction + if _, err := clientLogin.Write(scanner.Bytes()); err != nil { + return err } c := s.NewClientConn(rwc, remoteAddr) @@ -612,7 +607,7 @@ 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.") + t := c.NewErrReply(&clientLogin, "Incorrect login.") b, err := t.MarshalBinary() if err != nil { return err @@ -644,7 +639,7 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser c.Flags = []byte{0, 2} } - s.outbox <- c.NewReply(clientLogin, + s.outbox <- c.NewReply(&clientLogin, NewField(fieldVersion, []byte{0x00, 0xbe}), NewField(fieldCommunityBannerID, []byte{0, 0}), NewField(fieldServerName, []byte(s.Config.Name)), @@ -693,11 +688,12 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser buf := make([]byte, len(scanner.Bytes())) copy(buf, scanner.Bytes()) - t, _, err := ReadTransaction(buf) - if err != nil { - panic(err) + var t Transaction + if _, err := t.Write(buf); err != nil { + return err } - if err := c.handleTransaction(*t); err != nil { + + if err := c.handleTransaction(t); err != nil { c.logger.Errorw("Error handling transaction", "err", err) } } @@ -705,15 +701,14 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser } func (s *Server) NewPrivateChat(cc *ClientConn) []byte { - s.mux.Lock() - defer s.mux.Unlock() + s.PrivateChatsMu.Lock() + defer s.PrivateChatsMu.Unlock() randID := make([]byte, 4) rand.Read(randID) data := binary.BigEndian.Uint32(randID[:]) s.PrivateChats[data] = &PrivateChat{ - Subject: "", ClientConn: make(map[uint16]*ClientConn), } s.PrivateChats[data].ClientConn[cc.uint16ID()] = cc @@ -773,7 +768,6 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro switch fileTransfer.Type { case bannerDownload: if err := s.bannerDownload(rwc); err != nil { - panic(err) return err } case FileDownload: