]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/server.go
patch: v0.10.11
[rbdr/mobius] / hotline / server.go
index 8d6803b274f411c3a0b1eb4d360a9f9daeccd8b3..1aa9b1a35e074aae26dd90e4dc3f280049c79972 100644 (file)
@@ -153,18 +153,18 @@ func (s *Server) sendTransaction(t Transaction) error {
 
        s.mux.Lock()
        client := s.Clients[uint16(clientID)]
 
        s.mux.Lock()
        client := s.Clients[uint16(clientID)]
+       s.mux.Unlock()
        if client == nil {
                return fmt.Errorf("invalid client id %v", *t.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
        }
 
        b, err := t.MarshalBinary()
        if err != nil {
                return err
        }
 
-       if _, err := client.Connection.Write(b); err != nil {
+       _, err = client.Connection.Write(b)
+       if err != nil {
                return err
        }
 
                return err
        }
 
@@ -565,8 +565,13 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
 
        scanner.Scan()
 
 
        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
        var clientLogin Transaction
-       if _, err := clientLogin.Write(scanner.Bytes()); err != nil {
+       if _, err := clientLogin.Write(buf); err != nil {
                return err
        }
 
                return err
        }
 
@@ -749,6 +754,10 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                delete(s.fileTransfers, t.ReferenceNumber)
                s.mux.Unlock()
 
                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()
        }()
 
        s.mux.Lock()
@@ -783,7 +792,9 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
        case FileDownload:
                s.Stats.DownloadCounter += 1
                s.Stats.DownloadsInProgress += 1
        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 {
 
                var dataOffset int64
                if fileTransfer.fileResumeData != nil {