snapshot: sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1
Содержимое пина, зафиксированного в go.mod sing-box-lx, одним коммитом без истории. Полная история SagerNet/gvisor — 1.45 ГБ и клонируется в каждой CI-джобе; наша дельта — одна вставка в одну функцию, история для неё не нужна. Module path github.com/sagernet/gvisor сохранён намеренно: на него опирается replace-директива суперпроекта. Патч поверх — отдельным коммитом, чтобы дельта читалась одним git show и переносилась на новый пин копированием. SPECS/TASKS/048-GVISOR_HANDSHAKE_NIL_CRASH
This commit is contained in:
commit
2c4ae3b0a4
712 changed files with 185689 additions and 0 deletions
124
pkg/tcpip/header/mldv2_igmpv3_common.go
Normal file
124
pkg/tcpip/header/mldv2_igmpv3_common.go
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright 2022 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package header
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/tcpip"
|
||||
)
|
||||
|
||||
func mldv2AndIGMPv3QuerierQueryCodeToInterval(code uint8) time.Duration {
|
||||
// MLDv2: As per RFC 3810 section 5.1.19,
|
||||
//
|
||||
// The Querier's Query Interval Code field specifies the [Query
|
||||
// Interval] used by the Querier. The actual interval, called the
|
||||
// Querier's Query Interval (QQI), is represented in units of seconds,
|
||||
// and is derived from the Querier's Query Interval Code as follows:
|
||||
//
|
||||
// If QQIC < 128, QQI = QQIC
|
||||
//
|
||||
// If QQIC >= 128, QQIC represents a floating-point value as follows:
|
||||
//
|
||||
// 0 1 2 3 4 5 6 7
|
||||
// +-+-+-+-+-+-+-+-+
|
||||
// |1| exp | mant |
|
||||
// +-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// QQI = (mant | 0x10) << (exp + 3)
|
||||
//
|
||||
// Multicast routers that are not the current Querier adopt the QQI
|
||||
// value from the most recently received Query as their own [Query
|
||||
// Interval] value, unless that most recently received QQI was zero, in
|
||||
// which case the receiving routers use the default [Query Interval]
|
||||
// value specified in section 9.2.
|
||||
//
|
||||
// IGMPv3: As per RFC 3376 section 4.1.7,
|
||||
//
|
||||
// The Querier's Query Interval Code field specifies the [Query
|
||||
// Interval] used by the querier. The actual interval, called the
|
||||
// Querier's Query Interval (QQI), is represented in units of seconds
|
||||
// and is derived from the Querier's Query Interval Code as follows:
|
||||
//
|
||||
// If QQIC < 128, QQI = QQIC
|
||||
//
|
||||
// If QQIC >= 128, QQIC represents a floating-point value as follows:
|
||||
//
|
||||
// 0 1 2 3 4 5 6 7
|
||||
// +-+-+-+-+-+-+-+-+
|
||||
// |1| exp | mant |
|
||||
// +-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// QQI = (mant | 0x10) << (exp + 3)
|
||||
//
|
||||
// Multicast routers that are not the current querier adopt the QQI
|
||||
// value from the most recently received Query as their own [Query
|
||||
// Interval] value, unless that most recently received QQI was zero, in
|
||||
// which case the receiving routers use the default [Query Interval]
|
||||
// value specified in section 8.2.
|
||||
interval := time.Duration(code)
|
||||
if interval < 128 {
|
||||
return interval * time.Second
|
||||
}
|
||||
|
||||
const expMask = 0b111
|
||||
const mantBits = 4
|
||||
mant := interval & ((1 << mantBits) - 1)
|
||||
exp := (interval >> mantBits) & expMask
|
||||
return (mant | 0x10) << (exp + 3) * time.Second
|
||||
}
|
||||
|
||||
// MakeAddressIterator returns an AddressIterator.
|
||||
func MakeAddressIterator(addressSize int, buf *bytes.Buffer) AddressIterator {
|
||||
return AddressIterator{addressSize: addressSize, buf: buf}
|
||||
}
|
||||
|
||||
// AddressIterator is an iterator over IPv6 addresses.
|
||||
type AddressIterator struct {
|
||||
addressSize int
|
||||
buf *bytes.Buffer
|
||||
}
|
||||
|
||||
// Done indicates that the iterator has been exhausted/has no more elements.
|
||||
func (it *AddressIterator) Done() bool {
|
||||
return it.buf.Len() == 0
|
||||
}
|
||||
|
||||
// Next returns the next address in the iterator.
|
||||
//
|
||||
// Returns false if the iterator has been exhausted.
|
||||
func (it *AddressIterator) Next() (tcpip.Address, bool) {
|
||||
if it.Done() {
|
||||
var emptyAddress tcpip.Address
|
||||
return emptyAddress, false
|
||||
}
|
||||
|
||||
b := it.buf.Next(it.addressSize)
|
||||
if len(b) != it.addressSize {
|
||||
panic(fmt.Sprintf("got len(buf.Next(%d)) = %d, want = %d", it.addressSize, len(b), it.addressSize))
|
||||
}
|
||||
|
||||
return tcpip.AddrFromSlice(b), true
|
||||
}
|
||||
|
||||
func makeAddressIterator(b []byte, expectedAddresses uint16, addressSize int) (AddressIterator, bool) {
|
||||
expectedLen := int(expectedAddresses) * addressSize
|
||||
if len(b) < expectedLen {
|
||||
return AddressIterator{}, false
|
||||
}
|
||||
return MakeAddressIterator(addressSize, bytes.NewBuffer(b[:expectedLen])), true
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue