X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/361928c9ad8945d525534e3d7178755f49ff6c1f..210c231f9495aeb93ffcf5676069944dbb24550c:/hotline/server.go diff --git a/hotline/server.go b/hotline/server.go index 8d6803b..e28ff9a 100644 --- a/hotline/server.go +++ b/hotline/server.go @@ -152,13 +152,12 @@ func (s *Server) sendTransaction(t Transaction) error { } s.mux.Lock() + defer s.mux.Unlock() client := s.Clients[uint16(clientID)] if client == nil { return fmt.Errorf("invalid client id %v", *t.clientID) } - s.mux.Unlock() - b, err := t.MarshalBinary() if err != nil { return err @@ -565,8 +564,13 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser scanner.Scan() + // Make a new []byte slice and copy the scanner bytes to it. This is critical to avoid a data race as the + // scanner re-uses the buffer for subsequent scans. + buf := make([]byte, len(scanner.Bytes())) + copy(buf, scanner.Bytes()) + var clientLogin Transaction - if _, err := clientLogin.Write(scanner.Bytes()); err != nil { + if _, err := clientLogin.Write(buf); err != nil { return err } @@ -749,6 +753,10 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro delete(s.fileTransfers, t.ReferenceNumber) s.mux.Unlock() + // Wait a few seconds before closing the connection: this is a workaround for problems + // observed with Windows clients where the client must initiate close of the TCP connection before + // the server does. This is gross and seems unnecessary. TODO: Revisit? + time.Sleep(3 * time.Second) }() s.mux.Lock() @@ -783,7 +791,9 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro case FileDownload: s.Stats.DownloadCounter += 1 s.Stats.DownloadsInProgress += 1 - defer func() { s.Stats.DownloadsInProgress -= 1 }() + defer func() { + s.Stats.DownloadsInProgress -= 1 + }() var dataOffset int64 if fileTransfer.fileResumeData != nil {