- Allow zero-sized requests since they are sent by all current versions of Syncthing. - Stop sending zero-sized requests since that's stupid. --------- Signed-off-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
@@ -1345,6 +1345,12 @@ func (f *sendReceiveFolder) copierRoutine(ctx context.Context, in <-chan copyBlo
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if block.Size == 0 {
|
||||||
|
// Copying zero bytes is a no-op.
|
||||||
|
state.copyDone(block)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if !f.DisableSparseFiles && state.reused == 0 && block.IsEmpty() {
|
if !f.DisableSparseFiles && state.reused == 0 && block.IsEmpty() {
|
||||||
// The block is a block of all zeroes, and we are not reusing
|
// The block is a block of all zeroes, and we are not reusing
|
||||||
// a temp file, so there is no need to do anything with it.
|
// a temp file, so there is no need to do anything with it.
|
||||||
@@ -1534,6 +1540,13 @@ func (f *sendReceiveFolder) pullerRoutine(ctx context.Context, in <-chan pullBlo
|
|||||||
|
|
||||||
bytes := state.block.Size
|
bytes := state.block.Size
|
||||||
|
|
||||||
|
if bytes == 0 {
|
||||||
|
// Pulling zero bytes is a no-op.
|
||||||
|
state.pullDone(state.block)
|
||||||
|
out <- state.sharedPullerState
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if err := requestLimiter.TakeWithContext(ctx, bytes); err != nil {
|
if err := requestLimiter.TakeWithContext(ctx, bytes); err != nil {
|
||||||
state.fail(err)
|
state.fail(err)
|
||||||
out <- state.sharedPullerState
|
out <- state.sharedPullerState
|
||||||
|
|||||||
@@ -891,7 +891,7 @@ func TestPullCtxCancel(t *testing.T) {
|
|||||||
emptyState := func() pullBlockState {
|
emptyState := func() pullBlockState {
|
||||||
return pullBlockState{
|
return pullBlockState{
|
||||||
sharedPullerState: newSharedPullerState(protocol.FileInfo{}, nil, f.folderID, "", nil, nil, false, false, protocol.FileInfo{}, false, false),
|
sharedPullerState: newSharedPullerState(protocol.FileInfo{}, nil, f.folderID, "", nil, nil, false, false, protocol.FileInfo{}, false, false),
|
||||||
block: protocol.BlockInfo{},
|
block: protocol.BlockInfo{Size: 42},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ func (c *rawConnection) dispatcherLoop() (err error) {
|
|||||||
if err := checkFilename(msg.Name); err != nil {
|
if err := checkFilename(msg.Name); err != nil {
|
||||||
return newProtocolError(err, msgContext)
|
return newProtocolError(err, msgContext)
|
||||||
}
|
}
|
||||||
if msg.Size <= 0 {
|
if msg.Size < 0 {
|
||||||
return newProtocolError(fmt.Errorf("request size %d too small", msg.Size), msgContext)
|
return newProtocolError(fmt.Errorf("request size %d too small", msg.Size), msgContext)
|
||||||
}
|
}
|
||||||
if msg.Size > MaxRequestSize {
|
if msg.Size > MaxRequestSize {
|
||||||
|
|||||||
@@ -544,7 +544,7 @@ func TestDispatcherToCloseDeadlock(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRequestMaxSize(t *testing.T) {
|
func TestRequestMaxSize(t *testing.T) {
|
||||||
invalidSize := []int{-65536, 0, MaxRequestSize + 1}
|
invalidSize := []int{-65536, -1, MaxRequestSize + 1}
|
||||||
for _, s := range invalidSize {
|
for _, s := range invalidSize {
|
||||||
t.Run(fmt.Sprintf("invalid/%d", s), func(t *testing.T) {
|
t.Run(fmt.Sprintf("invalid/%d", s), func(t *testing.T) {
|
||||||
m := newTestModel()
|
m := newTestModel()
|
||||||
@@ -592,6 +592,34 @@ func TestRequestMaxSize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRequestZeroSize(t *testing.T) {
|
||||||
|
// A zero-sized request should be accepted, since current versions of
|
||||||
|
// Syncthing send these. See https://github.com/syncthing/syncthing/issues/10709.
|
||||||
|
m := newTestModel()
|
||||||
|
rw := testutil.NewBlockingRW()
|
||||||
|
c := getRawConnection(NewConnection(c0ID, rw, &testutil.NoopRW{}, testutil.NoopCloser{}, m, new(mockedConnectionInfo), CompressionAlways, testKeyGen))
|
||||||
|
c.Start()
|
||||||
|
defer closeAndWait(c, rw)
|
||||||
|
|
||||||
|
c.inbox <- &bep.ClusterConfig{}
|
||||||
|
c.inbox <- &bep.Request{
|
||||||
|
Id: 1,
|
||||||
|
Name: "valid",
|
||||||
|
Size: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case res := <-c.outbox:
|
||||||
|
if msg, ok := res.msg.(*bep.Response); !ok || msg.Id != 1 {
|
||||||
|
t.Errorf("bad response %#v", msg)
|
||||||
|
}
|
||||||
|
case <-c.dispatcherLoopStopped:
|
||||||
|
t.Fatal("dispatcher loop terminated, expected zero-sized request to be accepted")
|
||||||
|
case <-time.After(time.Second):
|
||||||
|
t.Fatal("timed out waiting for response")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRequestInvalidFilename(t *testing.T) {
|
func TestRequestInvalidFilename(t *testing.T) {
|
||||||
m := newTestModel()
|
m := newTestModel()
|
||||||
rw := testutil.NewBlockingRW()
|
rw := testutil.NewBlockingRW()
|
||||||
|
|||||||
Reference in New Issue
Block a user