Skip to content

Commit

Permalink
drain inFlight packets in read/write methods
Browse files Browse the repository at this point in the history
Fixes issue pkg#167

File read/write client methods were breaking out of the packet handling
loops with packets still 'in flight' (packets sent without reply from
server) when errors occured. This caused problems after the fact with
the returning packets interfearing with later calls.

This change makes sure all the in flight packets are processed (even if
just discarded) before breaking out of the loop and returning.
  • Loading branch information
eikenb committed Apr 24, 2017
1 parent 63cbed8 commit 700027f
Showing 1 changed file with 6 additions and 12 deletions.
18 changes: 6 additions & 12 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,13 +694,13 @@ func (f *File) Read(b []byte) (int, error) {
inFlight--
if res.err != nil {
firstErr = offsetErr{offset: 0, err: res.err}
break
continue
}
reqID, data := unmarshalUint32(res.data)
req, ok := reqs[reqID]
if !ok {
firstErr = offsetErr{offset: 0, err: errors.Errorf("sid: %v not found", reqID)}
break
continue
}
delete(reqs, reqID)
switch res.typ {
Expand All @@ -710,7 +710,6 @@ func (f *File) Read(b []byte) (int, error) {
offset: req.offset,
err: normaliseError(unmarshalStatus(reqID, res.data)),
}
break
}
case ssh_FXP_DATA:
l, data := unmarshalUint32(data)
Expand All @@ -724,7 +723,6 @@ func (f *File) Read(b []byte) (int, error) {
}
default:
firstErr = offsetErr{offset: 0, err: unimplementedPacketErr(res.typ)}
break
}
}
// If the error is anything other than EOF, then there
Expand Down Expand Up @@ -798,20 +796,19 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
inFlight--
if res.err != nil {
firstErr = offsetErr{offset: 0, err: res.err}
break
continue
}
reqID, data := unmarshalUint32(res.data)
req, ok := reqs[reqID]
if !ok {
firstErr = offsetErr{offset: 0, err: errors.Errorf("sid: %v not found", reqID)}
break
continue
}
delete(reqs, reqID)
switch res.typ {
case ssh_FXP_STATUS:
if firstErr.err == nil || req.offset < firstErr.offset {
firstErr = offsetErr{offset: req.offset, err: normaliseError(unmarshalStatus(reqID, res.data))}
break
}
case ssh_FXP_DATA:
l, data := unmarshalUint32(data)
Expand Down Expand Up @@ -864,7 +861,6 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
}
default:
firstErr = offsetErr{offset: 0, err: unimplementedPacketErr(res.typ)}
break
}
}
if firstErr.err != io.EOF {
Expand Down Expand Up @@ -921,7 +917,7 @@ func (f *File) Write(b []byte) (int, error) {
inFlight--
if res.err != nil {
firstErr = res.err
break
continue
}
switch res.typ {
case ssh_FXP_STATUS:
Expand All @@ -936,7 +932,6 @@ func (f *File) Write(b []byte) (int, error) {
}
default:
firstErr = unimplementedPacketErr(res.typ)
break
}
}
// If error is non-nil, then there may be gaps in the data written to
Expand Down Expand Up @@ -986,7 +981,7 @@ func (f *File) ReadFrom(r io.Reader) (int64, error) {
inFlight--
if res.err != nil {
firstErr = res.err
break
continue
}
switch res.typ {
case ssh_FXP_STATUS:
Expand All @@ -1001,7 +996,6 @@ func (f *File) ReadFrom(r io.Reader) (int64, error) {
}
default:
firstErr = unimplementedPacketErr(res.typ)
break
}
}
if firstErr == io.EOF {
Expand Down

0 comments on commit 700027f

Please sign in to comment.