hirochachacha / go-smb2

SMB2/3 client library written in Go.
BSD 2-Clause "Simplified" License
350 stars 94 forks source link

Connection Reset by Peer if Application is Idle For Too Long #68

Open trebabcock opened 2 years ago

trebabcock commented 2 years ago

Hello, I wrote a file sync application to sync changes in a local repository to a remote SMB share. Everything is working perfectly so far, except when the program is idle for too long. Seems to take maybe 10-15 minutes. Data is not being sent all the time, I have a select statement that waits on a message from a channel about local changes. Then, depending on the type of change, it applies those changes to the share. Users can sometimes go a little while between saves, so the application will be idle for too long and the connection will reset. They then have to restart the application. I couldn't find anything about a timeout or something similar in the code, and setting a deadline of 0 on the conn.Conn type did nothing. Is something that I would be able to fix, or is this an issue with SMB, or my SMB server specifically?

Error message with some information redacted:

2022/09/16 10:36:30 open Program Files\x\x\x\x.html: connection error: read tcp [ip:port]->[ip:port]: read: connection reset by peer

The only workaround I can think of is to have a goroutine stat a file every few minutes, but that doesn't feel right.

trebabcock commented 2 years ago
conn, err := net.Dial("tcp", server)
if err != nil {
    log.Fatal(err)
}
defer conn.Close()
conn.SetDeadline(time.Time{}) // this did not resolve the issue

d := &smb2.Dialer{
    Initiator: &smb2.NTLMInitiator{
        User:     settings.Username,
        Password: settings.Password,
    },
}

s, err := d.Dial(conn)
if err != nil {
    log.Fatal(err)
}
defer s.Logoff()

share, err := s.Mount("C")
if err != nil {
    log.Fatal(err)
}
defer share.Umount()

go func() {
    for {
        select {
                [...] // application will hang here until local changes are made
                }
        }
}()
jxsl13 commented 2 years ago

implement a redial

hirochachacha commented 2 years ago

you can use WithContext method for timeout

jxsl13 commented 2 years ago

the timeout is the problem, not what he wants. What he wants is a "keep alive" for the connection.