Make binary search faster with 11 parallel queries
This commit is contained in:
@@ -132,18 +132,17 @@ func pmtudMultiSizes(ctx context.Context, ip netip.Addr,
|
|||||||
// cannot be working if we had a timeout.
|
// cannot be working if we had a timeout.
|
||||||
for i := len(tests) - 2; i >= 0; i-- { //nolint:mnd
|
for i := len(tests) - 2; i >= 0; i-- { //nolint:mnd
|
||||||
if tests[i].ok {
|
if tests[i].ok {
|
||||||
return pmtudMultiSizes(ctx, ip, tests[i].mtu, tests[i+1].mtu,
|
return pmtudMultiSizes(ctx, ip, tests[i].mtu, tests[i+1].mtu-1,
|
||||||
pingTimeout, logger)
|
pingTimeout, logger)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All MTUs failed.
|
if tests[0].mtu == minMTU+1 { // All MTUs failed.
|
||||||
if tests[0].mtu == minMTU+1 {
|
|
||||||
return minMTU, nil
|
return minMTU, nil
|
||||||
}
|
}
|
||||||
// Re-test with MTUs between the minimum MTU
|
// Re-test with MTUs between the minimum MTU
|
||||||
// and the smallest next MTU we tested.
|
// and the smallest next MTU we tested.
|
||||||
return pmtudMultiSizes(ctx, ip, minMTU, tests[0].mtu,
|
return pmtudMultiSizes(ctx, ip, minMTU, tests[0].mtu-1,
|
||||||
pingTimeout, logger)
|
pingTimeout, logger)
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return 0, fmt.Errorf("collecting ICMP echo replies: %w", err)
|
return 0, fmt.Errorf("collecting ICMP echo replies: %w", err)
|
||||||
@@ -152,14 +151,17 @@ func pmtudMultiSizes(ctx context.Context, ip netip.Addr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the MTU slice of length 8 such that:
|
// Create the MTU slice of length 11 such that:
|
||||||
// - the first element is the minMTU plus the step
|
// - the first element is the minMTU plus the step
|
||||||
// - the last element is the maxMTU
|
// - the last element is the maxMTU
|
||||||
// - elements in-between are separated as close to each other
|
// - elements in-between are separated as close to each other
|
||||||
// - Don't make the minMTU part of the MTUs to test since
|
// - Don't make the minMTU part of the MTUs to test since
|
||||||
// it's assumed it's already working.
|
// it's assumed it's already working.
|
||||||
|
// The number 11 is chosen to find the final MTU in 3 searches;
|
||||||
|
// to find it in 2 searches requires 37 parallel queries which
|
||||||
|
// could be blocked by firewalls.
|
||||||
func makeMTUsToTest(minMTU, maxMTU int) (mtus []int) {
|
func makeMTUsToTest(minMTU, maxMTU int) (mtus []int) {
|
||||||
const mtusLength = 8
|
const mtusLength = 11 // find the final MTU in 3 searches
|
||||||
diff := maxMTU - minMTU
|
diff := maxMTU - minMTU
|
||||||
switch {
|
switch {
|
||||||
case minMTU > maxMTU:
|
case minMTU > maxMTU:
|
||||||
|
|||||||
@@ -27,20 +27,20 @@ func Test_makeMTUsToTest(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"0_12": {
|
"0_12": {
|
||||||
maxMTU: 12,
|
maxMTU: 12,
|
||||||
mtus: []int{2, 3, 5, 6, 8, 9, 11, 12},
|
mtus: []int{1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12},
|
||||||
},
|
},
|
||||||
"0_80": {
|
"0_80": {
|
||||||
maxMTU: 80,
|
maxMTU: 80,
|
||||||
mtus: []int{10, 20, 30, 40, 50, 60, 70, 80},
|
mtus: []int{7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 80},
|
||||||
},
|
},
|
||||||
"0_100": {
|
"0_100": {
|
||||||
maxMTU: 100,
|
maxMTU: 100,
|
||||||
mtus: []int{12, 24, 36, 48, 60, 72, 84, 100},
|
mtus: []int{9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 100},
|
||||||
},
|
},
|
||||||
"1280_1500": {
|
"1280_1500": {
|
||||||
minMTU: 1280,
|
minMTU: 1280,
|
||||||
maxMTU: 1500,
|
maxMTU: 1500,
|
||||||
mtus: []int{1307, 1334, 1361, 1388, 1415, 1442, 1469, 1500},
|
mtus: []int{1300, 1320, 1340, 1360, 1380, 1400, 1420, 1440, 1460, 1480, 1500},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user