Integrate BACKBEAT SDK and resolve KACHING license validation
Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
27
vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
22
vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
41
vendor/golang.org/x/net/bpf/asm.go
generated
vendored
Normal file
41
vendor/golang.org/x/net/bpf/asm.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Assemble converts insts into raw instructions suitable for loading
|
||||
// into a BPF virtual machine.
|
||||
//
|
||||
// Currently, no optimization is attempted, the assembled program flow
|
||||
// is exactly as provided.
|
||||
func Assemble(insts []Instruction) ([]RawInstruction, error) {
|
||||
ret := make([]RawInstruction, len(insts))
|
||||
var err error
|
||||
for i, inst := range insts {
|
||||
ret[i], err = inst.Assemble()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("assembling instruction %d: %s", i+1, err)
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Disassemble attempts to parse raw back into
|
||||
// Instructions. Unrecognized RawInstructions are assumed to be an
|
||||
// extension not implemented by this package, and are passed through
|
||||
// unchanged to the output. The allDecoded value reports whether insts
|
||||
// contains no RawInstructions.
|
||||
func Disassemble(raw []RawInstruction) (insts []Instruction, allDecoded bool) {
|
||||
insts = make([]Instruction, len(raw))
|
||||
allDecoded = true
|
||||
for i, r := range raw {
|
||||
insts[i] = r.Disassemble()
|
||||
if _, ok := insts[i].(RawInstruction); ok {
|
||||
allDecoded = false
|
||||
}
|
||||
}
|
||||
return insts, allDecoded
|
||||
}
|
||||
222
vendor/golang.org/x/net/bpf/constants.go
generated
vendored
Normal file
222
vendor/golang.org/x/net/bpf/constants.go
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf
|
||||
|
||||
// A Register is a register of the BPF virtual machine.
|
||||
type Register uint16
|
||||
|
||||
const (
|
||||
// RegA is the accumulator register. RegA is always the
|
||||
// destination register of ALU operations.
|
||||
RegA Register = iota
|
||||
// RegX is the indirection register, used by LoadIndirect
|
||||
// operations.
|
||||
RegX
|
||||
)
|
||||
|
||||
// An ALUOp is an arithmetic or logic operation.
|
||||
type ALUOp uint16
|
||||
|
||||
// ALU binary operation types.
|
||||
const (
|
||||
ALUOpAdd ALUOp = iota << 4
|
||||
ALUOpSub
|
||||
ALUOpMul
|
||||
ALUOpDiv
|
||||
ALUOpOr
|
||||
ALUOpAnd
|
||||
ALUOpShiftLeft
|
||||
ALUOpShiftRight
|
||||
aluOpNeg // Not exported because it's the only unary ALU operation, and gets its own instruction type.
|
||||
ALUOpMod
|
||||
ALUOpXor
|
||||
)
|
||||
|
||||
// A JumpTest is a comparison operator used in conditional jumps.
|
||||
type JumpTest uint16
|
||||
|
||||
// Supported operators for conditional jumps.
|
||||
// K can be RegX for JumpIfX
|
||||
const (
|
||||
// K == A
|
||||
JumpEqual JumpTest = iota
|
||||
// K != A
|
||||
JumpNotEqual
|
||||
// K > A
|
||||
JumpGreaterThan
|
||||
// K < A
|
||||
JumpLessThan
|
||||
// K >= A
|
||||
JumpGreaterOrEqual
|
||||
// K <= A
|
||||
JumpLessOrEqual
|
||||
// K & A != 0
|
||||
JumpBitsSet
|
||||
// K & A == 0
|
||||
JumpBitsNotSet
|
||||
)
|
||||
|
||||
// An Extension is a function call provided by the kernel that
|
||||
// performs advanced operations that are expensive or impossible
|
||||
// within the BPF virtual machine.
|
||||
//
|
||||
// Extensions are only implemented by the Linux kernel.
|
||||
//
|
||||
// TODO: should we prune this list? Some of these extensions seem
|
||||
// either broken or near-impossible to use correctly, whereas other
|
||||
// (len, random, ifindex) are quite useful.
|
||||
type Extension int
|
||||
|
||||
// Extension functions available in the Linux kernel.
|
||||
const (
|
||||
// extOffset is the negative maximum number of instructions used
|
||||
// to load instructions by overloading the K argument.
|
||||
extOffset = -0x1000
|
||||
// ExtLen returns the length of the packet.
|
||||
ExtLen Extension = 1
|
||||
// ExtProto returns the packet's L3 protocol type.
|
||||
ExtProto Extension = 0
|
||||
// ExtType returns the packet's type (skb->pkt_type in the kernel)
|
||||
//
|
||||
// TODO: better documentation. How nice an API do we want to
|
||||
// provide for these esoteric extensions?
|
||||
ExtType Extension = 4
|
||||
// ExtPayloadOffset returns the offset of the packet payload, or
|
||||
// the first protocol header that the kernel does not know how to
|
||||
// parse.
|
||||
ExtPayloadOffset Extension = 52
|
||||
// ExtInterfaceIndex returns the index of the interface on which
|
||||
// the packet was received.
|
||||
ExtInterfaceIndex Extension = 8
|
||||
// ExtNetlinkAttr returns the netlink attribute of type X at
|
||||
// offset A.
|
||||
ExtNetlinkAttr Extension = 12
|
||||
// ExtNetlinkAttrNested returns the nested netlink attribute of
|
||||
// type X at offset A.
|
||||
ExtNetlinkAttrNested Extension = 16
|
||||
// ExtMark returns the packet's mark value.
|
||||
ExtMark Extension = 20
|
||||
// ExtQueue returns the packet's assigned hardware queue.
|
||||
ExtQueue Extension = 24
|
||||
// ExtLinkLayerType returns the packet's hardware address type
|
||||
// (e.g. Ethernet, Infiniband).
|
||||
ExtLinkLayerType Extension = 28
|
||||
// ExtRXHash returns the packets receive hash.
|
||||
//
|
||||
// TODO: figure out what this rxhash actually is.
|
||||
ExtRXHash Extension = 32
|
||||
// ExtCPUID returns the ID of the CPU processing the current
|
||||
// packet.
|
||||
ExtCPUID Extension = 36
|
||||
// ExtVLANTag returns the packet's VLAN tag.
|
||||
ExtVLANTag Extension = 44
|
||||
// ExtVLANTagPresent returns non-zero if the packet has a VLAN
|
||||
// tag.
|
||||
//
|
||||
// TODO: I think this might be a lie: it reads bit 0x1000 of the
|
||||
// VLAN header, which changed meaning in recent revisions of the
|
||||
// spec - this extension may now return meaningless information.
|
||||
ExtVLANTagPresent Extension = 48
|
||||
// ExtVLANProto returns 0x8100 if the frame has a VLAN header,
|
||||
// 0x88a8 if the frame has a "Q-in-Q" double VLAN header, or some
|
||||
// other value if no VLAN information is present.
|
||||
ExtVLANProto Extension = 60
|
||||
// ExtRand returns a uniformly random uint32.
|
||||
ExtRand Extension = 56
|
||||
)
|
||||
|
||||
// The following gives names to various bit patterns used in opcode construction.
|
||||
|
||||
const (
|
||||
opMaskCls uint16 = 0x7
|
||||
// opClsLoad masks
|
||||
opMaskLoadDest = 0x01
|
||||
opMaskLoadWidth = 0x18
|
||||
opMaskLoadMode = 0xe0
|
||||
// opClsALU & opClsJump
|
||||
opMaskOperand = 0x08
|
||||
opMaskOperator = 0xf0
|
||||
)
|
||||
|
||||
const (
|
||||
// +---------------+-----------------+---+---+---+
|
||||
// | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 0 |
|
||||
// +---------------+-----------------+---+---+---+
|
||||
opClsLoadA uint16 = iota
|
||||
// +---------------+-----------------+---+---+---+
|
||||
// | AddrMode (3b) | LoadWidth (2b) | 0 | 0 | 1 |
|
||||
// +---------------+-----------------+---+---+---+
|
||||
opClsLoadX
|
||||
// +---+---+---+---+---+---+---+---+
|
||||
// | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
|
||||
// +---+---+---+---+---+---+---+---+
|
||||
opClsStoreA
|
||||
// +---+---+---+---+---+---+---+---+
|
||||
// | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
|
||||
// +---+---+---+---+---+---+---+---+
|
||||
opClsStoreX
|
||||
// +---------------+-----------------+---+---+---+
|
||||
// | Operator (4b) | OperandSrc (1b) | 1 | 0 | 0 |
|
||||
// +---------------+-----------------+---+---+---+
|
||||
opClsALU
|
||||
// +-----------------------------+---+---+---+---+
|
||||
// | TestOperator (4b) | 0 | 1 | 0 | 1 |
|
||||
// +-----------------------------+---+---+---+---+
|
||||
opClsJump
|
||||
// +---+-------------------------+---+---+---+---+
|
||||
// | 0 | 0 | 0 | RetSrc (1b) | 0 | 1 | 1 | 0 |
|
||||
// +---+-------------------------+---+---+---+---+
|
||||
opClsReturn
|
||||
// +---+-------------------------+---+---+---+---+
|
||||
// | 0 | 0 | 0 | TXAorTAX (1b) | 0 | 1 | 1 | 1 |
|
||||
// +---+-------------------------+---+---+---+---+
|
||||
opClsMisc
|
||||
)
|
||||
|
||||
const (
|
||||
opAddrModeImmediate uint16 = iota << 5
|
||||
opAddrModeAbsolute
|
||||
opAddrModeIndirect
|
||||
opAddrModeScratch
|
||||
opAddrModePacketLen // actually an extension, not an addressing mode.
|
||||
opAddrModeMemShift
|
||||
)
|
||||
|
||||
const (
|
||||
opLoadWidth4 uint16 = iota << 3
|
||||
opLoadWidth2
|
||||
opLoadWidth1
|
||||
)
|
||||
|
||||
// Operand for ALU and Jump instructions
|
||||
type opOperand uint16
|
||||
|
||||
// Supported operand sources.
|
||||
const (
|
||||
opOperandConstant opOperand = iota << 3
|
||||
opOperandX
|
||||
)
|
||||
|
||||
// An jumpOp is a conditional jump condition.
|
||||
type jumpOp uint16
|
||||
|
||||
// Supported jump conditions.
|
||||
const (
|
||||
opJumpAlways jumpOp = iota << 4
|
||||
opJumpEqual
|
||||
opJumpGT
|
||||
opJumpGE
|
||||
opJumpSet
|
||||
)
|
||||
|
||||
const (
|
||||
opRetSrcConstant uint16 = iota << 4
|
||||
opRetSrcA
|
||||
)
|
||||
|
||||
const (
|
||||
opMiscTAX = 0x00
|
||||
opMiscTXA = 0x80
|
||||
)
|
||||
80
vendor/golang.org/x/net/bpf/doc.go
generated
vendored
Normal file
80
vendor/golang.org/x/net/bpf/doc.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package bpf implements marshaling and unmarshaling of programs for the
|
||||
Berkeley Packet Filter virtual machine, and provides a Go implementation
|
||||
of the virtual machine.
|
||||
|
||||
BPF's main use is to specify a packet filter for network taps, so that
|
||||
the kernel doesn't have to expensively copy every packet it sees to
|
||||
userspace. However, it's been repurposed to other areas where running
|
||||
user code in-kernel is needed. For example, Linux's seccomp uses BPF
|
||||
to apply security policies to system calls. For simplicity, this
|
||||
documentation refers only to packets, but other uses of BPF have their
|
||||
own data payloads.
|
||||
|
||||
BPF programs run in a restricted virtual machine. It has almost no
|
||||
access to kernel functions, and while conditional branches are
|
||||
allowed, they can only jump forwards, to guarantee that there are no
|
||||
infinite loops.
|
||||
|
||||
# The virtual machine
|
||||
|
||||
The BPF VM is an accumulator machine. Its main register, called
|
||||
register A, is an implicit source and destination in all arithmetic
|
||||
and logic operations. The machine also has 16 scratch registers for
|
||||
temporary storage, and an indirection register (register X) for
|
||||
indirect memory access. All registers are 32 bits wide.
|
||||
|
||||
Each run of a BPF program is given one packet, which is placed in the
|
||||
VM's read-only "main memory". LoadAbsolute and LoadIndirect
|
||||
instructions can fetch up to 32 bits at a time into register A for
|
||||
examination.
|
||||
|
||||
The goal of a BPF program is to produce and return a verdict (uint32),
|
||||
which tells the kernel what to do with the packet. In the context of
|
||||
packet filtering, the returned value is the number of bytes of the
|
||||
packet to forward to userspace, or 0 to ignore the packet. Other
|
||||
contexts like seccomp define their own return values.
|
||||
|
||||
In order to simplify programs, attempts to read past the end of the
|
||||
packet terminate the program execution with a verdict of 0 (ignore
|
||||
packet). This means that the vast majority of BPF programs don't need
|
||||
to do any explicit bounds checking.
|
||||
|
||||
In addition to the bytes of the packet, some BPF programs have access
|
||||
to extensions, which are essentially calls to kernel utility
|
||||
functions. Currently, the only extensions supported by this package
|
||||
are the Linux packet filter extensions.
|
||||
|
||||
# Examples
|
||||
|
||||
This packet filter selects all ARP packets.
|
||||
|
||||
bpf.Assemble([]bpf.Instruction{
|
||||
// Load "EtherType" field from the ethernet header.
|
||||
bpf.LoadAbsolute{Off: 12, Size: 2},
|
||||
// Skip over the next instruction if EtherType is not ARP.
|
||||
bpf.JumpIf{Cond: bpf.JumpNotEqual, Val: 0x0806, SkipTrue: 1},
|
||||
// Verdict is "send up to 4k of the packet to userspace."
|
||||
bpf.RetConstant{Val: 4096},
|
||||
// Verdict is "ignore packet."
|
||||
bpf.RetConstant{Val: 0},
|
||||
})
|
||||
|
||||
This packet filter captures a random 1% sample of traffic.
|
||||
|
||||
bpf.Assemble([]bpf.Instruction{
|
||||
// Get a 32-bit random number from the Linux kernel.
|
||||
bpf.LoadExtension{Num: bpf.ExtRand},
|
||||
// 1% dice roll?
|
||||
bpf.JumpIf{Cond: bpf.JumpLessThan, Val: 2^32/100, SkipFalse: 1},
|
||||
// Capture.
|
||||
bpf.RetConstant{Val: 4096},
|
||||
// Ignore.
|
||||
bpf.RetConstant{Val: 0},
|
||||
})
|
||||
*/
|
||||
package bpf // import "golang.org/x/net/bpf"
|
||||
726
vendor/golang.org/x/net/bpf/instructions.go
generated
vendored
Normal file
726
vendor/golang.org/x/net/bpf/instructions.go
generated
vendored
Normal file
@@ -0,0 +1,726 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf
|
||||
|
||||
import "fmt"
|
||||
|
||||
// An Instruction is one instruction executed by the BPF virtual
|
||||
// machine.
|
||||
type Instruction interface {
|
||||
// Assemble assembles the Instruction into a RawInstruction.
|
||||
Assemble() (RawInstruction, error)
|
||||
}
|
||||
|
||||
// A RawInstruction is a raw BPF virtual machine instruction.
|
||||
type RawInstruction struct {
|
||||
// Operation to execute.
|
||||
Op uint16
|
||||
// For conditional jump instructions, the number of instructions
|
||||
// to skip if the condition is true/false.
|
||||
Jt uint8
|
||||
Jf uint8
|
||||
// Constant parameter. The meaning depends on the Op.
|
||||
K uint32
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (ri RawInstruction) Assemble() (RawInstruction, error) { return ri, nil }
|
||||
|
||||
// Disassemble parses ri into an Instruction and returns it. If ri is
|
||||
// not recognized by this package, ri itself is returned.
|
||||
func (ri RawInstruction) Disassemble() Instruction {
|
||||
switch ri.Op & opMaskCls {
|
||||
case opClsLoadA, opClsLoadX:
|
||||
reg := Register(ri.Op & opMaskLoadDest)
|
||||
sz := 0
|
||||
switch ri.Op & opMaskLoadWidth {
|
||||
case opLoadWidth4:
|
||||
sz = 4
|
||||
case opLoadWidth2:
|
||||
sz = 2
|
||||
case opLoadWidth1:
|
||||
sz = 1
|
||||
default:
|
||||
return ri
|
||||
}
|
||||
switch ri.Op & opMaskLoadMode {
|
||||
case opAddrModeImmediate:
|
||||
if sz != 4 {
|
||||
return ri
|
||||
}
|
||||
return LoadConstant{Dst: reg, Val: ri.K}
|
||||
case opAddrModeScratch:
|
||||
if sz != 4 || ri.K > 15 {
|
||||
return ri
|
||||
}
|
||||
return LoadScratch{Dst: reg, N: int(ri.K)}
|
||||
case opAddrModeAbsolute:
|
||||
if ri.K > extOffset+0xffffffff {
|
||||
return LoadExtension{Num: Extension(-extOffset + ri.K)}
|
||||
}
|
||||
return LoadAbsolute{Size: sz, Off: ri.K}
|
||||
case opAddrModeIndirect:
|
||||
return LoadIndirect{Size: sz, Off: ri.K}
|
||||
case opAddrModePacketLen:
|
||||
if sz != 4 {
|
||||
return ri
|
||||
}
|
||||
return LoadExtension{Num: ExtLen}
|
||||
case opAddrModeMemShift:
|
||||
return LoadMemShift{Off: ri.K}
|
||||
default:
|
||||
return ri
|
||||
}
|
||||
|
||||
case opClsStoreA:
|
||||
if ri.Op != opClsStoreA || ri.K > 15 {
|
||||
return ri
|
||||
}
|
||||
return StoreScratch{Src: RegA, N: int(ri.K)}
|
||||
|
||||
case opClsStoreX:
|
||||
if ri.Op != opClsStoreX || ri.K > 15 {
|
||||
return ri
|
||||
}
|
||||
return StoreScratch{Src: RegX, N: int(ri.K)}
|
||||
|
||||
case opClsALU:
|
||||
switch op := ALUOp(ri.Op & opMaskOperator); op {
|
||||
case ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor:
|
||||
switch operand := opOperand(ri.Op & opMaskOperand); operand {
|
||||
case opOperandX:
|
||||
return ALUOpX{Op: op}
|
||||
case opOperandConstant:
|
||||
return ALUOpConstant{Op: op, Val: ri.K}
|
||||
default:
|
||||
return ri
|
||||
}
|
||||
case aluOpNeg:
|
||||
return NegateA{}
|
||||
default:
|
||||
return ri
|
||||
}
|
||||
|
||||
case opClsJump:
|
||||
switch op := jumpOp(ri.Op & opMaskOperator); op {
|
||||
case opJumpAlways:
|
||||
return Jump{Skip: ri.K}
|
||||
case opJumpEqual, opJumpGT, opJumpGE, opJumpSet:
|
||||
cond, skipTrue, skipFalse := jumpOpToTest(op, ri.Jt, ri.Jf)
|
||||
switch operand := opOperand(ri.Op & opMaskOperand); operand {
|
||||
case opOperandX:
|
||||
return JumpIfX{Cond: cond, SkipTrue: skipTrue, SkipFalse: skipFalse}
|
||||
case opOperandConstant:
|
||||
return JumpIf{Cond: cond, Val: ri.K, SkipTrue: skipTrue, SkipFalse: skipFalse}
|
||||
default:
|
||||
return ri
|
||||
}
|
||||
default:
|
||||
return ri
|
||||
}
|
||||
|
||||
case opClsReturn:
|
||||
switch ri.Op {
|
||||
case opClsReturn | opRetSrcA:
|
||||
return RetA{}
|
||||
case opClsReturn | opRetSrcConstant:
|
||||
return RetConstant{Val: ri.K}
|
||||
default:
|
||||
return ri
|
||||
}
|
||||
|
||||
case opClsMisc:
|
||||
switch ri.Op {
|
||||
case opClsMisc | opMiscTAX:
|
||||
return TAX{}
|
||||
case opClsMisc | opMiscTXA:
|
||||
return TXA{}
|
||||
default:
|
||||
return ri
|
||||
}
|
||||
|
||||
default:
|
||||
panic("unreachable") // switch is exhaustive on the bit pattern
|
||||
}
|
||||
}
|
||||
|
||||
func jumpOpToTest(op jumpOp, skipTrue uint8, skipFalse uint8) (JumpTest, uint8, uint8) {
|
||||
var test JumpTest
|
||||
|
||||
// Decode "fake" jump conditions that don't appear in machine code
|
||||
// Ensures the Assemble -> Disassemble stage recreates the same instructions
|
||||
// See https://github.com/golang/go/issues/18470
|
||||
if skipTrue == 0 {
|
||||
switch op {
|
||||
case opJumpEqual:
|
||||
test = JumpNotEqual
|
||||
case opJumpGT:
|
||||
test = JumpLessOrEqual
|
||||
case opJumpGE:
|
||||
test = JumpLessThan
|
||||
case opJumpSet:
|
||||
test = JumpBitsNotSet
|
||||
}
|
||||
|
||||
return test, skipFalse, 0
|
||||
}
|
||||
|
||||
switch op {
|
||||
case opJumpEqual:
|
||||
test = JumpEqual
|
||||
case opJumpGT:
|
||||
test = JumpGreaterThan
|
||||
case opJumpGE:
|
||||
test = JumpGreaterOrEqual
|
||||
case opJumpSet:
|
||||
test = JumpBitsSet
|
||||
}
|
||||
|
||||
return test, skipTrue, skipFalse
|
||||
}
|
||||
|
||||
// LoadConstant loads Val into register Dst.
|
||||
type LoadConstant struct {
|
||||
Dst Register
|
||||
Val uint32
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a LoadConstant) Assemble() (RawInstruction, error) {
|
||||
return assembleLoad(a.Dst, 4, opAddrModeImmediate, a.Val)
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a LoadConstant) String() string {
|
||||
switch a.Dst {
|
||||
case RegA:
|
||||
return fmt.Sprintf("ld #%d", a.Val)
|
||||
case RegX:
|
||||
return fmt.Sprintf("ldx #%d", a.Val)
|
||||
default:
|
||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// LoadScratch loads scratch[N] into register Dst.
|
||||
type LoadScratch struct {
|
||||
Dst Register
|
||||
N int // 0-15
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a LoadScratch) Assemble() (RawInstruction, error) {
|
||||
if a.N < 0 || a.N > 15 {
|
||||
return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N)
|
||||
}
|
||||
return assembleLoad(a.Dst, 4, opAddrModeScratch, uint32(a.N))
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a LoadScratch) String() string {
|
||||
switch a.Dst {
|
||||
case RegA:
|
||||
return fmt.Sprintf("ld M[%d]", a.N)
|
||||
case RegX:
|
||||
return fmt.Sprintf("ldx M[%d]", a.N)
|
||||
default:
|
||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// LoadAbsolute loads packet[Off:Off+Size] as an integer value into
|
||||
// register A.
|
||||
type LoadAbsolute struct {
|
||||
Off uint32
|
||||
Size int // 1, 2 or 4
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a LoadAbsolute) Assemble() (RawInstruction, error) {
|
||||
return assembleLoad(RegA, a.Size, opAddrModeAbsolute, a.Off)
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a LoadAbsolute) String() string {
|
||||
switch a.Size {
|
||||
case 1: // byte
|
||||
return fmt.Sprintf("ldb [%d]", a.Off)
|
||||
case 2: // half word
|
||||
return fmt.Sprintf("ldh [%d]", a.Off)
|
||||
case 4: // word
|
||||
if a.Off > extOffset+0xffffffff {
|
||||
return LoadExtension{Num: Extension(a.Off + 0x1000)}.String()
|
||||
}
|
||||
return fmt.Sprintf("ld [%d]", a.Off)
|
||||
default:
|
||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// LoadIndirect loads packet[X+Off:X+Off+Size] as an integer value
|
||||
// into register A.
|
||||
type LoadIndirect struct {
|
||||
Off uint32
|
||||
Size int // 1, 2 or 4
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a LoadIndirect) Assemble() (RawInstruction, error) {
|
||||
return assembleLoad(RegA, a.Size, opAddrModeIndirect, a.Off)
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a LoadIndirect) String() string {
|
||||
switch a.Size {
|
||||
case 1: // byte
|
||||
return fmt.Sprintf("ldb [x + %d]", a.Off)
|
||||
case 2: // half word
|
||||
return fmt.Sprintf("ldh [x + %d]", a.Off)
|
||||
case 4: // word
|
||||
return fmt.Sprintf("ld [x + %d]", a.Off)
|
||||
default:
|
||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// LoadMemShift multiplies the first 4 bits of the byte at packet[Off]
|
||||
// by 4 and stores the result in register X.
|
||||
//
|
||||
// This instruction is mainly useful to load into X the length of an
|
||||
// IPv4 packet header in a single instruction, rather than have to do
|
||||
// the arithmetic on the header's first byte by hand.
|
||||
type LoadMemShift struct {
|
||||
Off uint32
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a LoadMemShift) Assemble() (RawInstruction, error) {
|
||||
return assembleLoad(RegX, 1, opAddrModeMemShift, a.Off)
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a LoadMemShift) String() string {
|
||||
return fmt.Sprintf("ldx 4*([%d]&0xf)", a.Off)
|
||||
}
|
||||
|
||||
// LoadExtension invokes a linux-specific extension and stores the
|
||||
// result in register A.
|
||||
type LoadExtension struct {
|
||||
Num Extension
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a LoadExtension) Assemble() (RawInstruction, error) {
|
||||
if a.Num == ExtLen {
|
||||
return assembleLoad(RegA, 4, opAddrModePacketLen, 0)
|
||||
}
|
||||
return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(extOffset+a.Num))
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a LoadExtension) String() string {
|
||||
switch a.Num {
|
||||
case ExtLen:
|
||||
return "ld #len"
|
||||
case ExtProto:
|
||||
return "ld #proto"
|
||||
case ExtType:
|
||||
return "ld #type"
|
||||
case ExtPayloadOffset:
|
||||
return "ld #poff"
|
||||
case ExtInterfaceIndex:
|
||||
return "ld #ifidx"
|
||||
case ExtNetlinkAttr:
|
||||
return "ld #nla"
|
||||
case ExtNetlinkAttrNested:
|
||||
return "ld #nlan"
|
||||
case ExtMark:
|
||||
return "ld #mark"
|
||||
case ExtQueue:
|
||||
return "ld #queue"
|
||||
case ExtLinkLayerType:
|
||||
return "ld #hatype"
|
||||
case ExtRXHash:
|
||||
return "ld #rxhash"
|
||||
case ExtCPUID:
|
||||
return "ld #cpu"
|
||||
case ExtVLANTag:
|
||||
return "ld #vlan_tci"
|
||||
case ExtVLANTagPresent:
|
||||
return "ld #vlan_avail"
|
||||
case ExtVLANProto:
|
||||
return "ld #vlan_tpid"
|
||||
case ExtRand:
|
||||
return "ld #rand"
|
||||
default:
|
||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// StoreScratch stores register Src into scratch[N].
|
||||
type StoreScratch struct {
|
||||
Src Register
|
||||
N int // 0-15
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a StoreScratch) Assemble() (RawInstruction, error) {
|
||||
if a.N < 0 || a.N > 15 {
|
||||
return RawInstruction{}, fmt.Errorf("invalid scratch slot %d", a.N)
|
||||
}
|
||||
var op uint16
|
||||
switch a.Src {
|
||||
case RegA:
|
||||
op = opClsStoreA
|
||||
case RegX:
|
||||
op = opClsStoreX
|
||||
default:
|
||||
return RawInstruction{}, fmt.Errorf("invalid source register %v", a.Src)
|
||||
}
|
||||
|
||||
return RawInstruction{
|
||||
Op: op,
|
||||
K: uint32(a.N),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a StoreScratch) String() string {
|
||||
switch a.Src {
|
||||
case RegA:
|
||||
return fmt.Sprintf("st M[%d]", a.N)
|
||||
case RegX:
|
||||
return fmt.Sprintf("stx M[%d]", a.N)
|
||||
default:
|
||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// ALUOpConstant executes A = A <Op> Val.
|
||||
type ALUOpConstant struct {
|
||||
Op ALUOp
|
||||
Val uint32
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a ALUOpConstant) Assemble() (RawInstruction, error) {
|
||||
return RawInstruction{
|
||||
Op: opClsALU | uint16(opOperandConstant) | uint16(a.Op),
|
||||
K: a.Val,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a ALUOpConstant) String() string {
|
||||
switch a.Op {
|
||||
case ALUOpAdd:
|
||||
return fmt.Sprintf("add #%d", a.Val)
|
||||
case ALUOpSub:
|
||||
return fmt.Sprintf("sub #%d", a.Val)
|
||||
case ALUOpMul:
|
||||
return fmt.Sprintf("mul #%d", a.Val)
|
||||
case ALUOpDiv:
|
||||
return fmt.Sprintf("div #%d", a.Val)
|
||||
case ALUOpMod:
|
||||
return fmt.Sprintf("mod #%d", a.Val)
|
||||
case ALUOpAnd:
|
||||
return fmt.Sprintf("and #%d", a.Val)
|
||||
case ALUOpOr:
|
||||
return fmt.Sprintf("or #%d", a.Val)
|
||||
case ALUOpXor:
|
||||
return fmt.Sprintf("xor #%d", a.Val)
|
||||
case ALUOpShiftLeft:
|
||||
return fmt.Sprintf("lsh #%d", a.Val)
|
||||
case ALUOpShiftRight:
|
||||
return fmt.Sprintf("rsh #%d", a.Val)
|
||||
default:
|
||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// ALUOpX executes A = A <Op> X
|
||||
type ALUOpX struct {
|
||||
Op ALUOp
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a ALUOpX) Assemble() (RawInstruction, error) {
|
||||
return RawInstruction{
|
||||
Op: opClsALU | uint16(opOperandX) | uint16(a.Op),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a ALUOpX) String() string {
|
||||
switch a.Op {
|
||||
case ALUOpAdd:
|
||||
return "add x"
|
||||
case ALUOpSub:
|
||||
return "sub x"
|
||||
case ALUOpMul:
|
||||
return "mul x"
|
||||
case ALUOpDiv:
|
||||
return "div x"
|
||||
case ALUOpMod:
|
||||
return "mod x"
|
||||
case ALUOpAnd:
|
||||
return "and x"
|
||||
case ALUOpOr:
|
||||
return "or x"
|
||||
case ALUOpXor:
|
||||
return "xor x"
|
||||
case ALUOpShiftLeft:
|
||||
return "lsh x"
|
||||
case ALUOpShiftRight:
|
||||
return "rsh x"
|
||||
default:
|
||||
return fmt.Sprintf("unknown instruction: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// NegateA executes A = -A.
|
||||
type NegateA struct{}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a NegateA) Assemble() (RawInstruction, error) {
|
||||
return RawInstruction{
|
||||
Op: opClsALU | uint16(aluOpNeg),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a NegateA) String() string {
|
||||
return fmt.Sprintf("neg")
|
||||
}
|
||||
|
||||
// Jump skips the following Skip instructions in the program.
|
||||
type Jump struct {
|
||||
Skip uint32
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a Jump) Assemble() (RawInstruction, error) {
|
||||
return RawInstruction{
|
||||
Op: opClsJump | uint16(opJumpAlways),
|
||||
K: a.Skip,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a Jump) String() string {
|
||||
return fmt.Sprintf("ja %d", a.Skip)
|
||||
}
|
||||
|
||||
// JumpIf skips the following Skip instructions in the program if A
|
||||
// <Cond> Val is true.
|
||||
type JumpIf struct {
|
||||
Cond JumpTest
|
||||
Val uint32
|
||||
SkipTrue uint8
|
||||
SkipFalse uint8
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a JumpIf) Assemble() (RawInstruction, error) {
|
||||
return jumpToRaw(a.Cond, opOperandConstant, a.Val, a.SkipTrue, a.SkipFalse)
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a JumpIf) String() string {
|
||||
return jumpToString(a.Cond, fmt.Sprintf("#%d", a.Val), a.SkipTrue, a.SkipFalse)
|
||||
}
|
||||
|
||||
// JumpIfX skips the following Skip instructions in the program if A
|
||||
// <Cond> X is true.
|
||||
type JumpIfX struct {
|
||||
Cond JumpTest
|
||||
SkipTrue uint8
|
||||
SkipFalse uint8
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a JumpIfX) Assemble() (RawInstruction, error) {
|
||||
return jumpToRaw(a.Cond, opOperandX, 0, a.SkipTrue, a.SkipFalse)
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a JumpIfX) String() string {
|
||||
return jumpToString(a.Cond, "x", a.SkipTrue, a.SkipFalse)
|
||||
}
|
||||
|
||||
// jumpToRaw assembles a jump instruction into a RawInstruction
|
||||
func jumpToRaw(test JumpTest, operand opOperand, k uint32, skipTrue, skipFalse uint8) (RawInstruction, error) {
|
||||
var (
|
||||
cond jumpOp
|
||||
flip bool
|
||||
)
|
||||
switch test {
|
||||
case JumpEqual:
|
||||
cond = opJumpEqual
|
||||
case JumpNotEqual:
|
||||
cond, flip = opJumpEqual, true
|
||||
case JumpGreaterThan:
|
||||
cond = opJumpGT
|
||||
case JumpLessThan:
|
||||
cond, flip = opJumpGE, true
|
||||
case JumpGreaterOrEqual:
|
||||
cond = opJumpGE
|
||||
case JumpLessOrEqual:
|
||||
cond, flip = opJumpGT, true
|
||||
case JumpBitsSet:
|
||||
cond = opJumpSet
|
||||
case JumpBitsNotSet:
|
||||
cond, flip = opJumpSet, true
|
||||
default:
|
||||
return RawInstruction{}, fmt.Errorf("unknown JumpTest %v", test)
|
||||
}
|
||||
jt, jf := skipTrue, skipFalse
|
||||
if flip {
|
||||
jt, jf = jf, jt
|
||||
}
|
||||
return RawInstruction{
|
||||
Op: opClsJump | uint16(cond) | uint16(operand),
|
||||
Jt: jt,
|
||||
Jf: jf,
|
||||
K: k,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// jumpToString converts a jump instruction to assembler notation
|
||||
func jumpToString(cond JumpTest, operand string, skipTrue, skipFalse uint8) string {
|
||||
switch cond {
|
||||
// K == A
|
||||
case JumpEqual:
|
||||
return conditionalJump(operand, skipTrue, skipFalse, "jeq", "jneq")
|
||||
// K != A
|
||||
case JumpNotEqual:
|
||||
return fmt.Sprintf("jneq %s,%d", operand, skipTrue)
|
||||
// K > A
|
||||
case JumpGreaterThan:
|
||||
return conditionalJump(operand, skipTrue, skipFalse, "jgt", "jle")
|
||||
// K < A
|
||||
case JumpLessThan:
|
||||
return fmt.Sprintf("jlt %s,%d", operand, skipTrue)
|
||||
// K >= A
|
||||
case JumpGreaterOrEqual:
|
||||
return conditionalJump(operand, skipTrue, skipFalse, "jge", "jlt")
|
||||
// K <= A
|
||||
case JumpLessOrEqual:
|
||||
return fmt.Sprintf("jle %s,%d", operand, skipTrue)
|
||||
// K & A != 0
|
||||
case JumpBitsSet:
|
||||
if skipFalse > 0 {
|
||||
return fmt.Sprintf("jset %s,%d,%d", operand, skipTrue, skipFalse)
|
||||
}
|
||||
return fmt.Sprintf("jset %s,%d", operand, skipTrue)
|
||||
// K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips
|
||||
case JumpBitsNotSet:
|
||||
return jumpToString(JumpBitsSet, operand, skipFalse, skipTrue)
|
||||
default:
|
||||
return fmt.Sprintf("unknown JumpTest %#v", cond)
|
||||
}
|
||||
}
|
||||
|
||||
func conditionalJump(operand string, skipTrue, skipFalse uint8, positiveJump, negativeJump string) string {
|
||||
if skipTrue > 0 {
|
||||
if skipFalse > 0 {
|
||||
return fmt.Sprintf("%s %s,%d,%d", positiveJump, operand, skipTrue, skipFalse)
|
||||
}
|
||||
return fmt.Sprintf("%s %s,%d", positiveJump, operand, skipTrue)
|
||||
}
|
||||
return fmt.Sprintf("%s %s,%d", negativeJump, operand, skipFalse)
|
||||
}
|
||||
|
||||
// RetA exits the BPF program, returning the value of register A.
|
||||
type RetA struct{}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a RetA) Assemble() (RawInstruction, error) {
|
||||
return RawInstruction{
|
||||
Op: opClsReturn | opRetSrcA,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a RetA) String() string {
|
||||
return fmt.Sprintf("ret a")
|
||||
}
|
||||
|
||||
// RetConstant exits the BPF program, returning a constant value.
|
||||
type RetConstant struct {
|
||||
Val uint32
|
||||
}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a RetConstant) Assemble() (RawInstruction, error) {
|
||||
return RawInstruction{
|
||||
Op: opClsReturn | opRetSrcConstant,
|
||||
K: a.Val,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a RetConstant) String() string {
|
||||
return fmt.Sprintf("ret #%d", a.Val)
|
||||
}
|
||||
|
||||
// TXA copies the value of register X to register A.
|
||||
type TXA struct{}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a TXA) Assemble() (RawInstruction, error) {
|
||||
return RawInstruction{
|
||||
Op: opClsMisc | opMiscTXA,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a TXA) String() string {
|
||||
return fmt.Sprintf("txa")
|
||||
}
|
||||
|
||||
// TAX copies the value of register A to register X.
|
||||
type TAX struct{}
|
||||
|
||||
// Assemble implements the Instruction Assemble method.
|
||||
func (a TAX) Assemble() (RawInstruction, error) {
|
||||
return RawInstruction{
|
||||
Op: opClsMisc | opMiscTAX,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// String returns the instruction in assembler notation.
|
||||
func (a TAX) String() string {
|
||||
return fmt.Sprintf("tax")
|
||||
}
|
||||
|
||||
func assembleLoad(dst Register, loadSize int, mode uint16, k uint32) (RawInstruction, error) {
|
||||
var (
|
||||
cls uint16
|
||||
sz uint16
|
||||
)
|
||||
switch dst {
|
||||
case RegA:
|
||||
cls = opClsLoadA
|
||||
case RegX:
|
||||
cls = opClsLoadX
|
||||
default:
|
||||
return RawInstruction{}, fmt.Errorf("invalid target register %v", dst)
|
||||
}
|
||||
switch loadSize {
|
||||
case 1:
|
||||
sz = opLoadWidth1
|
||||
case 2:
|
||||
sz = opLoadWidth2
|
||||
case 4:
|
||||
sz = opLoadWidth4
|
||||
default:
|
||||
return RawInstruction{}, fmt.Errorf("invalid load byte length %d", sz)
|
||||
}
|
||||
return RawInstruction{
|
||||
Op: cls | sz | mode,
|
||||
K: k,
|
||||
}, nil
|
||||
}
|
||||
10
vendor/golang.org/x/net/bpf/setter.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/bpf/setter.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf
|
||||
|
||||
// A Setter is a type which can attach a compiled BPF filter to itself.
|
||||
type Setter interface {
|
||||
SetBPF(filter []RawInstruction) error
|
||||
}
|
||||
150
vendor/golang.org/x/net/bpf/vm.go
generated
vendored
Normal file
150
vendor/golang.org/x/net/bpf/vm.go
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// A VM is an emulated BPF virtual machine.
|
||||
type VM struct {
|
||||
filter []Instruction
|
||||
}
|
||||
|
||||
// NewVM returns a new VM using the input BPF program.
|
||||
func NewVM(filter []Instruction) (*VM, error) {
|
||||
if len(filter) == 0 {
|
||||
return nil, errors.New("one or more Instructions must be specified")
|
||||
}
|
||||
|
||||
for i, ins := range filter {
|
||||
check := len(filter) - (i + 1)
|
||||
switch ins := ins.(type) {
|
||||
// Check for out-of-bounds jumps in instructions
|
||||
case Jump:
|
||||
if check <= int(ins.Skip) {
|
||||
return nil, fmt.Errorf("cannot jump %d instructions; jumping past program bounds", ins.Skip)
|
||||
}
|
||||
case JumpIf:
|
||||
if check <= int(ins.SkipTrue) {
|
||||
return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue)
|
||||
}
|
||||
if check <= int(ins.SkipFalse) {
|
||||
return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse)
|
||||
}
|
||||
case JumpIfX:
|
||||
if check <= int(ins.SkipTrue) {
|
||||
return nil, fmt.Errorf("cannot jump %d instructions in true case; jumping past program bounds", ins.SkipTrue)
|
||||
}
|
||||
if check <= int(ins.SkipFalse) {
|
||||
return nil, fmt.Errorf("cannot jump %d instructions in false case; jumping past program bounds", ins.SkipFalse)
|
||||
}
|
||||
// Check for division or modulus by zero
|
||||
case ALUOpConstant:
|
||||
if ins.Val != 0 {
|
||||
break
|
||||
}
|
||||
|
||||
switch ins.Op {
|
||||
case ALUOpDiv, ALUOpMod:
|
||||
return nil, errors.New("cannot divide by zero using ALUOpConstant")
|
||||
}
|
||||
// Check for unknown extensions
|
||||
case LoadExtension:
|
||||
switch ins.Num {
|
||||
case ExtLen:
|
||||
default:
|
||||
return nil, fmt.Errorf("extension %d not implemented", ins.Num)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure last instruction is a return instruction
|
||||
switch filter[len(filter)-1].(type) {
|
||||
case RetA, RetConstant:
|
||||
default:
|
||||
return nil, errors.New("BPF program must end with RetA or RetConstant")
|
||||
}
|
||||
|
||||
// Though our VM works using disassembled instructions, we
|
||||
// attempt to assemble the input filter anyway to ensure it is compatible
|
||||
// with an operating system VM.
|
||||
_, err := Assemble(filter)
|
||||
|
||||
return &VM{
|
||||
filter: filter,
|
||||
}, err
|
||||
}
|
||||
|
||||
// Run runs the VM's BPF program against the input bytes.
|
||||
// Run returns the number of bytes accepted by the BPF program, and any errors
|
||||
// which occurred while processing the program.
|
||||
func (v *VM) Run(in []byte) (int, error) {
|
||||
var (
|
||||
// Registers of the virtual machine
|
||||
regA uint32
|
||||
regX uint32
|
||||
regScratch [16]uint32
|
||||
|
||||
// OK is true if the program should continue processing the next
|
||||
// instruction, or false if not, causing the loop to break
|
||||
ok = true
|
||||
)
|
||||
|
||||
// TODO(mdlayher): implement:
|
||||
// - NegateA:
|
||||
// - would require a change from uint32 registers to int32
|
||||
// registers
|
||||
|
||||
// TODO(mdlayher): add interop tests that check signedness of ALU
|
||||
// operations against kernel implementation, and make sure Go
|
||||
// implementation matches behavior
|
||||
|
||||
for i := 0; i < len(v.filter) && ok; i++ {
|
||||
ins := v.filter[i]
|
||||
|
||||
switch ins := ins.(type) {
|
||||
case ALUOpConstant:
|
||||
regA = aluOpConstant(ins, regA)
|
||||
case ALUOpX:
|
||||
regA, ok = aluOpX(ins, regA, regX)
|
||||
case Jump:
|
||||
i += int(ins.Skip)
|
||||
case JumpIf:
|
||||
jump := jumpIf(ins, regA)
|
||||
i += jump
|
||||
case JumpIfX:
|
||||
jump := jumpIfX(ins, regA, regX)
|
||||
i += jump
|
||||
case LoadAbsolute:
|
||||
regA, ok = loadAbsolute(ins, in)
|
||||
case LoadConstant:
|
||||
regA, regX = loadConstant(ins, regA, regX)
|
||||
case LoadExtension:
|
||||
regA = loadExtension(ins, in)
|
||||
case LoadIndirect:
|
||||
regA, ok = loadIndirect(ins, in, regX)
|
||||
case LoadMemShift:
|
||||
regX, ok = loadMemShift(ins, in)
|
||||
case LoadScratch:
|
||||
regA, regX = loadScratch(ins, regScratch, regA, regX)
|
||||
case RetA:
|
||||
return int(regA), nil
|
||||
case RetConstant:
|
||||
return int(ins.Val), nil
|
||||
case StoreScratch:
|
||||
regScratch = storeScratch(ins, regScratch, regA, regX)
|
||||
case TAX:
|
||||
regX = regA
|
||||
case TXA:
|
||||
regA = regX
|
||||
default:
|
||||
return 0, fmt.Errorf("unknown Instruction at index %d: %T", i, ins)
|
||||
}
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
182
vendor/golang.org/x/net/bpf/vm_instructions.go
generated
vendored
Normal file
182
vendor/golang.org/x/net/bpf/vm_instructions.go
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bpf
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func aluOpConstant(ins ALUOpConstant, regA uint32) uint32 {
|
||||
return aluOpCommon(ins.Op, regA, ins.Val)
|
||||
}
|
||||
|
||||
func aluOpX(ins ALUOpX, regA uint32, regX uint32) (uint32, bool) {
|
||||
// Guard against division or modulus by zero by terminating
|
||||
// the program, as the OS BPF VM does
|
||||
if regX == 0 {
|
||||
switch ins.Op {
|
||||
case ALUOpDiv, ALUOpMod:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
return aluOpCommon(ins.Op, regA, regX), true
|
||||
}
|
||||
|
||||
func aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 {
|
||||
switch op {
|
||||
case ALUOpAdd:
|
||||
return regA + value
|
||||
case ALUOpSub:
|
||||
return regA - value
|
||||
case ALUOpMul:
|
||||
return regA * value
|
||||
case ALUOpDiv:
|
||||
// Division by zero not permitted by NewVM and aluOpX checks
|
||||
return regA / value
|
||||
case ALUOpOr:
|
||||
return regA | value
|
||||
case ALUOpAnd:
|
||||
return regA & value
|
||||
case ALUOpShiftLeft:
|
||||
return regA << value
|
||||
case ALUOpShiftRight:
|
||||
return regA >> value
|
||||
case ALUOpMod:
|
||||
// Modulus by zero not permitted by NewVM and aluOpX checks
|
||||
return regA % value
|
||||
case ALUOpXor:
|
||||
return regA ^ value
|
||||
default:
|
||||
return regA
|
||||
}
|
||||
}
|
||||
|
||||
func jumpIf(ins JumpIf, regA uint32) int {
|
||||
return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, ins.Val)
|
||||
}
|
||||
|
||||
func jumpIfX(ins JumpIfX, regA uint32, regX uint32) int {
|
||||
return jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, regX)
|
||||
}
|
||||
|
||||
func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value uint32) int {
|
||||
var ok bool
|
||||
|
||||
switch cond {
|
||||
case JumpEqual:
|
||||
ok = regA == value
|
||||
case JumpNotEqual:
|
||||
ok = regA != value
|
||||
case JumpGreaterThan:
|
||||
ok = regA > value
|
||||
case JumpLessThan:
|
||||
ok = regA < value
|
||||
case JumpGreaterOrEqual:
|
||||
ok = regA >= value
|
||||
case JumpLessOrEqual:
|
||||
ok = regA <= value
|
||||
case JumpBitsSet:
|
||||
ok = (regA & value) != 0
|
||||
case JumpBitsNotSet:
|
||||
ok = (regA & value) == 0
|
||||
}
|
||||
|
||||
if ok {
|
||||
return int(skipTrue)
|
||||
}
|
||||
|
||||
return int(skipFalse)
|
||||
}
|
||||
|
||||
func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) {
|
||||
offset := int(ins.Off)
|
||||
size := ins.Size
|
||||
|
||||
return loadCommon(in, offset, size)
|
||||
}
|
||||
|
||||
func loadConstant(ins LoadConstant, regA uint32, regX uint32) (uint32, uint32) {
|
||||
switch ins.Dst {
|
||||
case RegA:
|
||||
regA = ins.Val
|
||||
case RegX:
|
||||
regX = ins.Val
|
||||
}
|
||||
|
||||
return regA, regX
|
||||
}
|
||||
|
||||
func loadExtension(ins LoadExtension, in []byte) uint32 {
|
||||
switch ins.Num {
|
||||
case ExtLen:
|
||||
return uint32(len(in))
|
||||
default:
|
||||
panic(fmt.Sprintf("unimplemented extension: %d", ins.Num))
|
||||
}
|
||||
}
|
||||
|
||||
func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) {
|
||||
offset := int(ins.Off) + int(regX)
|
||||
size := ins.Size
|
||||
|
||||
return loadCommon(in, offset, size)
|
||||
}
|
||||
|
||||
func loadMemShift(ins LoadMemShift, in []byte) (uint32, bool) {
|
||||
offset := int(ins.Off)
|
||||
|
||||
// Size of LoadMemShift is always 1 byte
|
||||
if !inBounds(len(in), offset, 1) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Mask off high 4 bits and multiply low 4 bits by 4
|
||||
return uint32(in[offset]&0x0f) * 4, true
|
||||
}
|
||||
|
||||
func inBounds(inLen int, offset int, size int) bool {
|
||||
return offset+size <= inLen
|
||||
}
|
||||
|
||||
func loadCommon(in []byte, offset int, size int) (uint32, bool) {
|
||||
if !inBounds(len(in), offset, size) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
switch size {
|
||||
case 1:
|
||||
return uint32(in[offset]), true
|
||||
case 2:
|
||||
return uint32(binary.BigEndian.Uint16(in[offset : offset+size])), true
|
||||
case 4:
|
||||
return uint32(binary.BigEndian.Uint32(in[offset : offset+size])), true
|
||||
default:
|
||||
panic(fmt.Sprintf("invalid load size: %d", size))
|
||||
}
|
||||
}
|
||||
|
||||
func loadScratch(ins LoadScratch, regScratch [16]uint32, regA uint32, regX uint32) (uint32, uint32) {
|
||||
switch ins.Dst {
|
||||
case RegA:
|
||||
regA = regScratch[ins.N]
|
||||
case RegX:
|
||||
regX = regScratch[ins.N]
|
||||
}
|
||||
|
||||
return regA, regX
|
||||
}
|
||||
|
||||
func storeScratch(ins StoreScratch, regScratch [16]uint32, regA uint32, regX uint32) [16]uint32 {
|
||||
switch ins.Src {
|
||||
case RegA:
|
||||
regScratch[ins.N] = regA
|
||||
case RegX:
|
||||
regScratch[ins.N] = regX
|
||||
}
|
||||
|
||||
return regScratch
|
||||
}
|
||||
50
vendor/golang.org/x/net/http/httpguts/guts.go
generated
vendored
Normal file
50
vendor/golang.org/x/net/http/httpguts/guts.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package httpguts provides functions implementing various details
|
||||
// of the HTTP specification.
|
||||
//
|
||||
// This package is shared by the standard library (which vendors it)
|
||||
// and x/net/http2. It comes with no API stability promise.
|
||||
package httpguts
|
||||
|
||||
import (
|
||||
"net/textproto"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ValidTrailerHeader reports whether name is a valid header field name to appear
|
||||
// in trailers.
|
||||
// See RFC 7230, Section 4.1.2
|
||||
func ValidTrailerHeader(name string) bool {
|
||||
name = textproto.CanonicalMIMEHeaderKey(name)
|
||||
if strings.HasPrefix(name, "If-") || badTrailer[name] {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var badTrailer = map[string]bool{
|
||||
"Authorization": true,
|
||||
"Cache-Control": true,
|
||||
"Connection": true,
|
||||
"Content-Encoding": true,
|
||||
"Content-Length": true,
|
||||
"Content-Range": true,
|
||||
"Content-Type": true,
|
||||
"Expect": true,
|
||||
"Host": true,
|
||||
"Keep-Alive": true,
|
||||
"Max-Forwards": true,
|
||||
"Pragma": true,
|
||||
"Proxy-Authenticate": true,
|
||||
"Proxy-Authorization": true,
|
||||
"Proxy-Connection": true,
|
||||
"Range": true,
|
||||
"Realm": true,
|
||||
"Te": true,
|
||||
"Trailer": true,
|
||||
"Transfer-Encoding": true,
|
||||
"Www-Authenticate": true,
|
||||
}
|
||||
347
vendor/golang.org/x/net/http/httpguts/httplex.go
generated
vendored
Normal file
347
vendor/golang.org/x/net/http/httpguts/httplex.go
generated
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package httpguts
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/net/idna"
|
||||
)
|
||||
|
||||
var isTokenTable = [256]bool{
|
||||
'!': true,
|
||||
'#': true,
|
||||
'$': true,
|
||||
'%': true,
|
||||
'&': true,
|
||||
'\'': true,
|
||||
'*': true,
|
||||
'+': true,
|
||||
'-': true,
|
||||
'.': true,
|
||||
'0': true,
|
||||
'1': true,
|
||||
'2': true,
|
||||
'3': true,
|
||||
'4': true,
|
||||
'5': true,
|
||||
'6': true,
|
||||
'7': true,
|
||||
'8': true,
|
||||
'9': true,
|
||||
'A': true,
|
||||
'B': true,
|
||||
'C': true,
|
||||
'D': true,
|
||||
'E': true,
|
||||
'F': true,
|
||||
'G': true,
|
||||
'H': true,
|
||||
'I': true,
|
||||
'J': true,
|
||||
'K': true,
|
||||
'L': true,
|
||||
'M': true,
|
||||
'N': true,
|
||||
'O': true,
|
||||
'P': true,
|
||||
'Q': true,
|
||||
'R': true,
|
||||
'S': true,
|
||||
'T': true,
|
||||
'U': true,
|
||||
'W': true,
|
||||
'V': true,
|
||||
'X': true,
|
||||
'Y': true,
|
||||
'Z': true,
|
||||
'^': true,
|
||||
'_': true,
|
||||
'`': true,
|
||||
'a': true,
|
||||
'b': true,
|
||||
'c': true,
|
||||
'd': true,
|
||||
'e': true,
|
||||
'f': true,
|
||||
'g': true,
|
||||
'h': true,
|
||||
'i': true,
|
||||
'j': true,
|
||||
'k': true,
|
||||
'l': true,
|
||||
'm': true,
|
||||
'n': true,
|
||||
'o': true,
|
||||
'p': true,
|
||||
'q': true,
|
||||
'r': true,
|
||||
's': true,
|
||||
't': true,
|
||||
'u': true,
|
||||
'v': true,
|
||||
'w': true,
|
||||
'x': true,
|
||||
'y': true,
|
||||
'z': true,
|
||||
'|': true,
|
||||
'~': true,
|
||||
}
|
||||
|
||||
func IsTokenRune(r rune) bool {
|
||||
return r < utf8.RuneSelf && isTokenTable[byte(r)]
|
||||
}
|
||||
|
||||
// HeaderValuesContainsToken reports whether any string in values
|
||||
// contains the provided token, ASCII case-insensitively.
|
||||
func HeaderValuesContainsToken(values []string, token string) bool {
|
||||
for _, v := range values {
|
||||
if headerValueContainsToken(v, token) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isOWS reports whether b is an optional whitespace byte, as defined
|
||||
// by RFC 7230 section 3.2.3.
|
||||
func isOWS(b byte) bool { return b == ' ' || b == '\t' }
|
||||
|
||||
// trimOWS returns x with all optional whitespace removes from the
|
||||
// beginning and end.
|
||||
func trimOWS(x string) string {
|
||||
// TODO: consider using strings.Trim(x, " \t") instead,
|
||||
// if and when it's fast enough. See issue 10292.
|
||||
// But this ASCII-only code will probably always beat UTF-8
|
||||
// aware code.
|
||||
for len(x) > 0 && isOWS(x[0]) {
|
||||
x = x[1:]
|
||||
}
|
||||
for len(x) > 0 && isOWS(x[len(x)-1]) {
|
||||
x = x[:len(x)-1]
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
// headerValueContainsToken reports whether v (assumed to be a
|
||||
// 0#element, in the ABNF extension described in RFC 7230 section 7)
|
||||
// contains token amongst its comma-separated tokens, ASCII
|
||||
// case-insensitively.
|
||||
func headerValueContainsToken(v string, token string) bool {
|
||||
for comma := strings.IndexByte(v, ','); comma != -1; comma = strings.IndexByte(v, ',') {
|
||||
if tokenEqual(trimOWS(v[:comma]), token) {
|
||||
return true
|
||||
}
|
||||
v = v[comma+1:]
|
||||
}
|
||||
return tokenEqual(trimOWS(v), token)
|
||||
}
|
||||
|
||||
// lowerASCII returns the ASCII lowercase version of b.
|
||||
func lowerASCII(b byte) byte {
|
||||
if 'A' <= b && b <= 'Z' {
|
||||
return b + ('a' - 'A')
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// tokenEqual reports whether t1 and t2 are equal, ASCII case-insensitively.
|
||||
func tokenEqual(t1, t2 string) bool {
|
||||
if len(t1) != len(t2) {
|
||||
return false
|
||||
}
|
||||
for i, b := range t1 {
|
||||
if b >= utf8.RuneSelf {
|
||||
// No UTF-8 or non-ASCII allowed in tokens.
|
||||
return false
|
||||
}
|
||||
if lowerASCII(byte(b)) != lowerASCII(t2[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// isLWS reports whether b is linear white space, according
|
||||
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
|
||||
//
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
func isLWS(b byte) bool { return b == ' ' || b == '\t' }
|
||||
|
||||
// isCTL reports whether b is a control byte, according
|
||||
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
|
||||
//
|
||||
// CTL = <any US-ASCII control character
|
||||
// (octets 0 - 31) and DEL (127)>
|
||||
func isCTL(b byte) bool {
|
||||
const del = 0x7f // a CTL
|
||||
return b < ' ' || b == del
|
||||
}
|
||||
|
||||
// ValidHeaderFieldName reports whether v is a valid HTTP/1.x header name.
|
||||
// HTTP/2 imposes the additional restriction that uppercase ASCII
|
||||
// letters are not allowed.
|
||||
//
|
||||
// RFC 7230 says:
|
||||
//
|
||||
// header-field = field-name ":" OWS field-value OWS
|
||||
// field-name = token
|
||||
// token = 1*tchar
|
||||
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
|
||||
// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
|
||||
func ValidHeaderFieldName(v string) bool {
|
||||
if len(v) == 0 {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(v); i++ {
|
||||
if !isTokenTable[v[i]] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ValidHostHeader reports whether h is a valid host header.
|
||||
func ValidHostHeader(h string) bool {
|
||||
// The latest spec is actually this:
|
||||
//
|
||||
// http://tools.ietf.org/html/rfc7230#section-5.4
|
||||
// Host = uri-host [ ":" port ]
|
||||
//
|
||||
// Where uri-host is:
|
||||
// http://tools.ietf.org/html/rfc3986#section-3.2.2
|
||||
//
|
||||
// But we're going to be much more lenient for now and just
|
||||
// search for any byte that's not a valid byte in any of those
|
||||
// expressions.
|
||||
for i := 0; i < len(h); i++ {
|
||||
if !validHostByte[h[i]] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// See the validHostHeader comment.
|
||||
var validHostByte = [256]bool{
|
||||
'0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true, '7': true,
|
||||
'8': true, '9': true,
|
||||
|
||||
'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true, 'h': true,
|
||||
'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, 'p': true,
|
||||
'q': true, 'r': true, 's': true, 't': true, 'u': true, 'v': true, 'w': true, 'x': true,
|
||||
'y': true, 'z': true,
|
||||
|
||||
'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true, 'H': true,
|
||||
'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, 'P': true,
|
||||
'Q': true, 'R': true, 'S': true, 'T': true, 'U': true, 'V': true, 'W': true, 'X': true,
|
||||
'Y': true, 'Z': true,
|
||||
|
||||
'!': true, // sub-delims
|
||||
'$': true, // sub-delims
|
||||
'%': true, // pct-encoded (and used in IPv6 zones)
|
||||
'&': true, // sub-delims
|
||||
'(': true, // sub-delims
|
||||
')': true, // sub-delims
|
||||
'*': true, // sub-delims
|
||||
'+': true, // sub-delims
|
||||
',': true, // sub-delims
|
||||
'-': true, // unreserved
|
||||
'.': true, // unreserved
|
||||
':': true, // IPv6address + Host expression's optional port
|
||||
';': true, // sub-delims
|
||||
'=': true, // sub-delims
|
||||
'[': true,
|
||||
'\'': true, // sub-delims
|
||||
']': true,
|
||||
'_': true, // unreserved
|
||||
'~': true, // unreserved
|
||||
}
|
||||
|
||||
// ValidHeaderFieldValue reports whether v is a valid "field-value" according to
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
|
||||
//
|
||||
// message-header = field-name ":" [ field-value ]
|
||||
// field-value = *( field-content | LWS )
|
||||
// field-content = <the OCTETs making up the field-value
|
||||
// and consisting of either *TEXT or combinations
|
||||
// of token, separators, and quoted-string>
|
||||
//
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
|
||||
//
|
||||
// TEXT = <any OCTET except CTLs,
|
||||
// but including LWS>
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
// CTL = <any US-ASCII control character
|
||||
// (octets 0 - 31) and DEL (127)>
|
||||
//
|
||||
// RFC 7230 says:
|
||||
//
|
||||
// field-value = *( field-content / obs-fold )
|
||||
// obj-fold = N/A to http2, and deprecated
|
||||
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
||||
// field-vchar = VCHAR / obs-text
|
||||
// obs-text = %x80-FF
|
||||
// VCHAR = "any visible [USASCII] character"
|
||||
//
|
||||
// http2 further says: "Similarly, HTTP/2 allows header field values
|
||||
// that are not valid. While most of the values that can be encoded
|
||||
// will not alter header field parsing, carriage return (CR, ASCII
|
||||
// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII
|
||||
// 0x0) might be exploited by an attacker if they are translated
|
||||
// verbatim. Any request or response that contains a character not
|
||||
// permitted in a header field value MUST be treated as malformed
|
||||
// (Section 8.1.2.6). Valid characters are defined by the
|
||||
// field-content ABNF rule in Section 3.2 of [RFC7230]."
|
||||
//
|
||||
// This function does not (yet?) properly handle the rejection of
|
||||
// strings that begin or end with SP or HTAB.
|
||||
func ValidHeaderFieldValue(v string) bool {
|
||||
for i := 0; i < len(v); i++ {
|
||||
b := v[i]
|
||||
if isCTL(b) && !isLWS(b) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isASCII(s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] >= utf8.RuneSelf {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// PunycodeHostPort returns the IDNA Punycode version
|
||||
// of the provided "host" or "host:port" string.
|
||||
func PunycodeHostPort(v string) (string, error) {
|
||||
if isASCII(v) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(v)
|
||||
if err != nil {
|
||||
// The input 'v' argument was just a "host" argument,
|
||||
// without a port. This error should not be returned
|
||||
// to the caller.
|
||||
host = v
|
||||
port = ""
|
||||
}
|
||||
host, err = idna.ToASCII(host)
|
||||
if err != nil {
|
||||
// Non-UTF-8? Not representable in Punycode, in any
|
||||
// case.
|
||||
return "", err
|
||||
}
|
||||
if port == "" {
|
||||
return host, nil
|
||||
}
|
||||
return net.JoinHostPort(host, port), nil
|
||||
}
|
||||
245
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
Normal file
245
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package hpack
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
uint32Max = ^uint32(0)
|
||||
initialHeaderTableSize = 4096
|
||||
)
|
||||
|
||||
type Encoder struct {
|
||||
dynTab dynamicTable
|
||||
// minSize is the minimum table size set by
|
||||
// SetMaxDynamicTableSize after the previous Header Table Size
|
||||
// Update.
|
||||
minSize uint32
|
||||
// maxSizeLimit is the maximum table size this encoder
|
||||
// supports. This will protect the encoder from too large
|
||||
// size.
|
||||
maxSizeLimit uint32
|
||||
// tableSizeUpdate indicates whether "Header Table Size
|
||||
// Update" is required.
|
||||
tableSizeUpdate bool
|
||||
w io.Writer
|
||||
buf []byte
|
||||
}
|
||||
|
||||
// NewEncoder returns a new Encoder which performs HPACK encoding. An
|
||||
// encoded data is written to w.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
e := &Encoder{
|
||||
minSize: uint32Max,
|
||||
maxSizeLimit: initialHeaderTableSize,
|
||||
tableSizeUpdate: false,
|
||||
w: w,
|
||||
}
|
||||
e.dynTab.table.init()
|
||||
e.dynTab.setMaxSize(initialHeaderTableSize)
|
||||
return e
|
||||
}
|
||||
|
||||
// WriteField encodes f into a single Write to e's underlying Writer.
|
||||
// This function may also produce bytes for "Header Table Size Update"
|
||||
// if necessary. If produced, it is done before encoding f.
|
||||
func (e *Encoder) WriteField(f HeaderField) error {
|
||||
e.buf = e.buf[:0]
|
||||
|
||||
if e.tableSizeUpdate {
|
||||
e.tableSizeUpdate = false
|
||||
if e.minSize < e.dynTab.maxSize {
|
||||
e.buf = appendTableSize(e.buf, e.minSize)
|
||||
}
|
||||
e.minSize = uint32Max
|
||||
e.buf = appendTableSize(e.buf, e.dynTab.maxSize)
|
||||
}
|
||||
|
||||
idx, nameValueMatch := e.searchTable(f)
|
||||
if nameValueMatch {
|
||||
e.buf = appendIndexed(e.buf, idx)
|
||||
} else {
|
||||
indexing := e.shouldIndex(f)
|
||||
if indexing {
|
||||
e.dynTab.add(f)
|
||||
}
|
||||
|
||||
if idx == 0 {
|
||||
e.buf = appendNewName(e.buf, f, indexing)
|
||||
} else {
|
||||
e.buf = appendIndexedName(e.buf, f, idx, indexing)
|
||||
}
|
||||
}
|
||||
n, err := e.w.Write(e.buf)
|
||||
if err == nil && n != len(e.buf) {
|
||||
err = io.ErrShortWrite
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// searchTable searches f in both stable and dynamic header tables.
|
||||
// The static header table is searched first. Only when there is no
|
||||
// exact match for both name and value, the dynamic header table is
|
||||
// then searched. If there is no match, i is 0. If both name and value
|
||||
// match, i is the matched index and nameValueMatch becomes true. If
|
||||
// only name matches, i points to that index and nameValueMatch
|
||||
// becomes false.
|
||||
func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) {
|
||||
i, nameValueMatch = staticTable.search(f)
|
||||
if nameValueMatch {
|
||||
return i, true
|
||||
}
|
||||
|
||||
j, nameValueMatch := e.dynTab.table.search(f)
|
||||
if nameValueMatch || (i == 0 && j != 0) {
|
||||
return j + uint64(staticTable.len()), nameValueMatch
|
||||
}
|
||||
|
||||
return i, false
|
||||
}
|
||||
|
||||
// SetMaxDynamicTableSize changes the dynamic header table size to v.
|
||||
// The actual size is bounded by the value passed to
|
||||
// SetMaxDynamicTableSizeLimit.
|
||||
func (e *Encoder) SetMaxDynamicTableSize(v uint32) {
|
||||
if v > e.maxSizeLimit {
|
||||
v = e.maxSizeLimit
|
||||
}
|
||||
if v < e.minSize {
|
||||
e.minSize = v
|
||||
}
|
||||
e.tableSizeUpdate = true
|
||||
e.dynTab.setMaxSize(v)
|
||||
}
|
||||
|
||||
// MaxDynamicTableSize returns the current dynamic header table size.
|
||||
func (e *Encoder) MaxDynamicTableSize() (v uint32) {
|
||||
return e.dynTab.maxSize
|
||||
}
|
||||
|
||||
// SetMaxDynamicTableSizeLimit changes the maximum value that can be
|
||||
// specified in SetMaxDynamicTableSize to v. By default, it is set to
|
||||
// 4096, which is the same size of the default dynamic header table
|
||||
// size described in HPACK specification. If the current maximum
|
||||
// dynamic header table size is strictly greater than v, "Header Table
|
||||
// Size Update" will be done in the next WriteField call and the
|
||||
// maximum dynamic header table size is truncated to v.
|
||||
func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) {
|
||||
e.maxSizeLimit = v
|
||||
if e.dynTab.maxSize > v {
|
||||
e.tableSizeUpdate = true
|
||||
e.dynTab.setMaxSize(v)
|
||||
}
|
||||
}
|
||||
|
||||
// shouldIndex reports whether f should be indexed.
|
||||
func (e *Encoder) shouldIndex(f HeaderField) bool {
|
||||
return !f.Sensitive && f.Size() <= e.dynTab.maxSize
|
||||
}
|
||||
|
||||
// appendIndexed appends index i, as encoded in "Indexed Header Field"
|
||||
// representation, to dst and returns the extended buffer.
|
||||
func appendIndexed(dst []byte, i uint64) []byte {
|
||||
first := len(dst)
|
||||
dst = appendVarInt(dst, 7, i)
|
||||
dst[first] |= 0x80
|
||||
return dst
|
||||
}
|
||||
|
||||
// appendNewName appends f, as encoded in one of "Literal Header field
|
||||
// - New Name" representation variants, to dst and returns the
|
||||
// extended buffer.
|
||||
//
|
||||
// If f.Sensitive is true, "Never Indexed" representation is used. If
|
||||
// f.Sensitive is false and indexing is true, "Incremental Indexing"
|
||||
// representation is used.
|
||||
func appendNewName(dst []byte, f HeaderField, indexing bool) []byte {
|
||||
dst = append(dst, encodeTypeByte(indexing, f.Sensitive))
|
||||
dst = appendHpackString(dst, f.Name)
|
||||
return appendHpackString(dst, f.Value)
|
||||
}
|
||||
|
||||
// appendIndexedName appends f and index i referring indexed name
|
||||
// entry, as encoded in one of "Literal Header field - Indexed Name"
|
||||
// representation variants, to dst and returns the extended buffer.
|
||||
//
|
||||
// If f.Sensitive is true, "Never Indexed" representation is used. If
|
||||
// f.Sensitive is false and indexing is true, "Incremental Indexing"
|
||||
// representation is used.
|
||||
func appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte {
|
||||
first := len(dst)
|
||||
var n byte
|
||||
if indexing {
|
||||
n = 6
|
||||
} else {
|
||||
n = 4
|
||||
}
|
||||
dst = appendVarInt(dst, n, i)
|
||||
dst[first] |= encodeTypeByte(indexing, f.Sensitive)
|
||||
return appendHpackString(dst, f.Value)
|
||||
}
|
||||
|
||||
// appendTableSize appends v, as encoded in "Header Table Size Update"
|
||||
// representation, to dst and returns the extended buffer.
|
||||
func appendTableSize(dst []byte, v uint32) []byte {
|
||||
first := len(dst)
|
||||
dst = appendVarInt(dst, 5, uint64(v))
|
||||
dst[first] |= 0x20
|
||||
return dst
|
||||
}
|
||||
|
||||
// appendVarInt appends i, as encoded in variable integer form using n
|
||||
// bit prefix, to dst and returns the extended buffer.
|
||||
//
|
||||
// See
|
||||
// https://httpwg.org/specs/rfc7541.html#integer.representation
|
||||
func appendVarInt(dst []byte, n byte, i uint64) []byte {
|
||||
k := uint64((1 << n) - 1)
|
||||
if i < k {
|
||||
return append(dst, byte(i))
|
||||
}
|
||||
dst = append(dst, byte(k))
|
||||
i -= k
|
||||
for ; i >= 128; i >>= 7 {
|
||||
dst = append(dst, byte(0x80|(i&0x7f)))
|
||||
}
|
||||
return append(dst, byte(i))
|
||||
}
|
||||
|
||||
// appendHpackString appends s, as encoded in "String Literal"
|
||||
// representation, to dst and returns the extended buffer.
|
||||
//
|
||||
// s will be encoded in Huffman codes only when it produces strictly
|
||||
// shorter byte string.
|
||||
func appendHpackString(dst []byte, s string) []byte {
|
||||
huffmanLength := HuffmanEncodeLength(s)
|
||||
if huffmanLength < uint64(len(s)) {
|
||||
first := len(dst)
|
||||
dst = appendVarInt(dst, 7, huffmanLength)
|
||||
dst = AppendHuffmanString(dst, s)
|
||||
dst[first] |= 0x80
|
||||
} else {
|
||||
dst = appendVarInt(dst, 7, uint64(len(s)))
|
||||
dst = append(dst, s...)
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// encodeTypeByte returns type byte. If sensitive is true, type byte
|
||||
// for "Never Indexed" representation is returned. If sensitive is
|
||||
// false and indexing is true, type byte for "Incremental Indexing"
|
||||
// representation is returned. Otherwise, type byte for "Without
|
||||
// Indexing" is returned.
|
||||
func encodeTypeByte(indexing, sensitive bool) byte {
|
||||
if sensitive {
|
||||
return 0x10
|
||||
}
|
||||
if indexing {
|
||||
return 0x40
|
||||
}
|
||||
return 0
|
||||
}
|
||||
523
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
Normal file
523
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
Normal file
@@ -0,0 +1,523 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package hpack implements HPACK, a compression format for
|
||||
// efficiently representing HTTP header fields in the context of HTTP/2.
|
||||
//
|
||||
// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09
|
||||
package hpack
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// A DecodingError is something the spec defines as a decoding error.
|
||||
type DecodingError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (de DecodingError) Error() string {
|
||||
return fmt.Sprintf("decoding error: %v", de.Err)
|
||||
}
|
||||
|
||||
// An InvalidIndexError is returned when an encoder references a table
|
||||
// entry before the static table or after the end of the dynamic table.
|
||||
type InvalidIndexError int
|
||||
|
||||
func (e InvalidIndexError) Error() string {
|
||||
return fmt.Sprintf("invalid indexed representation index %d", int(e))
|
||||
}
|
||||
|
||||
// A HeaderField is a name-value pair. Both the name and value are
|
||||
// treated as opaque sequences of octets.
|
||||
type HeaderField struct {
|
||||
Name, Value string
|
||||
|
||||
// Sensitive means that this header field should never be
|
||||
// indexed.
|
||||
Sensitive bool
|
||||
}
|
||||
|
||||
// IsPseudo reports whether the header field is an http2 pseudo header.
|
||||
// That is, it reports whether it starts with a colon.
|
||||
// It is not otherwise guaranteed to be a valid pseudo header field,
|
||||
// though.
|
||||
func (hf HeaderField) IsPseudo() bool {
|
||||
return len(hf.Name) != 0 && hf.Name[0] == ':'
|
||||
}
|
||||
|
||||
func (hf HeaderField) String() string {
|
||||
var suffix string
|
||||
if hf.Sensitive {
|
||||
suffix = " (sensitive)"
|
||||
}
|
||||
return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix)
|
||||
}
|
||||
|
||||
// Size returns the size of an entry per RFC 7541 section 4.1.
|
||||
func (hf HeaderField) Size() uint32 {
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.4.1
|
||||
// "The size of the dynamic table is the sum of the size of
|
||||
// its entries. The size of an entry is the sum of its name's
|
||||
// length in octets (as defined in Section 5.2), its value's
|
||||
// length in octets (see Section 5.2), plus 32. The size of
|
||||
// an entry is calculated using the length of the name and
|
||||
// value without any Huffman encoding applied."
|
||||
|
||||
// This can overflow if somebody makes a large HeaderField
|
||||
// Name and/or Value by hand, but we don't care, because that
|
||||
// won't happen on the wire because the encoding doesn't allow
|
||||
// it.
|
||||
return uint32(len(hf.Name) + len(hf.Value) + 32)
|
||||
}
|
||||
|
||||
// A Decoder is the decoding context for incremental processing of
|
||||
// header blocks.
|
||||
type Decoder struct {
|
||||
dynTab dynamicTable
|
||||
emit func(f HeaderField)
|
||||
|
||||
emitEnabled bool // whether calls to emit are enabled
|
||||
maxStrLen int // 0 means unlimited
|
||||
|
||||
// buf is the unparsed buffer. It's only written to
|
||||
// saveBuf if it was truncated in the middle of a header
|
||||
// block. Because it's usually not owned, we can only
|
||||
// process it under Write.
|
||||
buf []byte // not owned; only valid during Write
|
||||
|
||||
// saveBuf is previous data passed to Write which we weren't able
|
||||
// to fully parse before. Unlike buf, we own this data.
|
||||
saveBuf bytes.Buffer
|
||||
|
||||
firstField bool // processing the first field of the header block
|
||||
}
|
||||
|
||||
// NewDecoder returns a new decoder with the provided maximum dynamic
|
||||
// table size. The emitFunc will be called for each valid field
|
||||
// parsed, in the same goroutine as calls to Write, before Write returns.
|
||||
func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {
|
||||
d := &Decoder{
|
||||
emit: emitFunc,
|
||||
emitEnabled: true,
|
||||
firstField: true,
|
||||
}
|
||||
d.dynTab.table.init()
|
||||
d.dynTab.allowedMaxSize = maxDynamicTableSize
|
||||
d.dynTab.setMaxSize(maxDynamicTableSize)
|
||||
return d
|
||||
}
|
||||
|
||||
// ErrStringLength is returned by Decoder.Write when the max string length
|
||||
// (as configured by Decoder.SetMaxStringLength) would be violated.
|
||||
var ErrStringLength = errors.New("hpack: string too long")
|
||||
|
||||
// SetMaxStringLength sets the maximum size of a HeaderField name or
|
||||
// value string. If a string exceeds this length (even after any
|
||||
// decompression), Write will return ErrStringLength.
|
||||
// A value of 0 means unlimited and is the default from NewDecoder.
|
||||
func (d *Decoder) SetMaxStringLength(n int) {
|
||||
d.maxStrLen = n
|
||||
}
|
||||
|
||||
// SetEmitFunc changes the callback used when new header fields
|
||||
// are decoded.
|
||||
// It must be non-nil. It does not affect EmitEnabled.
|
||||
func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {
|
||||
d.emit = emitFunc
|
||||
}
|
||||
|
||||
// SetEmitEnabled controls whether the emitFunc provided to NewDecoder
|
||||
// should be called. The default is true.
|
||||
//
|
||||
// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE
|
||||
// while still decoding and keeping in-sync with decoder state, but
|
||||
// without doing unnecessary decompression or generating unnecessary
|
||||
// garbage for header fields past the limit.
|
||||
func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }
|
||||
|
||||
// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder
|
||||
// are currently enabled. The default is true.
|
||||
func (d *Decoder) EmitEnabled() bool { return d.emitEnabled }
|
||||
|
||||
// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their
|
||||
// underlying buffers for garbage reasons.
|
||||
|
||||
func (d *Decoder) SetMaxDynamicTableSize(v uint32) {
|
||||
d.dynTab.setMaxSize(v)
|
||||
}
|
||||
|
||||
// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded
|
||||
// stream (via dynamic table size updates) may set the maximum size
|
||||
// to.
|
||||
func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
|
||||
d.dynTab.allowedMaxSize = v
|
||||
}
|
||||
|
||||
type dynamicTable struct {
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2
|
||||
table headerFieldTable
|
||||
size uint32 // in bytes
|
||||
maxSize uint32 // current maxSize
|
||||
allowedMaxSize uint32 // maxSize may go up to this, inclusive
|
||||
}
|
||||
|
||||
func (dt *dynamicTable) setMaxSize(v uint32) {
|
||||
dt.maxSize = v
|
||||
dt.evict()
|
||||
}
|
||||
|
||||
func (dt *dynamicTable) add(f HeaderField) {
|
||||
dt.table.addEntry(f)
|
||||
dt.size += f.Size()
|
||||
dt.evict()
|
||||
}
|
||||
|
||||
// If we're too big, evict old stuff.
|
||||
func (dt *dynamicTable) evict() {
|
||||
var n int
|
||||
for dt.size > dt.maxSize && n < dt.table.len() {
|
||||
dt.size -= dt.table.ents[n].Size()
|
||||
n++
|
||||
}
|
||||
dt.table.evictOldest(n)
|
||||
}
|
||||
|
||||
func (d *Decoder) maxTableIndex() int {
|
||||
// This should never overflow. RFC 7540 Section 6.5.2 limits the size of
|
||||
// the dynamic table to 2^32 bytes, where each entry will occupy more than
|
||||
// one byte. Further, the staticTable has a fixed, small length.
|
||||
return d.dynTab.table.len() + staticTable.len()
|
||||
}
|
||||
|
||||
func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {
|
||||
// See Section 2.3.3.
|
||||
if i == 0 {
|
||||
return
|
||||
}
|
||||
if i <= uint64(staticTable.len()) {
|
||||
return staticTable.ents[i-1], true
|
||||
}
|
||||
if i > uint64(d.maxTableIndex()) {
|
||||
return
|
||||
}
|
||||
// In the dynamic table, newer entries have lower indices.
|
||||
// However, dt.ents[0] is the oldest entry. Hence, dt.ents is
|
||||
// the reversed dynamic table.
|
||||
dt := d.dynTab.table
|
||||
return dt.ents[dt.len()-(int(i)-staticTable.len())], true
|
||||
}
|
||||
|
||||
// DecodeFull decodes an entire block.
|
||||
//
|
||||
// TODO: remove this method and make it incremental later? This is
|
||||
// easier for debugging now.
|
||||
func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
|
||||
var hf []HeaderField
|
||||
saveFunc := d.emit
|
||||
defer func() { d.emit = saveFunc }()
|
||||
d.emit = func(f HeaderField) { hf = append(hf, f) }
|
||||
if _, err := d.Write(p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := d.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hf, nil
|
||||
}
|
||||
|
||||
// Close declares that the decoding is complete and resets the Decoder
|
||||
// to be reused again for a new header block. If there is any remaining
|
||||
// data in the decoder's buffer, Close returns an error.
|
||||
func (d *Decoder) Close() error {
|
||||
if d.saveBuf.Len() > 0 {
|
||||
d.saveBuf.Reset()
|
||||
return DecodingError{errors.New("truncated headers")}
|
||||
}
|
||||
d.firstField = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Decoder) Write(p []byte) (n int, err error) {
|
||||
if len(p) == 0 {
|
||||
// Prevent state machine CPU attacks (making us redo
|
||||
// work up to the point of finding out we don't have
|
||||
// enough data)
|
||||
return
|
||||
}
|
||||
// Only copy the data if we have to. Optimistically assume
|
||||
// that p will contain a complete header block.
|
||||
if d.saveBuf.Len() == 0 {
|
||||
d.buf = p
|
||||
} else {
|
||||
d.saveBuf.Write(p)
|
||||
d.buf = d.saveBuf.Bytes()
|
||||
d.saveBuf.Reset()
|
||||
}
|
||||
|
||||
for len(d.buf) > 0 {
|
||||
err = d.parseHeaderFieldRepr()
|
||||
if err == errNeedMore {
|
||||
// Extra paranoia, making sure saveBuf won't
|
||||
// get too large. All the varint and string
|
||||
// reading code earlier should already catch
|
||||
// overlong things and return ErrStringLength,
|
||||
// but keep this as a last resort.
|
||||
const varIntOverhead = 8 // conservative
|
||||
if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {
|
||||
return 0, ErrStringLength
|
||||
}
|
||||
d.saveBuf.Write(d.buf)
|
||||
return len(p), nil
|
||||
}
|
||||
d.firstField = false
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return len(p), err
|
||||
}
|
||||
|
||||
// errNeedMore is an internal sentinel error value that means the
|
||||
// buffer is truncated and we need to read more data before we can
|
||||
// continue parsing.
|
||||
var errNeedMore = errors.New("need more data")
|
||||
|
||||
type indexType int
|
||||
|
||||
const (
|
||||
indexedTrue indexType = iota
|
||||
indexedFalse
|
||||
indexedNever
|
||||
)
|
||||
|
||||
func (v indexType) indexed() bool { return v == indexedTrue }
|
||||
func (v indexType) sensitive() bool { return v == indexedNever }
|
||||
|
||||
// returns errNeedMore if there isn't enough data available.
|
||||
// any other error is fatal.
|
||||
// consumes d.buf iff it returns nil.
|
||||
// precondition: must be called with len(d.buf) > 0
|
||||
func (d *Decoder) parseHeaderFieldRepr() error {
|
||||
b := d.buf[0]
|
||||
switch {
|
||||
case b&128 != 0:
|
||||
// Indexed representation.
|
||||
// High bit set?
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.1
|
||||
return d.parseFieldIndexed()
|
||||
case b&192 == 64:
|
||||
// 6.2.1 Literal Header Field with Incremental Indexing
|
||||
// 0b10xxxxxx: top two bits are 10
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1
|
||||
return d.parseFieldLiteral(6, indexedTrue)
|
||||
case b&240 == 0:
|
||||
// 6.2.2 Literal Header Field without Indexing
|
||||
// 0b0000xxxx: top four bits are 0000
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2
|
||||
return d.parseFieldLiteral(4, indexedFalse)
|
||||
case b&240 == 16:
|
||||
// 6.2.3 Literal Header Field never Indexed
|
||||
// 0b0001xxxx: top four bits are 0001
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3
|
||||
return d.parseFieldLiteral(4, indexedNever)
|
||||
case b&224 == 32:
|
||||
// 6.3 Dynamic Table Size Update
|
||||
// Top three bits are '001'.
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.3
|
||||
return d.parseDynamicTableSizeUpdate()
|
||||
}
|
||||
|
||||
return DecodingError{errors.New("invalid encoding")}
|
||||
}
|
||||
|
||||
// (same invariants and behavior as parseHeaderFieldRepr)
|
||||
func (d *Decoder) parseFieldIndexed() error {
|
||||
buf := d.buf
|
||||
idx, buf, err := readVarInt(7, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hf, ok := d.at(idx)
|
||||
if !ok {
|
||||
return DecodingError{InvalidIndexError(idx)}
|
||||
}
|
||||
d.buf = buf
|
||||
return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})
|
||||
}
|
||||
|
||||
// (same invariants and behavior as parseHeaderFieldRepr)
|
||||
func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
|
||||
buf := d.buf
|
||||
nameIdx, buf, err := readVarInt(n, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var hf HeaderField
|
||||
wantStr := d.emitEnabled || it.indexed()
|
||||
var undecodedName undecodedString
|
||||
if nameIdx > 0 {
|
||||
ihf, ok := d.at(nameIdx)
|
||||
if !ok {
|
||||
return DecodingError{InvalidIndexError(nameIdx)}
|
||||
}
|
||||
hf.Name = ihf.Name
|
||||
} else {
|
||||
undecodedName, buf, err = d.readString(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
undecodedValue, buf, err := d.readString(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if wantStr {
|
||||
if nameIdx <= 0 {
|
||||
hf.Name, err = d.decodeString(undecodedName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
hf.Value, err = d.decodeString(undecodedValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
d.buf = buf
|
||||
if it.indexed() {
|
||||
d.dynTab.add(hf)
|
||||
}
|
||||
hf.Sensitive = it.sensitive()
|
||||
return d.callEmit(hf)
|
||||
}
|
||||
|
||||
func (d *Decoder) callEmit(hf HeaderField) error {
|
||||
if d.maxStrLen != 0 {
|
||||
if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {
|
||||
return ErrStringLength
|
||||
}
|
||||
}
|
||||
if d.emitEnabled {
|
||||
d.emit(hf)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// (same invariants and behavior as parseHeaderFieldRepr)
|
||||
func (d *Decoder) parseDynamicTableSizeUpdate() error {
|
||||
// RFC 7541, sec 4.2: This dynamic table size update MUST occur at the
|
||||
// beginning of the first header block following the change to the dynamic table size.
|
||||
if !d.firstField && d.dynTab.size > 0 {
|
||||
return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")}
|
||||
}
|
||||
|
||||
buf := d.buf
|
||||
size, buf, err := readVarInt(5, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if size > uint64(d.dynTab.allowedMaxSize) {
|
||||
return DecodingError{errors.New("dynamic table size update too large")}
|
||||
}
|
||||
d.dynTab.setMaxSize(uint32(size))
|
||||
d.buf = buf
|
||||
return nil
|
||||
}
|
||||
|
||||
var errVarintOverflow = DecodingError{errors.New("varint integer overflow")}
|
||||
|
||||
// readVarInt reads an unsigned variable length integer off the
|
||||
// beginning of p. n is the parameter as described in
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1.
|
||||
//
|
||||
// n must always be between 1 and 8.
|
||||
//
|
||||
// The returned remain buffer is either a smaller suffix of p, or err != nil.
|
||||
// The error is errNeedMore if p doesn't contain a complete integer.
|
||||
func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
|
||||
if n < 1 || n > 8 {
|
||||
panic("bad n")
|
||||
}
|
||||
if len(p) == 0 {
|
||||
return 0, p, errNeedMore
|
||||
}
|
||||
i = uint64(p[0])
|
||||
if n < 8 {
|
||||
i &= (1 << uint64(n)) - 1
|
||||
}
|
||||
if i < (1<<uint64(n))-1 {
|
||||
return i, p[1:], nil
|
||||
}
|
||||
|
||||
origP := p
|
||||
p = p[1:]
|
||||
var m uint64
|
||||
for len(p) > 0 {
|
||||
b := p[0]
|
||||
p = p[1:]
|
||||
i += uint64(b&127) << m
|
||||
if b&128 == 0 {
|
||||
return i, p, nil
|
||||
}
|
||||
m += 7
|
||||
if m >= 63 { // TODO: proper overflow check. making this up.
|
||||
return 0, origP, errVarintOverflow
|
||||
}
|
||||
}
|
||||
return 0, origP, errNeedMore
|
||||
}
|
||||
|
||||
// readString reads an hpack string from p.
|
||||
//
|
||||
// It returns a reference to the encoded string data to permit deferring decode costs
|
||||
// until after the caller verifies all data is present.
|
||||
func (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) {
|
||||
if len(p) == 0 {
|
||||
return u, p, errNeedMore
|
||||
}
|
||||
isHuff := p[0]&128 != 0
|
||||
strLen, p, err := readVarInt(7, p)
|
||||
if err != nil {
|
||||
return u, p, err
|
||||
}
|
||||
if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
|
||||
// Returning an error here means Huffman decoding errors
|
||||
// for non-indexed strings past the maximum string length
|
||||
// are ignored, but the server is returning an error anyway
|
||||
// and because the string is not indexed the error will not
|
||||
// affect the decoding state.
|
||||
return u, nil, ErrStringLength
|
||||
}
|
||||
if uint64(len(p)) < strLen {
|
||||
return u, p, errNeedMore
|
||||
}
|
||||
u.isHuff = isHuff
|
||||
u.b = p[:strLen]
|
||||
return u, p[strLen:], nil
|
||||
}
|
||||
|
||||
type undecodedString struct {
|
||||
isHuff bool
|
||||
b []byte
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeString(u undecodedString) (string, error) {
|
||||
if !u.isHuff {
|
||||
return string(u.b), nil
|
||||
}
|
||||
buf := bufPool.Get().(*bytes.Buffer)
|
||||
buf.Reset() // don't trust others
|
||||
var s string
|
||||
err := huffmanDecode(buf, d.maxStrLen, u.b)
|
||||
if err == nil {
|
||||
s = buf.String()
|
||||
}
|
||||
buf.Reset() // be nice to GC
|
||||
bufPool.Put(buf)
|
||||
return s, err
|
||||
}
|
||||
226
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
Normal file
226
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package hpack
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var bufPool = sync.Pool{
|
||||
New: func() interface{} { return new(bytes.Buffer) },
|
||||
}
|
||||
|
||||
// HuffmanDecode decodes the string in v and writes the expanded
|
||||
// result to w, returning the number of bytes written to w and the
|
||||
// Write call's return value. At most one Write call is made.
|
||||
func HuffmanDecode(w io.Writer, v []byte) (int, error) {
|
||||
buf := bufPool.Get().(*bytes.Buffer)
|
||||
buf.Reset()
|
||||
defer bufPool.Put(buf)
|
||||
if err := huffmanDecode(buf, 0, v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return w.Write(buf.Bytes())
|
||||
}
|
||||
|
||||
// HuffmanDecodeToString decodes the string in v.
|
||||
func HuffmanDecodeToString(v []byte) (string, error) {
|
||||
buf := bufPool.Get().(*bytes.Buffer)
|
||||
buf.Reset()
|
||||
defer bufPool.Put(buf)
|
||||
if err := huffmanDecode(buf, 0, v); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// ErrInvalidHuffman is returned for errors found decoding
|
||||
// Huffman-encoded strings.
|
||||
var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data")
|
||||
|
||||
// huffmanDecode decodes v to buf.
|
||||
// If maxLen is greater than 0, attempts to write more to buf than
|
||||
// maxLen bytes will return ErrStringLength.
|
||||
func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {
|
||||
rootHuffmanNode := getRootHuffmanNode()
|
||||
n := rootHuffmanNode
|
||||
// cur is the bit buffer that has not been fed into n.
|
||||
// cbits is the number of low order bits in cur that are valid.
|
||||
// sbits is the number of bits of the symbol prefix being decoded.
|
||||
cur, cbits, sbits := uint(0), uint8(0), uint8(0)
|
||||
for _, b := range v {
|
||||
cur = cur<<8 | uint(b)
|
||||
cbits += 8
|
||||
sbits += 8
|
||||
for cbits >= 8 {
|
||||
idx := byte(cur >> (cbits - 8))
|
||||
n = n.children[idx]
|
||||
if n == nil {
|
||||
return ErrInvalidHuffman
|
||||
}
|
||||
if n.children == nil {
|
||||
if maxLen != 0 && buf.Len() == maxLen {
|
||||
return ErrStringLength
|
||||
}
|
||||
buf.WriteByte(n.sym)
|
||||
cbits -= n.codeLen
|
||||
n = rootHuffmanNode
|
||||
sbits = cbits
|
||||
} else {
|
||||
cbits -= 8
|
||||
}
|
||||
}
|
||||
}
|
||||
for cbits > 0 {
|
||||
n = n.children[byte(cur<<(8-cbits))]
|
||||
if n == nil {
|
||||
return ErrInvalidHuffman
|
||||
}
|
||||
if n.children != nil || n.codeLen > cbits {
|
||||
break
|
||||
}
|
||||
if maxLen != 0 && buf.Len() == maxLen {
|
||||
return ErrStringLength
|
||||
}
|
||||
buf.WriteByte(n.sym)
|
||||
cbits -= n.codeLen
|
||||
n = rootHuffmanNode
|
||||
sbits = cbits
|
||||
}
|
||||
if sbits > 7 {
|
||||
// Either there was an incomplete symbol, or overlong padding.
|
||||
// Both are decoding errors per RFC 7541 section 5.2.
|
||||
return ErrInvalidHuffman
|
||||
}
|
||||
if mask := uint(1<<cbits - 1); cur&mask != mask {
|
||||
// Trailing bits must be a prefix of EOS per RFC 7541 section 5.2.
|
||||
return ErrInvalidHuffman
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// incomparable is a zero-width, non-comparable type. Adding it to a struct
|
||||
// makes that struct also non-comparable, and generally doesn't add
|
||||
// any size (as long as it's first).
|
||||
type incomparable [0]func()
|
||||
|
||||
type node struct {
|
||||
_ incomparable
|
||||
|
||||
// children is non-nil for internal nodes
|
||||
children *[256]*node
|
||||
|
||||
// The following are only valid if children is nil:
|
||||
codeLen uint8 // number of bits that led to the output of sym
|
||||
sym byte // output symbol
|
||||
}
|
||||
|
||||
func newInternalNode() *node {
|
||||
return &node{children: new([256]*node)}
|
||||
}
|
||||
|
||||
var (
|
||||
buildRootOnce sync.Once
|
||||
lazyRootHuffmanNode *node
|
||||
)
|
||||
|
||||
func getRootHuffmanNode() *node {
|
||||
buildRootOnce.Do(buildRootHuffmanNode)
|
||||
return lazyRootHuffmanNode
|
||||
}
|
||||
|
||||
func buildRootHuffmanNode() {
|
||||
if len(huffmanCodes) != 256 {
|
||||
panic("unexpected size")
|
||||
}
|
||||
lazyRootHuffmanNode = newInternalNode()
|
||||
// allocate a leaf node for each of the 256 symbols
|
||||
leaves := new([256]node)
|
||||
|
||||
for sym, code := range huffmanCodes {
|
||||
codeLen := huffmanCodeLen[sym]
|
||||
|
||||
cur := lazyRootHuffmanNode
|
||||
for codeLen > 8 {
|
||||
codeLen -= 8
|
||||
i := uint8(code >> codeLen)
|
||||
if cur.children[i] == nil {
|
||||
cur.children[i] = newInternalNode()
|
||||
}
|
||||
cur = cur.children[i]
|
||||
}
|
||||
shift := 8 - codeLen
|
||||
start, end := int(uint8(code<<shift)), int(1<<shift)
|
||||
|
||||
leaves[sym].sym = byte(sym)
|
||||
leaves[sym].codeLen = codeLen
|
||||
for i := start; i < start+end; i++ {
|
||||
cur.children[i] = &leaves[sym]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AppendHuffmanString appends s, as encoded in Huffman codes, to dst
|
||||
// and returns the extended buffer.
|
||||
func AppendHuffmanString(dst []byte, s string) []byte {
|
||||
// This relies on the maximum huffman code length being 30 (See tables.go huffmanCodeLen array)
|
||||
// So if a uint64 buffer has less than 32 valid bits can always accommodate another huffmanCode.
|
||||
var (
|
||||
x uint64 // buffer
|
||||
n uint // number valid of bits present in x
|
||||
)
|
||||
for i := 0; i < len(s); i++ {
|
||||
c := s[i]
|
||||
n += uint(huffmanCodeLen[c])
|
||||
x <<= huffmanCodeLen[c] % 64
|
||||
x |= uint64(huffmanCodes[c])
|
||||
if n >= 32 {
|
||||
n %= 32 // Normally would be -= 32 but %= 32 informs compiler 0 <= n <= 31 for upcoming shift
|
||||
y := uint32(x >> n) // Compiler doesn't combine memory writes if y isn't uint32
|
||||
dst = append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
|
||||
}
|
||||
}
|
||||
// Add padding bits if necessary
|
||||
if over := n % 8; over > 0 {
|
||||
const (
|
||||
eosCode = 0x3fffffff
|
||||
eosNBits = 30
|
||||
eosPadByte = eosCode >> (eosNBits - 8)
|
||||
)
|
||||
pad := 8 - over
|
||||
x = (x << pad) | (eosPadByte >> over)
|
||||
n += pad // 8 now divides into n exactly
|
||||
}
|
||||
// n in (0, 8, 16, 24, 32)
|
||||
switch n / 8 {
|
||||
case 0:
|
||||
return dst
|
||||
case 1:
|
||||
return append(dst, byte(x))
|
||||
case 2:
|
||||
y := uint16(x)
|
||||
return append(dst, byte(y>>8), byte(y))
|
||||
case 3:
|
||||
y := uint16(x >> 8)
|
||||
return append(dst, byte(y>>8), byte(y), byte(x))
|
||||
}
|
||||
// case 4:
|
||||
y := uint32(x)
|
||||
return append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
|
||||
}
|
||||
|
||||
// HuffmanEncodeLength returns the number of bytes required to encode
|
||||
// s in Huffman codes. The result is round up to byte boundary.
|
||||
func HuffmanEncodeLength(s string) uint64 {
|
||||
n := uint64(0)
|
||||
for i := 0; i < len(s); i++ {
|
||||
n += uint64(huffmanCodeLen[s[i]])
|
||||
}
|
||||
return (n + 7) / 8
|
||||
}
|
||||
188
vendor/golang.org/x/net/http2/hpack/static_table.go
generated
vendored
Normal file
188
vendor/golang.org/x/net/http2/hpack/static_table.go
generated
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
// go generate gen.go
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
package hpack
|
||||
|
||||
var staticTable = &headerFieldTable{
|
||||
evictCount: 0,
|
||||
byName: map[string]uint64{
|
||||
":authority": 1,
|
||||
":method": 3,
|
||||
":path": 5,
|
||||
":scheme": 7,
|
||||
":status": 14,
|
||||
"accept-charset": 15,
|
||||
"accept-encoding": 16,
|
||||
"accept-language": 17,
|
||||
"accept-ranges": 18,
|
||||
"accept": 19,
|
||||
"access-control-allow-origin": 20,
|
||||
"age": 21,
|
||||
"allow": 22,
|
||||
"authorization": 23,
|
||||
"cache-control": 24,
|
||||
"content-disposition": 25,
|
||||
"content-encoding": 26,
|
||||
"content-language": 27,
|
||||
"content-length": 28,
|
||||
"content-location": 29,
|
||||
"content-range": 30,
|
||||
"content-type": 31,
|
||||
"cookie": 32,
|
||||
"date": 33,
|
||||
"etag": 34,
|
||||
"expect": 35,
|
||||
"expires": 36,
|
||||
"from": 37,
|
||||
"host": 38,
|
||||
"if-match": 39,
|
||||
"if-modified-since": 40,
|
||||
"if-none-match": 41,
|
||||
"if-range": 42,
|
||||
"if-unmodified-since": 43,
|
||||
"last-modified": 44,
|
||||
"link": 45,
|
||||
"location": 46,
|
||||
"max-forwards": 47,
|
||||
"proxy-authenticate": 48,
|
||||
"proxy-authorization": 49,
|
||||
"range": 50,
|
||||
"referer": 51,
|
||||
"refresh": 52,
|
||||
"retry-after": 53,
|
||||
"server": 54,
|
||||
"set-cookie": 55,
|
||||
"strict-transport-security": 56,
|
||||
"transfer-encoding": 57,
|
||||
"user-agent": 58,
|
||||
"vary": 59,
|
||||
"via": 60,
|
||||
"www-authenticate": 61,
|
||||
},
|
||||
byNameValue: map[pairNameValue]uint64{
|
||||
{name: ":authority", value: ""}: 1,
|
||||
{name: ":method", value: "GET"}: 2,
|
||||
{name: ":method", value: "POST"}: 3,
|
||||
{name: ":path", value: "/"}: 4,
|
||||
{name: ":path", value: "/index.html"}: 5,
|
||||
{name: ":scheme", value: "http"}: 6,
|
||||
{name: ":scheme", value: "https"}: 7,
|
||||
{name: ":status", value: "200"}: 8,
|
||||
{name: ":status", value: "204"}: 9,
|
||||
{name: ":status", value: "206"}: 10,
|
||||
{name: ":status", value: "304"}: 11,
|
||||
{name: ":status", value: "400"}: 12,
|
||||
{name: ":status", value: "404"}: 13,
|
||||
{name: ":status", value: "500"}: 14,
|
||||
{name: "accept-charset", value: ""}: 15,
|
||||
{name: "accept-encoding", value: "gzip, deflate"}: 16,
|
||||
{name: "accept-language", value: ""}: 17,
|
||||
{name: "accept-ranges", value: ""}: 18,
|
||||
{name: "accept", value: ""}: 19,
|
||||
{name: "access-control-allow-origin", value: ""}: 20,
|
||||
{name: "age", value: ""}: 21,
|
||||
{name: "allow", value: ""}: 22,
|
||||
{name: "authorization", value: ""}: 23,
|
||||
{name: "cache-control", value: ""}: 24,
|
||||
{name: "content-disposition", value: ""}: 25,
|
||||
{name: "content-encoding", value: ""}: 26,
|
||||
{name: "content-language", value: ""}: 27,
|
||||
{name: "content-length", value: ""}: 28,
|
||||
{name: "content-location", value: ""}: 29,
|
||||
{name: "content-range", value: ""}: 30,
|
||||
{name: "content-type", value: ""}: 31,
|
||||
{name: "cookie", value: ""}: 32,
|
||||
{name: "date", value: ""}: 33,
|
||||
{name: "etag", value: ""}: 34,
|
||||
{name: "expect", value: ""}: 35,
|
||||
{name: "expires", value: ""}: 36,
|
||||
{name: "from", value: ""}: 37,
|
||||
{name: "host", value: ""}: 38,
|
||||
{name: "if-match", value: ""}: 39,
|
||||
{name: "if-modified-since", value: ""}: 40,
|
||||
{name: "if-none-match", value: ""}: 41,
|
||||
{name: "if-range", value: ""}: 42,
|
||||
{name: "if-unmodified-since", value: ""}: 43,
|
||||
{name: "last-modified", value: ""}: 44,
|
||||
{name: "link", value: ""}: 45,
|
||||
{name: "location", value: ""}: 46,
|
||||
{name: "max-forwards", value: ""}: 47,
|
||||
{name: "proxy-authenticate", value: ""}: 48,
|
||||
{name: "proxy-authorization", value: ""}: 49,
|
||||
{name: "range", value: ""}: 50,
|
||||
{name: "referer", value: ""}: 51,
|
||||
{name: "refresh", value: ""}: 52,
|
||||
{name: "retry-after", value: ""}: 53,
|
||||
{name: "server", value: ""}: 54,
|
||||
{name: "set-cookie", value: ""}: 55,
|
||||
{name: "strict-transport-security", value: ""}: 56,
|
||||
{name: "transfer-encoding", value: ""}: 57,
|
||||
{name: "user-agent", value: ""}: 58,
|
||||
{name: "vary", value: ""}: 59,
|
||||
{name: "via", value: ""}: 60,
|
||||
{name: "www-authenticate", value: ""}: 61,
|
||||
},
|
||||
ents: []HeaderField{
|
||||
{Name: ":authority", Value: "", Sensitive: false},
|
||||
{Name: ":method", Value: "GET", Sensitive: false},
|
||||
{Name: ":method", Value: "POST", Sensitive: false},
|
||||
{Name: ":path", Value: "/", Sensitive: false},
|
||||
{Name: ":path", Value: "/index.html", Sensitive: false},
|
||||
{Name: ":scheme", Value: "http", Sensitive: false},
|
||||
{Name: ":scheme", Value: "https", Sensitive: false},
|
||||
{Name: ":status", Value: "200", Sensitive: false},
|
||||
{Name: ":status", Value: "204", Sensitive: false},
|
||||
{Name: ":status", Value: "206", Sensitive: false},
|
||||
{Name: ":status", Value: "304", Sensitive: false},
|
||||
{Name: ":status", Value: "400", Sensitive: false},
|
||||
{Name: ":status", Value: "404", Sensitive: false},
|
||||
{Name: ":status", Value: "500", Sensitive: false},
|
||||
{Name: "accept-charset", Value: "", Sensitive: false},
|
||||
{Name: "accept-encoding", Value: "gzip, deflate", Sensitive: false},
|
||||
{Name: "accept-language", Value: "", Sensitive: false},
|
||||
{Name: "accept-ranges", Value: "", Sensitive: false},
|
||||
{Name: "accept", Value: "", Sensitive: false},
|
||||
{Name: "access-control-allow-origin", Value: "", Sensitive: false},
|
||||
{Name: "age", Value: "", Sensitive: false},
|
||||
{Name: "allow", Value: "", Sensitive: false},
|
||||
{Name: "authorization", Value: "", Sensitive: false},
|
||||
{Name: "cache-control", Value: "", Sensitive: false},
|
||||
{Name: "content-disposition", Value: "", Sensitive: false},
|
||||
{Name: "content-encoding", Value: "", Sensitive: false},
|
||||
{Name: "content-language", Value: "", Sensitive: false},
|
||||
{Name: "content-length", Value: "", Sensitive: false},
|
||||
{Name: "content-location", Value: "", Sensitive: false},
|
||||
{Name: "content-range", Value: "", Sensitive: false},
|
||||
{Name: "content-type", Value: "", Sensitive: false},
|
||||
{Name: "cookie", Value: "", Sensitive: false},
|
||||
{Name: "date", Value: "", Sensitive: false},
|
||||
{Name: "etag", Value: "", Sensitive: false},
|
||||
{Name: "expect", Value: "", Sensitive: false},
|
||||
{Name: "expires", Value: "", Sensitive: false},
|
||||
{Name: "from", Value: "", Sensitive: false},
|
||||
{Name: "host", Value: "", Sensitive: false},
|
||||
{Name: "if-match", Value: "", Sensitive: false},
|
||||
{Name: "if-modified-since", Value: "", Sensitive: false},
|
||||
{Name: "if-none-match", Value: "", Sensitive: false},
|
||||
{Name: "if-range", Value: "", Sensitive: false},
|
||||
{Name: "if-unmodified-since", Value: "", Sensitive: false},
|
||||
{Name: "last-modified", Value: "", Sensitive: false},
|
||||
{Name: "link", Value: "", Sensitive: false},
|
||||
{Name: "location", Value: "", Sensitive: false},
|
||||
{Name: "max-forwards", Value: "", Sensitive: false},
|
||||
{Name: "proxy-authenticate", Value: "", Sensitive: false},
|
||||
{Name: "proxy-authorization", Value: "", Sensitive: false},
|
||||
{Name: "range", Value: "", Sensitive: false},
|
||||
{Name: "referer", Value: "", Sensitive: false},
|
||||
{Name: "refresh", Value: "", Sensitive: false},
|
||||
{Name: "retry-after", Value: "", Sensitive: false},
|
||||
{Name: "server", Value: "", Sensitive: false},
|
||||
{Name: "set-cookie", Value: "", Sensitive: false},
|
||||
{Name: "strict-transport-security", Value: "", Sensitive: false},
|
||||
{Name: "transfer-encoding", Value: "", Sensitive: false},
|
||||
{Name: "user-agent", Value: "", Sensitive: false},
|
||||
{Name: "vary", Value: "", Sensitive: false},
|
||||
{Name: "via", Value: "", Sensitive: false},
|
||||
{Name: "www-authenticate", Value: "", Sensitive: false},
|
||||
},
|
||||
}
|
||||
403
vendor/golang.org/x/net/http2/hpack/tables.go
generated
vendored
Normal file
403
vendor/golang.org/x/net/http2/hpack/tables.go
generated
vendored
Normal file
@@ -0,0 +1,403 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package hpack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// headerFieldTable implements a list of HeaderFields.
|
||||
// This is used to implement the static and dynamic tables.
|
||||
type headerFieldTable struct {
|
||||
// For static tables, entries are never evicted.
|
||||
//
|
||||
// For dynamic tables, entries are evicted from ents[0] and added to the end.
|
||||
// Each entry has a unique id that starts at one and increments for each
|
||||
// entry that is added. This unique id is stable across evictions, meaning
|
||||
// it can be used as a pointer to a specific entry. As in hpack, unique ids
|
||||
// are 1-based. The unique id for ents[k] is k + evictCount + 1.
|
||||
//
|
||||
// Zero is not a valid unique id.
|
||||
//
|
||||
// evictCount should not overflow in any remotely practical situation. In
|
||||
// practice, we will have one dynamic table per HTTP/2 connection. If we
|
||||
// assume a very powerful server that handles 1M QPS per connection and each
|
||||
// request adds (then evicts) 100 entries from the table, it would still take
|
||||
// 2M years for evictCount to overflow.
|
||||
ents []HeaderField
|
||||
evictCount uint64
|
||||
|
||||
// byName maps a HeaderField name to the unique id of the newest entry with
|
||||
// the same name. See above for a definition of "unique id".
|
||||
byName map[string]uint64
|
||||
|
||||
// byNameValue maps a HeaderField name/value pair to the unique id of the newest
|
||||
// entry with the same name and value. See above for a definition of "unique id".
|
||||
byNameValue map[pairNameValue]uint64
|
||||
}
|
||||
|
||||
type pairNameValue struct {
|
||||
name, value string
|
||||
}
|
||||
|
||||
func (t *headerFieldTable) init() {
|
||||
t.byName = make(map[string]uint64)
|
||||
t.byNameValue = make(map[pairNameValue]uint64)
|
||||
}
|
||||
|
||||
// len reports the number of entries in the table.
|
||||
func (t *headerFieldTable) len() int {
|
||||
return len(t.ents)
|
||||
}
|
||||
|
||||
// addEntry adds a new entry.
|
||||
func (t *headerFieldTable) addEntry(f HeaderField) {
|
||||
id := uint64(t.len()) + t.evictCount + 1
|
||||
t.byName[f.Name] = id
|
||||
t.byNameValue[pairNameValue{f.Name, f.Value}] = id
|
||||
t.ents = append(t.ents, f)
|
||||
}
|
||||
|
||||
// evictOldest evicts the n oldest entries in the table.
|
||||
func (t *headerFieldTable) evictOldest(n int) {
|
||||
if n > t.len() {
|
||||
panic(fmt.Sprintf("evictOldest(%v) on table with %v entries", n, t.len()))
|
||||
}
|
||||
for k := 0; k < n; k++ {
|
||||
f := t.ents[k]
|
||||
id := t.evictCount + uint64(k) + 1
|
||||
if t.byName[f.Name] == id {
|
||||
delete(t.byName, f.Name)
|
||||
}
|
||||
if p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id {
|
||||
delete(t.byNameValue, p)
|
||||
}
|
||||
}
|
||||
copy(t.ents, t.ents[n:])
|
||||
for k := t.len() - n; k < t.len(); k++ {
|
||||
t.ents[k] = HeaderField{} // so strings can be garbage collected
|
||||
}
|
||||
t.ents = t.ents[:t.len()-n]
|
||||
if t.evictCount+uint64(n) < t.evictCount {
|
||||
panic("evictCount overflow")
|
||||
}
|
||||
t.evictCount += uint64(n)
|
||||
}
|
||||
|
||||
// search finds f in the table. If there is no match, i is 0.
|
||||
// If both name and value match, i is the matched index and nameValueMatch
|
||||
// becomes true. If only name matches, i points to that index and
|
||||
// nameValueMatch becomes false.
|
||||
//
|
||||
// The returned index is a 1-based HPACK index. For dynamic tables, HPACK says
|
||||
// that index 1 should be the newest entry, but t.ents[0] is the oldest entry,
|
||||
// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic
|
||||
// table, the return value i actually refers to the entry t.ents[t.len()-i].
|
||||
//
|
||||
// All tables are assumed to be a dynamic tables except for the global staticTable.
|
||||
//
|
||||
// See Section 2.3.3.
|
||||
func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
|
||||
if !f.Sensitive {
|
||||
if id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 {
|
||||
return t.idToIndex(id), true
|
||||
}
|
||||
}
|
||||
if id := t.byName[f.Name]; id != 0 {
|
||||
return t.idToIndex(id), false
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// idToIndex converts a unique id to an HPACK index.
|
||||
// See Section 2.3.3.
|
||||
func (t *headerFieldTable) idToIndex(id uint64) uint64 {
|
||||
if id <= t.evictCount {
|
||||
panic(fmt.Sprintf("id (%v) <= evictCount (%v)", id, t.evictCount))
|
||||
}
|
||||
k := id - t.evictCount - 1 // convert id to an index t.ents[k]
|
||||
if t != staticTable {
|
||||
return uint64(t.len()) - k // dynamic table
|
||||
}
|
||||
return k + 1
|
||||
}
|
||||
|
||||
var huffmanCodes = [256]uint32{
|
||||
0x1ff8,
|
||||
0x7fffd8,
|
||||
0xfffffe2,
|
||||
0xfffffe3,
|
||||
0xfffffe4,
|
||||
0xfffffe5,
|
||||
0xfffffe6,
|
||||
0xfffffe7,
|
||||
0xfffffe8,
|
||||
0xffffea,
|
||||
0x3ffffffc,
|
||||
0xfffffe9,
|
||||
0xfffffea,
|
||||
0x3ffffffd,
|
||||
0xfffffeb,
|
||||
0xfffffec,
|
||||
0xfffffed,
|
||||
0xfffffee,
|
||||
0xfffffef,
|
||||
0xffffff0,
|
||||
0xffffff1,
|
||||
0xffffff2,
|
||||
0x3ffffffe,
|
||||
0xffffff3,
|
||||
0xffffff4,
|
||||
0xffffff5,
|
||||
0xffffff6,
|
||||
0xffffff7,
|
||||
0xffffff8,
|
||||
0xffffff9,
|
||||
0xffffffa,
|
||||
0xffffffb,
|
||||
0x14,
|
||||
0x3f8,
|
||||
0x3f9,
|
||||
0xffa,
|
||||
0x1ff9,
|
||||
0x15,
|
||||
0xf8,
|
||||
0x7fa,
|
||||
0x3fa,
|
||||
0x3fb,
|
||||
0xf9,
|
||||
0x7fb,
|
||||
0xfa,
|
||||
0x16,
|
||||
0x17,
|
||||
0x18,
|
||||
0x0,
|
||||
0x1,
|
||||
0x2,
|
||||
0x19,
|
||||
0x1a,
|
||||
0x1b,
|
||||
0x1c,
|
||||
0x1d,
|
||||
0x1e,
|
||||
0x1f,
|
||||
0x5c,
|
||||
0xfb,
|
||||
0x7ffc,
|
||||
0x20,
|
||||
0xffb,
|
||||
0x3fc,
|
||||
0x1ffa,
|
||||
0x21,
|
||||
0x5d,
|
||||
0x5e,
|
||||
0x5f,
|
||||
0x60,
|
||||
0x61,
|
||||
0x62,
|
||||
0x63,
|
||||
0x64,
|
||||
0x65,
|
||||
0x66,
|
||||
0x67,
|
||||
0x68,
|
||||
0x69,
|
||||
0x6a,
|
||||
0x6b,
|
||||
0x6c,
|
||||
0x6d,
|
||||
0x6e,
|
||||
0x6f,
|
||||
0x70,
|
||||
0x71,
|
||||
0x72,
|
||||
0xfc,
|
||||
0x73,
|
||||
0xfd,
|
||||
0x1ffb,
|
||||
0x7fff0,
|
||||
0x1ffc,
|
||||
0x3ffc,
|
||||
0x22,
|
||||
0x7ffd,
|
||||
0x3,
|
||||
0x23,
|
||||
0x4,
|
||||
0x24,
|
||||
0x5,
|
||||
0x25,
|
||||
0x26,
|
||||
0x27,
|
||||
0x6,
|
||||
0x74,
|
||||
0x75,
|
||||
0x28,
|
||||
0x29,
|
||||
0x2a,
|
||||
0x7,
|
||||
0x2b,
|
||||
0x76,
|
||||
0x2c,
|
||||
0x8,
|
||||
0x9,
|
||||
0x2d,
|
||||
0x77,
|
||||
0x78,
|
||||
0x79,
|
||||
0x7a,
|
||||
0x7b,
|
||||
0x7ffe,
|
||||
0x7fc,
|
||||
0x3ffd,
|
||||
0x1ffd,
|
||||
0xffffffc,
|
||||
0xfffe6,
|
||||
0x3fffd2,
|
||||
0xfffe7,
|
||||
0xfffe8,
|
||||
0x3fffd3,
|
||||
0x3fffd4,
|
||||
0x3fffd5,
|
||||
0x7fffd9,
|
||||
0x3fffd6,
|
||||
0x7fffda,
|
||||
0x7fffdb,
|
||||
0x7fffdc,
|
||||
0x7fffdd,
|
||||
0x7fffde,
|
||||
0xffffeb,
|
||||
0x7fffdf,
|
||||
0xffffec,
|
||||
0xffffed,
|
||||
0x3fffd7,
|
||||
0x7fffe0,
|
||||
0xffffee,
|
||||
0x7fffe1,
|
||||
0x7fffe2,
|
||||
0x7fffe3,
|
||||
0x7fffe4,
|
||||
0x1fffdc,
|
||||
0x3fffd8,
|
||||
0x7fffe5,
|
||||
0x3fffd9,
|
||||
0x7fffe6,
|
||||
0x7fffe7,
|
||||
0xffffef,
|
||||
0x3fffda,
|
||||
0x1fffdd,
|
||||
0xfffe9,
|
||||
0x3fffdb,
|
||||
0x3fffdc,
|
||||
0x7fffe8,
|
||||
0x7fffe9,
|
||||
0x1fffde,
|
||||
0x7fffea,
|
||||
0x3fffdd,
|
||||
0x3fffde,
|
||||
0xfffff0,
|
||||
0x1fffdf,
|
||||
0x3fffdf,
|
||||
0x7fffeb,
|
||||
0x7fffec,
|
||||
0x1fffe0,
|
||||
0x1fffe1,
|
||||
0x3fffe0,
|
||||
0x1fffe2,
|
||||
0x7fffed,
|
||||
0x3fffe1,
|
||||
0x7fffee,
|
||||
0x7fffef,
|
||||
0xfffea,
|
||||
0x3fffe2,
|
||||
0x3fffe3,
|
||||
0x3fffe4,
|
||||
0x7ffff0,
|
||||
0x3fffe5,
|
||||
0x3fffe6,
|
||||
0x7ffff1,
|
||||
0x3ffffe0,
|
||||
0x3ffffe1,
|
||||
0xfffeb,
|
||||
0x7fff1,
|
||||
0x3fffe7,
|
||||
0x7ffff2,
|
||||
0x3fffe8,
|
||||
0x1ffffec,
|
||||
0x3ffffe2,
|
||||
0x3ffffe3,
|
||||
0x3ffffe4,
|
||||
0x7ffffde,
|
||||
0x7ffffdf,
|
||||
0x3ffffe5,
|
||||
0xfffff1,
|
||||
0x1ffffed,
|
||||
0x7fff2,
|
||||
0x1fffe3,
|
||||
0x3ffffe6,
|
||||
0x7ffffe0,
|
||||
0x7ffffe1,
|
||||
0x3ffffe7,
|
||||
0x7ffffe2,
|
||||
0xfffff2,
|
||||
0x1fffe4,
|
||||
0x1fffe5,
|
||||
0x3ffffe8,
|
||||
0x3ffffe9,
|
||||
0xffffffd,
|
||||
0x7ffffe3,
|
||||
0x7ffffe4,
|
||||
0x7ffffe5,
|
||||
0xfffec,
|
||||
0xfffff3,
|
||||
0xfffed,
|
||||
0x1fffe6,
|
||||
0x3fffe9,
|
||||
0x1fffe7,
|
||||
0x1fffe8,
|
||||
0x7ffff3,
|
||||
0x3fffea,
|
||||
0x3fffeb,
|
||||
0x1ffffee,
|
||||
0x1ffffef,
|
||||
0xfffff4,
|
||||
0xfffff5,
|
||||
0x3ffffea,
|
||||
0x7ffff4,
|
||||
0x3ffffeb,
|
||||
0x7ffffe6,
|
||||
0x3ffffec,
|
||||
0x3ffffed,
|
||||
0x7ffffe7,
|
||||
0x7ffffe8,
|
||||
0x7ffffe9,
|
||||
0x7ffffea,
|
||||
0x7ffffeb,
|
||||
0xffffffe,
|
||||
0x7ffffec,
|
||||
0x7ffffed,
|
||||
0x7ffffee,
|
||||
0x7ffffef,
|
||||
0x7fffff0,
|
||||
0x3ffffee,
|
||||
}
|
||||
|
||||
var huffmanCodeLen = [256]uint8{
|
||||
13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,
|
||||
5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,
|
||||
13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,
|
||||
15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,
|
||||
6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,
|
||||
20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,
|
||||
24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,
|
||||
22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,
|
||||
21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,
|
||||
26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,
|
||||
19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,
|
||||
20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,
|
||||
26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,
|
||||
}
|
||||
13
vendor/golang.org/x/net/idna/go118.go
generated
vendored
Normal file
13
vendor/golang.org/x/net/idna/go118.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.18
|
||||
|
||||
package idna
|
||||
|
||||
// Transitional processing is disabled by default in Go 1.18.
|
||||
// https://golang.org/issue/47510
|
||||
const transitionalLookup = false
|
||||
769
vendor/golang.org/x/net/idna/idna10.0.0.go
generated
vendored
Normal file
769
vendor/golang.org/x/net/idna/idna10.0.0.go
generated
vendored
Normal file
@@ -0,0 +1,769 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.10
|
||||
|
||||
// Package idna implements IDNA2008 using the compatibility processing
|
||||
// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
|
||||
// deal with the transition from IDNA2003.
|
||||
//
|
||||
// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC
|
||||
// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.
|
||||
// UTS #46 is defined in https://www.unicode.org/reports/tr46.
|
||||
// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the
|
||||
// differences between these two standards.
|
||||
package idna // import "golang.org/x/net/idna"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/text/secure/bidirule"
|
||||
"golang.org/x/text/unicode/bidi"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
|
||||
// NOTE: Unlike common practice in Go APIs, the functions will return a
|
||||
// sanitized domain name in case of errors. Browsers sometimes use a partially
|
||||
// evaluated string as lookup.
|
||||
// TODO: the current error handling is, in my opinion, the least opinionated.
|
||||
// Other strategies are also viable, though:
|
||||
// Option 1) Return an empty string in case of error, but allow the user to
|
||||
// specify explicitly which errors to ignore.
|
||||
// Option 2) Return the partially evaluated string if it is itself a valid
|
||||
// string, otherwise return the empty string in case of error.
|
||||
// Option 3) Option 1 and 2.
|
||||
// Option 4) Always return an empty string for now and implement Option 1 as
|
||||
// needed, and document that the return string may not be empty in case of
|
||||
// error in the future.
|
||||
// I think Option 1 is best, but it is quite opinionated.
|
||||
|
||||
// ToASCII is a wrapper for Punycode.ToASCII.
|
||||
func ToASCII(s string) (string, error) {
|
||||
return Punycode.process(s, true)
|
||||
}
|
||||
|
||||
// ToUnicode is a wrapper for Punycode.ToUnicode.
|
||||
func ToUnicode(s string) (string, error) {
|
||||
return Punycode.process(s, false)
|
||||
}
|
||||
|
||||
// An Option configures a Profile at creation time.
|
||||
type Option func(*options)
|
||||
|
||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||
// compatibility. It is used by some browsers when resolving domain names. This
|
||||
// option is only meaningful if combined with MapForLookup.
|
||||
func Transitional(transitional bool) Option {
|
||||
return func(o *options) { o.transitional = transitional }
|
||||
}
|
||||
|
||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||
// are longer than allowed by the RFC.
|
||||
//
|
||||
// This option corresponds to the VerifyDnsLength flag in UTS #46.
|
||||
func VerifyDNSLength(verify bool) Option {
|
||||
return func(o *options) { o.verifyDNSLength = verify }
|
||||
}
|
||||
|
||||
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
||||
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
||||
func RemoveLeadingDots(remove bool) Option {
|
||||
return func(o *options) { o.removeLeadingDots = remove }
|
||||
}
|
||||
|
||||
// ValidateLabels sets whether to check the mandatory label validation criteria
|
||||
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
||||
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
||||
// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags
|
||||
// in UTS #46.
|
||||
func ValidateLabels(enable bool) Option {
|
||||
return func(o *options) {
|
||||
// Don't override existing mappings, but set one that at least checks
|
||||
// normalization if it is not set.
|
||||
if o.mapping == nil && enable {
|
||||
o.mapping = normalize
|
||||
}
|
||||
o.trie = trie
|
||||
o.checkJoiners = enable
|
||||
o.checkHyphens = enable
|
||||
if enable {
|
||||
o.fromPuny = validateFromPunycode
|
||||
} else {
|
||||
o.fromPuny = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CheckHyphens sets whether to check for correct use of hyphens ('-') in
|
||||
// labels. Most web browsers do not have this option set, since labels such as
|
||||
// "r3---sn-apo3qvuoxuxbt-j5pe" are in common use.
|
||||
//
|
||||
// This option corresponds to the CheckHyphens flag in UTS #46.
|
||||
func CheckHyphens(enable bool) Option {
|
||||
return func(o *options) { o.checkHyphens = enable }
|
||||
}
|
||||
|
||||
// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix
|
||||
// A of RFC 5892, concerning the use of joiner runes.
|
||||
//
|
||||
// This option corresponds to the CheckJoiners flag in UTS #46.
|
||||
func CheckJoiners(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.trie = trie
|
||||
o.checkJoiners = enable
|
||||
}
|
||||
}
|
||||
|
||||
// StrictDomainName limits the set of permissible ASCII characters to those
|
||||
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
||||
// hyphen). This is set by default for MapForLookup and ValidateForRegistration,
|
||||
// but is only useful if ValidateLabels is set.
|
||||
//
|
||||
// This option is useful, for instance, for browsers that allow characters
|
||||
// outside this range, for example a '_' (U+005F LOW LINE). See
|
||||
// http://www.rfc-editor.org/std/std3.txt for more details.
|
||||
//
|
||||
// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.
|
||||
func StrictDomainName(use bool) Option {
|
||||
return func(o *options) { o.useSTD3Rules = use }
|
||||
}
|
||||
|
||||
// NOTE: the following options pull in tables. The tables should not be linked
|
||||
// in as long as the options are not used.
|
||||
|
||||
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
||||
// that relies on proper validation of labels should include this rule.
|
||||
//
|
||||
// This option corresponds to the CheckBidi flag in UTS #46.
|
||||
func BidiRule() Option {
|
||||
return func(o *options) { o.bidirule = bidirule.ValidString }
|
||||
}
|
||||
|
||||
// ValidateForRegistration sets validation options to verify that a given IDN is
|
||||
// properly formatted for registration as defined by Section 4 of RFC 5891.
|
||||
func ValidateForRegistration() Option {
|
||||
return func(o *options) {
|
||||
o.mapping = validateRegistration
|
||||
StrictDomainName(true)(o)
|
||||
ValidateLabels(true)(o)
|
||||
VerifyDNSLength(true)(o)
|
||||
BidiRule()(o)
|
||||
}
|
||||
}
|
||||
|
||||
// MapForLookup sets validation and mapping options such that a given IDN is
|
||||
// transformed for domain name lookup according to the requirements set out in
|
||||
// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,
|
||||
// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option
|
||||
// to add this check.
|
||||
//
|
||||
// The mappings include normalization and mapping case, width and other
|
||||
// compatibility mappings.
|
||||
func MapForLookup() Option {
|
||||
return func(o *options) {
|
||||
o.mapping = validateAndMap
|
||||
StrictDomainName(true)(o)
|
||||
ValidateLabels(true)(o)
|
||||
}
|
||||
}
|
||||
|
||||
type options struct {
|
||||
transitional bool
|
||||
useSTD3Rules bool
|
||||
checkHyphens bool
|
||||
checkJoiners bool
|
||||
verifyDNSLength bool
|
||||
removeLeadingDots bool
|
||||
|
||||
trie *idnaTrie
|
||||
|
||||
// fromPuny calls validation rules when converting A-labels to U-labels.
|
||||
fromPuny func(p *Profile, s string) error
|
||||
|
||||
// mapping implements a validation and mapping step as defined in RFC 5895
|
||||
// or UTS 46, tailored to, for example, domain registration or lookup.
|
||||
mapping func(p *Profile, s string) (mapped string, isBidi bool, err error)
|
||||
|
||||
// bidirule, if specified, checks whether s conforms to the Bidi Rule
|
||||
// defined in RFC 5893.
|
||||
bidirule func(s string) bool
|
||||
}
|
||||
|
||||
// A Profile defines the configuration of an IDNA mapper.
|
||||
type Profile struct {
|
||||
options
|
||||
}
|
||||
|
||||
func apply(o *options, opts []Option) {
|
||||
for _, f := range opts {
|
||||
f(o)
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a new Profile.
|
||||
//
|
||||
// With no options, the returned Profile is the most permissive and equals the
|
||||
// Punycode Profile. Options can be passed to further restrict the Profile. The
|
||||
// MapForLookup and ValidateForRegistration options set a collection of options,
|
||||
// for lookup and registration purposes respectively, which can be tailored by
|
||||
// adding more fine-grained options, where later options override earlier
|
||||
// options.
|
||||
func New(o ...Option) *Profile {
|
||||
p := &Profile{}
|
||||
apply(&p.options, o)
|
||||
return p
|
||||
}
|
||||
|
||||
// ToASCII converts a domain or domain label to its ASCII form. For example,
|
||||
// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
|
||||
// ToASCII("golang") is "golang". If an error is encountered it will return
|
||||
// an error and a (partially) processed result.
|
||||
func (p *Profile) ToASCII(s string) (string, error) {
|
||||
return p.process(s, true)
|
||||
}
|
||||
|
||||
// ToUnicode converts a domain or domain label to its Unicode form. For example,
|
||||
// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
|
||||
// ToUnicode("golang") is "golang". If an error is encountered it will return
|
||||
// an error and a (partially) processed result.
|
||||
func (p *Profile) ToUnicode(s string) (string, error) {
|
||||
pp := *p
|
||||
pp.transitional = false
|
||||
return pp.process(s, false)
|
||||
}
|
||||
|
||||
// String reports a string with a description of the profile for debugging
|
||||
// purposes. The string format may change with different versions.
|
||||
func (p *Profile) String() string {
|
||||
s := ""
|
||||
if p.transitional {
|
||||
s = "Transitional"
|
||||
} else {
|
||||
s = "NonTransitional"
|
||||
}
|
||||
if p.useSTD3Rules {
|
||||
s += ":UseSTD3Rules"
|
||||
}
|
||||
if p.checkHyphens {
|
||||
s += ":CheckHyphens"
|
||||
}
|
||||
if p.checkJoiners {
|
||||
s += ":CheckJoiners"
|
||||
}
|
||||
if p.verifyDNSLength {
|
||||
s += ":VerifyDNSLength"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
var (
|
||||
// Punycode is a Profile that does raw punycode processing with a minimum
|
||||
// of validation.
|
||||
Punycode *Profile = punycode
|
||||
|
||||
// Lookup is the recommended profile for looking up domain names, according
|
||||
// to Section 5 of RFC 5891. The exact configuration of this profile may
|
||||
// change over time.
|
||||
Lookup *Profile = lookup
|
||||
|
||||
// Display is the recommended profile for displaying domain names.
|
||||
// The configuration of this profile may change over time.
|
||||
Display *Profile = display
|
||||
|
||||
// Registration is the recommended profile for checking whether a given
|
||||
// IDN is valid for registration, according to Section 4 of RFC 5891.
|
||||
Registration *Profile = registration
|
||||
|
||||
punycode = &Profile{}
|
||||
lookup = &Profile{options{
|
||||
transitional: transitionalLookup,
|
||||
useSTD3Rules: true,
|
||||
checkHyphens: true,
|
||||
checkJoiners: true,
|
||||
trie: trie,
|
||||
fromPuny: validateFromPunycode,
|
||||
mapping: validateAndMap,
|
||||
bidirule: bidirule.ValidString,
|
||||
}}
|
||||
display = &Profile{options{
|
||||
useSTD3Rules: true,
|
||||
checkHyphens: true,
|
||||
checkJoiners: true,
|
||||
trie: trie,
|
||||
fromPuny: validateFromPunycode,
|
||||
mapping: validateAndMap,
|
||||
bidirule: bidirule.ValidString,
|
||||
}}
|
||||
registration = &Profile{options{
|
||||
useSTD3Rules: true,
|
||||
verifyDNSLength: true,
|
||||
checkHyphens: true,
|
||||
checkJoiners: true,
|
||||
trie: trie,
|
||||
fromPuny: validateFromPunycode,
|
||||
mapping: validateRegistration,
|
||||
bidirule: bidirule.ValidString,
|
||||
}}
|
||||
|
||||
// TODO: profiles
|
||||
// Register: recommended for approving domain names: don't do any mappings
|
||||
// but rather reject on invalid input. Bundle or block deviation characters.
|
||||
)
|
||||
|
||||
type labelError struct{ label, code_ string }
|
||||
|
||||
func (e labelError) code() string { return e.code_ }
|
||||
func (e labelError) Error() string {
|
||||
return fmt.Sprintf("idna: invalid label %q", e.label)
|
||||
}
|
||||
|
||||
type runeError rune
|
||||
|
||||
func (e runeError) code() string { return "P1" }
|
||||
func (e runeError) Error() string {
|
||||
return fmt.Sprintf("idna: disallowed rune %U", e)
|
||||
}
|
||||
|
||||
// process implements the algorithm described in section 4 of UTS #46,
|
||||
// see https://www.unicode.org/reports/tr46.
|
||||
func (p *Profile) process(s string, toASCII bool) (string, error) {
|
||||
var err error
|
||||
var isBidi bool
|
||||
if p.mapping != nil {
|
||||
s, isBidi, err = p.mapping(p, s)
|
||||
}
|
||||
// Remove leading empty labels.
|
||||
if p.removeLeadingDots {
|
||||
for ; len(s) > 0 && s[0] == '.'; s = s[1:] {
|
||||
}
|
||||
}
|
||||
// TODO: allow for a quick check of the tables data.
|
||||
// It seems like we should only create this error on ToASCII, but the
|
||||
// UTS 46 conformance tests suggests we should always check this.
|
||||
if err == nil && p.verifyDNSLength && s == "" {
|
||||
err = &labelError{s, "A4"}
|
||||
}
|
||||
labels := labelIter{orig: s}
|
||||
for ; !labels.done(); labels.next() {
|
||||
label := labels.label()
|
||||
if label == "" {
|
||||
// Empty labels are not okay. The label iterator skips the last
|
||||
// label if it is empty.
|
||||
if err == nil && p.verifyDNSLength {
|
||||
err = &labelError{s, "A4"}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(label, acePrefix) {
|
||||
u, err2 := decode(label[len(acePrefix):])
|
||||
if err2 != nil {
|
||||
if err == nil {
|
||||
err = err2
|
||||
}
|
||||
// Spec says keep the old label.
|
||||
continue
|
||||
}
|
||||
isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight
|
||||
labels.set(u)
|
||||
if err == nil && p.fromPuny != nil {
|
||||
err = p.fromPuny(p, u)
|
||||
}
|
||||
if err == nil {
|
||||
// This should be called on NonTransitional, according to the
|
||||
// spec, but that currently does not have any effect. Use the
|
||||
// original profile to preserve options.
|
||||
err = p.validateLabel(u)
|
||||
}
|
||||
} else if err == nil {
|
||||
err = p.validateLabel(label)
|
||||
}
|
||||
}
|
||||
if isBidi && p.bidirule != nil && err == nil {
|
||||
for labels.reset(); !labels.done(); labels.next() {
|
||||
if !p.bidirule(labels.label()) {
|
||||
err = &labelError{s, "B"}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if toASCII {
|
||||
for labels.reset(); !labels.done(); labels.next() {
|
||||
label := labels.label()
|
||||
if !ascii(label) {
|
||||
a, err2 := encode(acePrefix, label)
|
||||
if err == nil {
|
||||
err = err2
|
||||
}
|
||||
label = a
|
||||
labels.set(a)
|
||||
}
|
||||
n := len(label)
|
||||
if p.verifyDNSLength && err == nil && (n == 0 || n > 63) {
|
||||
err = &labelError{label, "A4"}
|
||||
}
|
||||
}
|
||||
}
|
||||
s = labels.result()
|
||||
if toASCII && p.verifyDNSLength && err == nil {
|
||||
// Compute the length of the domain name minus the root label and its dot.
|
||||
n := len(s)
|
||||
if n > 0 && s[n-1] == '.' {
|
||||
n--
|
||||
}
|
||||
if len(s) < 1 || n > 253 {
|
||||
err = &labelError{s, "A4"}
|
||||
}
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
|
||||
func normalize(p *Profile, s string) (mapped string, isBidi bool, err error) {
|
||||
// TODO: consider first doing a quick check to see if any of these checks
|
||||
// need to be done. This will make it slower in the general case, but
|
||||
// faster in the common case.
|
||||
mapped = norm.NFC.String(s)
|
||||
isBidi = bidirule.DirectionString(mapped) == bidi.RightToLeft
|
||||
return mapped, isBidi, nil
|
||||
}
|
||||
|
||||
func validateRegistration(p *Profile, s string) (idem string, bidi bool, err error) {
|
||||
// TODO: filter need for normalization in loop below.
|
||||
if !norm.NFC.IsNormalString(s) {
|
||||
return s, false, &labelError{s, "V1"}
|
||||
}
|
||||
for i := 0; i < len(s); {
|
||||
v, sz := trie.lookupString(s[i:])
|
||||
if sz == 0 {
|
||||
return s, bidi, runeError(utf8.RuneError)
|
||||
}
|
||||
bidi = bidi || info(v).isBidi(s[i:])
|
||||
// Copy bytes not copied so far.
|
||||
switch p.simplify(info(v).category()) {
|
||||
// TODO: handle the NV8 defined in the Unicode idna data set to allow
|
||||
// for strict conformance to IDNA2008.
|
||||
case valid, deviation:
|
||||
case disallowed, mapped, unknown, ignored:
|
||||
r, _ := utf8.DecodeRuneInString(s[i:])
|
||||
return s, bidi, runeError(r)
|
||||
}
|
||||
i += sz
|
||||
}
|
||||
return s, bidi, nil
|
||||
}
|
||||
|
||||
func (c info) isBidi(s string) bool {
|
||||
if !c.isMapped() {
|
||||
return c&attributesMask == rtl
|
||||
}
|
||||
// TODO: also store bidi info for mapped data. This is possible, but a bit
|
||||
// cumbersome and not for the common case.
|
||||
p, _ := bidi.LookupString(s)
|
||||
switch p.Class() {
|
||||
case bidi.R, bidi.AL, bidi.AN:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) {
|
||||
var (
|
||||
b []byte
|
||||
k int
|
||||
)
|
||||
// combinedInfoBits contains the or-ed bits of all runes. We use this
|
||||
// to derive the mayNeedNorm bit later. This may trigger normalization
|
||||
// overeagerly, but it will not do so in the common case. The end result
|
||||
// is another 10% saving on BenchmarkProfile for the common case.
|
||||
var combinedInfoBits info
|
||||
for i := 0; i < len(s); {
|
||||
v, sz := trie.lookupString(s[i:])
|
||||
if sz == 0 {
|
||||
b = append(b, s[k:i]...)
|
||||
b = append(b, "\ufffd"...)
|
||||
k = len(s)
|
||||
if err == nil {
|
||||
err = runeError(utf8.RuneError)
|
||||
}
|
||||
break
|
||||
}
|
||||
combinedInfoBits |= info(v)
|
||||
bidi = bidi || info(v).isBidi(s[i:])
|
||||
start := i
|
||||
i += sz
|
||||
// Copy bytes not copied so far.
|
||||
switch p.simplify(info(v).category()) {
|
||||
case valid:
|
||||
continue
|
||||
case disallowed:
|
||||
if err == nil {
|
||||
r, _ := utf8.DecodeRuneInString(s[start:])
|
||||
err = runeError(r)
|
||||
}
|
||||
continue
|
||||
case mapped, deviation:
|
||||
b = append(b, s[k:start]...)
|
||||
b = info(v).appendMapping(b, s[start:i])
|
||||
case ignored:
|
||||
b = append(b, s[k:start]...)
|
||||
// drop the rune
|
||||
case unknown:
|
||||
b = append(b, s[k:start]...)
|
||||
b = append(b, "\ufffd"...)
|
||||
}
|
||||
k = i
|
||||
}
|
||||
if k == 0 {
|
||||
// No changes so far.
|
||||
if combinedInfoBits&mayNeedNorm != 0 {
|
||||
s = norm.NFC.String(s)
|
||||
}
|
||||
} else {
|
||||
b = append(b, s[k:]...)
|
||||
if norm.NFC.QuickSpan(b) != len(b) {
|
||||
b = norm.NFC.Bytes(b)
|
||||
}
|
||||
// TODO: the punycode converters require strings as input.
|
||||
s = string(b)
|
||||
}
|
||||
return s, bidi, err
|
||||
}
|
||||
|
||||
// A labelIter allows iterating over domain name labels.
|
||||
type labelIter struct {
|
||||
orig string
|
||||
slice []string
|
||||
curStart int
|
||||
curEnd int
|
||||
i int
|
||||
}
|
||||
|
||||
func (l *labelIter) reset() {
|
||||
l.curStart = 0
|
||||
l.curEnd = 0
|
||||
l.i = 0
|
||||
}
|
||||
|
||||
func (l *labelIter) done() bool {
|
||||
return l.curStart >= len(l.orig)
|
||||
}
|
||||
|
||||
func (l *labelIter) result() string {
|
||||
if l.slice != nil {
|
||||
return strings.Join(l.slice, ".")
|
||||
}
|
||||
return l.orig
|
||||
}
|
||||
|
||||
func (l *labelIter) label() string {
|
||||
if l.slice != nil {
|
||||
return l.slice[l.i]
|
||||
}
|
||||
p := strings.IndexByte(l.orig[l.curStart:], '.')
|
||||
l.curEnd = l.curStart + p
|
||||
if p == -1 {
|
||||
l.curEnd = len(l.orig)
|
||||
}
|
||||
return l.orig[l.curStart:l.curEnd]
|
||||
}
|
||||
|
||||
// next sets the value to the next label. It skips the last label if it is empty.
|
||||
func (l *labelIter) next() {
|
||||
l.i++
|
||||
if l.slice != nil {
|
||||
if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" {
|
||||
l.curStart = len(l.orig)
|
||||
}
|
||||
} else {
|
||||
l.curStart = l.curEnd + 1
|
||||
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
|
||||
l.curStart = len(l.orig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *labelIter) set(s string) {
|
||||
if l.slice == nil {
|
||||
l.slice = strings.Split(l.orig, ".")
|
||||
}
|
||||
l.slice[l.i] = s
|
||||
}
|
||||
|
||||
// acePrefix is the ASCII Compatible Encoding prefix.
|
||||
const acePrefix = "xn--"
|
||||
|
||||
func (p *Profile) simplify(cat category) category {
|
||||
switch cat {
|
||||
case disallowedSTD3Mapped:
|
||||
if p.useSTD3Rules {
|
||||
cat = disallowed
|
||||
} else {
|
||||
cat = mapped
|
||||
}
|
||||
case disallowedSTD3Valid:
|
||||
if p.useSTD3Rules {
|
||||
cat = disallowed
|
||||
} else {
|
||||
cat = valid
|
||||
}
|
||||
case deviation:
|
||||
if !p.transitional {
|
||||
cat = valid
|
||||
}
|
||||
case validNV8, validXV8:
|
||||
// TODO: handle V2008
|
||||
cat = valid
|
||||
}
|
||||
return cat
|
||||
}
|
||||
|
||||
func validateFromPunycode(p *Profile, s string) error {
|
||||
if !norm.NFC.IsNormalString(s) {
|
||||
return &labelError{s, "V1"}
|
||||
}
|
||||
// TODO: detect whether string may have to be normalized in the following
|
||||
// loop.
|
||||
for i := 0; i < len(s); {
|
||||
v, sz := trie.lookupString(s[i:])
|
||||
if sz == 0 {
|
||||
return runeError(utf8.RuneError)
|
||||
}
|
||||
if c := p.simplify(info(v).category()); c != valid && c != deviation {
|
||||
return &labelError{s, "V6"}
|
||||
}
|
||||
i += sz
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
zwnj = "\u200c"
|
||||
zwj = "\u200d"
|
||||
)
|
||||
|
||||
type joinState int8
|
||||
|
||||
const (
|
||||
stateStart joinState = iota
|
||||
stateVirama
|
||||
stateBefore
|
||||
stateBeforeVirama
|
||||
stateAfter
|
||||
stateFAIL
|
||||
)
|
||||
|
||||
var joinStates = [][numJoinTypes]joinState{
|
||||
stateStart: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
joinZWNJ: stateFAIL,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateVirama,
|
||||
},
|
||||
stateVirama: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
},
|
||||
stateBefore: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
joiningT: stateBefore,
|
||||
joinZWNJ: stateAfter,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateBeforeVirama,
|
||||
},
|
||||
stateBeforeVirama: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
joiningT: stateBefore,
|
||||
},
|
||||
stateAfter: {
|
||||
joiningL: stateFAIL,
|
||||
joiningD: stateBefore,
|
||||
joiningT: stateAfter,
|
||||
joiningR: stateStart,
|
||||
joinZWNJ: stateFAIL,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateAfter, // no-op as we can't accept joiners here
|
||||
},
|
||||
stateFAIL: {
|
||||
0: stateFAIL,
|
||||
joiningL: stateFAIL,
|
||||
joiningD: stateFAIL,
|
||||
joiningT: stateFAIL,
|
||||
joiningR: stateFAIL,
|
||||
joinZWNJ: stateFAIL,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateFAIL,
|
||||
},
|
||||
}
|
||||
|
||||
// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are
|
||||
// already implicitly satisfied by the overall implementation.
|
||||
func (p *Profile) validateLabel(s string) (err error) {
|
||||
if s == "" {
|
||||
if p.verifyDNSLength {
|
||||
return &labelError{s, "A4"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if p.checkHyphens {
|
||||
if len(s) > 4 && s[2] == '-' && s[3] == '-' {
|
||||
return &labelError{s, "V2"}
|
||||
}
|
||||
if s[0] == '-' || s[len(s)-1] == '-' {
|
||||
return &labelError{s, "V3"}
|
||||
}
|
||||
}
|
||||
if !p.checkJoiners {
|
||||
return nil
|
||||
}
|
||||
trie := p.trie // p.checkJoiners is only set if trie is set.
|
||||
// TODO: merge the use of this in the trie.
|
||||
v, sz := trie.lookupString(s)
|
||||
x := info(v)
|
||||
if x.isModifier() {
|
||||
return &labelError{s, "V5"}
|
||||
}
|
||||
// Quickly return in the absence of zero-width (non) joiners.
|
||||
if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 {
|
||||
return nil
|
||||
}
|
||||
st := stateStart
|
||||
for i := 0; ; {
|
||||
jt := x.joinType()
|
||||
if s[i:i+sz] == zwj {
|
||||
jt = joinZWJ
|
||||
} else if s[i:i+sz] == zwnj {
|
||||
jt = joinZWNJ
|
||||
}
|
||||
st = joinStates[st][jt]
|
||||
if x.isViramaModifier() {
|
||||
st = joinStates[st][joinVirama]
|
||||
}
|
||||
if i += sz; i == len(s) {
|
||||
break
|
||||
}
|
||||
v, sz = trie.lookupString(s[i:])
|
||||
x = info(v)
|
||||
}
|
||||
if st == stateFAIL || st == stateAfter {
|
||||
return &labelError{s, "C"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ascii(s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] >= utf8.RuneSelf {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
717
vendor/golang.org/x/net/idna/idna9.0.0.go
generated
vendored
Normal file
717
vendor/golang.org/x/net/idna/idna9.0.0.go
generated
vendored
Normal file
@@ -0,0 +1,717 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !go1.10
|
||||
|
||||
// Package idna implements IDNA2008 using the compatibility processing
|
||||
// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
|
||||
// deal with the transition from IDNA2003.
|
||||
//
|
||||
// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC
|
||||
// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.
|
||||
// UTS #46 is defined in https://www.unicode.org/reports/tr46.
|
||||
// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the
|
||||
// differences between these two standards.
|
||||
package idna // import "golang.org/x/net/idna"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"golang.org/x/text/secure/bidirule"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
|
||||
// NOTE: Unlike common practice in Go APIs, the functions will return a
|
||||
// sanitized domain name in case of errors. Browsers sometimes use a partially
|
||||
// evaluated string as lookup.
|
||||
// TODO: the current error handling is, in my opinion, the least opinionated.
|
||||
// Other strategies are also viable, though:
|
||||
// Option 1) Return an empty string in case of error, but allow the user to
|
||||
// specify explicitly which errors to ignore.
|
||||
// Option 2) Return the partially evaluated string if it is itself a valid
|
||||
// string, otherwise return the empty string in case of error.
|
||||
// Option 3) Option 1 and 2.
|
||||
// Option 4) Always return an empty string for now and implement Option 1 as
|
||||
// needed, and document that the return string may not be empty in case of
|
||||
// error in the future.
|
||||
// I think Option 1 is best, but it is quite opinionated.
|
||||
|
||||
// ToASCII is a wrapper for Punycode.ToASCII.
|
||||
func ToASCII(s string) (string, error) {
|
||||
return Punycode.process(s, true)
|
||||
}
|
||||
|
||||
// ToUnicode is a wrapper for Punycode.ToUnicode.
|
||||
func ToUnicode(s string) (string, error) {
|
||||
return Punycode.process(s, false)
|
||||
}
|
||||
|
||||
// An Option configures a Profile at creation time.
|
||||
type Option func(*options)
|
||||
|
||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||
// compatibility. It is used by some browsers when resolving domain names. This
|
||||
// option is only meaningful if combined with MapForLookup.
|
||||
func Transitional(transitional bool) Option {
|
||||
return func(o *options) { o.transitional = transitional }
|
||||
}
|
||||
|
||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||
// are longer than allowed by the RFC.
|
||||
//
|
||||
// This option corresponds to the VerifyDnsLength flag in UTS #46.
|
||||
func VerifyDNSLength(verify bool) Option {
|
||||
return func(o *options) { o.verifyDNSLength = verify }
|
||||
}
|
||||
|
||||
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
||||
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
||||
func RemoveLeadingDots(remove bool) Option {
|
||||
return func(o *options) { o.removeLeadingDots = remove }
|
||||
}
|
||||
|
||||
// ValidateLabels sets whether to check the mandatory label validation criteria
|
||||
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
||||
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
||||
// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags
|
||||
// in UTS #46.
|
||||
func ValidateLabels(enable bool) Option {
|
||||
return func(o *options) {
|
||||
// Don't override existing mappings, but set one that at least checks
|
||||
// normalization if it is not set.
|
||||
if o.mapping == nil && enable {
|
||||
o.mapping = normalize
|
||||
}
|
||||
o.trie = trie
|
||||
o.checkJoiners = enable
|
||||
o.checkHyphens = enable
|
||||
if enable {
|
||||
o.fromPuny = validateFromPunycode
|
||||
} else {
|
||||
o.fromPuny = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CheckHyphens sets whether to check for correct use of hyphens ('-') in
|
||||
// labels. Most web browsers do not have this option set, since labels such as
|
||||
// "r3---sn-apo3qvuoxuxbt-j5pe" are in common use.
|
||||
//
|
||||
// This option corresponds to the CheckHyphens flag in UTS #46.
|
||||
func CheckHyphens(enable bool) Option {
|
||||
return func(o *options) { o.checkHyphens = enable }
|
||||
}
|
||||
|
||||
// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix
|
||||
// A of RFC 5892, concerning the use of joiner runes.
|
||||
//
|
||||
// This option corresponds to the CheckJoiners flag in UTS #46.
|
||||
func CheckJoiners(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.trie = trie
|
||||
o.checkJoiners = enable
|
||||
}
|
||||
}
|
||||
|
||||
// StrictDomainName limits the set of permissible ASCII characters to those
|
||||
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
||||
// hyphen). This is set by default for MapForLookup and ValidateForRegistration,
|
||||
// but is only useful if ValidateLabels is set.
|
||||
//
|
||||
// This option is useful, for instance, for browsers that allow characters
|
||||
// outside this range, for example a '_' (U+005F LOW LINE). See
|
||||
// http://www.rfc-editor.org/std/std3.txt for more details.
|
||||
//
|
||||
// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.
|
||||
func StrictDomainName(use bool) Option {
|
||||
return func(o *options) { o.useSTD3Rules = use }
|
||||
}
|
||||
|
||||
// NOTE: the following options pull in tables. The tables should not be linked
|
||||
// in as long as the options are not used.
|
||||
|
||||
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
||||
// that relies on proper validation of labels should include this rule.
|
||||
//
|
||||
// This option corresponds to the CheckBidi flag in UTS #46.
|
||||
func BidiRule() Option {
|
||||
return func(o *options) { o.bidirule = bidirule.ValidString }
|
||||
}
|
||||
|
||||
// ValidateForRegistration sets validation options to verify that a given IDN is
|
||||
// properly formatted for registration as defined by Section 4 of RFC 5891.
|
||||
func ValidateForRegistration() Option {
|
||||
return func(o *options) {
|
||||
o.mapping = validateRegistration
|
||||
StrictDomainName(true)(o)
|
||||
ValidateLabels(true)(o)
|
||||
VerifyDNSLength(true)(o)
|
||||
BidiRule()(o)
|
||||
}
|
||||
}
|
||||
|
||||
// MapForLookup sets validation and mapping options such that a given IDN is
|
||||
// transformed for domain name lookup according to the requirements set out in
|
||||
// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,
|
||||
// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option
|
||||
// to add this check.
|
||||
//
|
||||
// The mappings include normalization and mapping case, width and other
|
||||
// compatibility mappings.
|
||||
func MapForLookup() Option {
|
||||
return func(o *options) {
|
||||
o.mapping = validateAndMap
|
||||
StrictDomainName(true)(o)
|
||||
ValidateLabels(true)(o)
|
||||
RemoveLeadingDots(true)(o)
|
||||
}
|
||||
}
|
||||
|
||||
type options struct {
|
||||
transitional bool
|
||||
useSTD3Rules bool
|
||||
checkHyphens bool
|
||||
checkJoiners bool
|
||||
verifyDNSLength bool
|
||||
removeLeadingDots bool
|
||||
|
||||
trie *idnaTrie
|
||||
|
||||
// fromPuny calls validation rules when converting A-labels to U-labels.
|
||||
fromPuny func(p *Profile, s string) error
|
||||
|
||||
// mapping implements a validation and mapping step as defined in RFC 5895
|
||||
// or UTS 46, tailored to, for example, domain registration or lookup.
|
||||
mapping func(p *Profile, s string) (string, error)
|
||||
|
||||
// bidirule, if specified, checks whether s conforms to the Bidi Rule
|
||||
// defined in RFC 5893.
|
||||
bidirule func(s string) bool
|
||||
}
|
||||
|
||||
// A Profile defines the configuration of a IDNA mapper.
|
||||
type Profile struct {
|
||||
options
|
||||
}
|
||||
|
||||
func apply(o *options, opts []Option) {
|
||||
for _, f := range opts {
|
||||
f(o)
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a new Profile.
|
||||
//
|
||||
// With no options, the returned Profile is the most permissive and equals the
|
||||
// Punycode Profile. Options can be passed to further restrict the Profile. The
|
||||
// MapForLookup and ValidateForRegistration options set a collection of options,
|
||||
// for lookup and registration purposes respectively, which can be tailored by
|
||||
// adding more fine-grained options, where later options override earlier
|
||||
// options.
|
||||
func New(o ...Option) *Profile {
|
||||
p := &Profile{}
|
||||
apply(&p.options, o)
|
||||
return p
|
||||
}
|
||||
|
||||
// ToASCII converts a domain or domain label to its ASCII form. For example,
|
||||
// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
|
||||
// ToASCII("golang") is "golang". If an error is encountered it will return
|
||||
// an error and a (partially) processed result.
|
||||
func (p *Profile) ToASCII(s string) (string, error) {
|
||||
return p.process(s, true)
|
||||
}
|
||||
|
||||
// ToUnicode converts a domain or domain label to its Unicode form. For example,
|
||||
// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
|
||||
// ToUnicode("golang") is "golang". If an error is encountered it will return
|
||||
// an error and a (partially) processed result.
|
||||
func (p *Profile) ToUnicode(s string) (string, error) {
|
||||
pp := *p
|
||||
pp.transitional = false
|
||||
return pp.process(s, false)
|
||||
}
|
||||
|
||||
// String reports a string with a description of the profile for debugging
|
||||
// purposes. The string format may change with different versions.
|
||||
func (p *Profile) String() string {
|
||||
s := ""
|
||||
if p.transitional {
|
||||
s = "Transitional"
|
||||
} else {
|
||||
s = "NonTransitional"
|
||||
}
|
||||
if p.useSTD3Rules {
|
||||
s += ":UseSTD3Rules"
|
||||
}
|
||||
if p.checkHyphens {
|
||||
s += ":CheckHyphens"
|
||||
}
|
||||
if p.checkJoiners {
|
||||
s += ":CheckJoiners"
|
||||
}
|
||||
if p.verifyDNSLength {
|
||||
s += ":VerifyDNSLength"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
var (
|
||||
// Punycode is a Profile that does raw punycode processing with a minimum
|
||||
// of validation.
|
||||
Punycode *Profile = punycode
|
||||
|
||||
// Lookup is the recommended profile for looking up domain names, according
|
||||
// to Section 5 of RFC 5891. The exact configuration of this profile may
|
||||
// change over time.
|
||||
Lookup *Profile = lookup
|
||||
|
||||
// Display is the recommended profile for displaying domain names.
|
||||
// The configuration of this profile may change over time.
|
||||
Display *Profile = display
|
||||
|
||||
// Registration is the recommended profile for checking whether a given
|
||||
// IDN is valid for registration, according to Section 4 of RFC 5891.
|
||||
Registration *Profile = registration
|
||||
|
||||
punycode = &Profile{}
|
||||
lookup = &Profile{options{
|
||||
transitional: true,
|
||||
removeLeadingDots: true,
|
||||
useSTD3Rules: true,
|
||||
checkHyphens: true,
|
||||
checkJoiners: true,
|
||||
trie: trie,
|
||||
fromPuny: validateFromPunycode,
|
||||
mapping: validateAndMap,
|
||||
bidirule: bidirule.ValidString,
|
||||
}}
|
||||
display = &Profile{options{
|
||||
useSTD3Rules: true,
|
||||
removeLeadingDots: true,
|
||||
checkHyphens: true,
|
||||
checkJoiners: true,
|
||||
trie: trie,
|
||||
fromPuny: validateFromPunycode,
|
||||
mapping: validateAndMap,
|
||||
bidirule: bidirule.ValidString,
|
||||
}}
|
||||
registration = &Profile{options{
|
||||
useSTD3Rules: true,
|
||||
verifyDNSLength: true,
|
||||
checkHyphens: true,
|
||||
checkJoiners: true,
|
||||
trie: trie,
|
||||
fromPuny: validateFromPunycode,
|
||||
mapping: validateRegistration,
|
||||
bidirule: bidirule.ValidString,
|
||||
}}
|
||||
|
||||
// TODO: profiles
|
||||
// Register: recommended for approving domain names: don't do any mappings
|
||||
// but rather reject on invalid input. Bundle or block deviation characters.
|
||||
)
|
||||
|
||||
type labelError struct{ label, code_ string }
|
||||
|
||||
func (e labelError) code() string { return e.code_ }
|
||||
func (e labelError) Error() string {
|
||||
return fmt.Sprintf("idna: invalid label %q", e.label)
|
||||
}
|
||||
|
||||
type runeError rune
|
||||
|
||||
func (e runeError) code() string { return "P1" }
|
||||
func (e runeError) Error() string {
|
||||
return fmt.Sprintf("idna: disallowed rune %U", e)
|
||||
}
|
||||
|
||||
// process implements the algorithm described in section 4 of UTS #46,
|
||||
// see https://www.unicode.org/reports/tr46.
|
||||
func (p *Profile) process(s string, toASCII bool) (string, error) {
|
||||
var err error
|
||||
if p.mapping != nil {
|
||||
s, err = p.mapping(p, s)
|
||||
}
|
||||
// Remove leading empty labels.
|
||||
if p.removeLeadingDots {
|
||||
for ; len(s) > 0 && s[0] == '.'; s = s[1:] {
|
||||
}
|
||||
}
|
||||
// It seems like we should only create this error on ToASCII, but the
|
||||
// UTS 46 conformance tests suggests we should always check this.
|
||||
if err == nil && p.verifyDNSLength && s == "" {
|
||||
err = &labelError{s, "A4"}
|
||||
}
|
||||
labels := labelIter{orig: s}
|
||||
for ; !labels.done(); labels.next() {
|
||||
label := labels.label()
|
||||
if label == "" {
|
||||
// Empty labels are not okay. The label iterator skips the last
|
||||
// label if it is empty.
|
||||
if err == nil && p.verifyDNSLength {
|
||||
err = &labelError{s, "A4"}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(label, acePrefix) {
|
||||
u, err2 := decode(label[len(acePrefix):])
|
||||
if err2 != nil {
|
||||
if err == nil {
|
||||
err = err2
|
||||
}
|
||||
// Spec says keep the old label.
|
||||
continue
|
||||
}
|
||||
labels.set(u)
|
||||
if err == nil && p.fromPuny != nil {
|
||||
err = p.fromPuny(p, u)
|
||||
}
|
||||
if err == nil {
|
||||
// This should be called on NonTransitional, according to the
|
||||
// spec, but that currently does not have any effect. Use the
|
||||
// original profile to preserve options.
|
||||
err = p.validateLabel(u)
|
||||
}
|
||||
} else if err == nil {
|
||||
err = p.validateLabel(label)
|
||||
}
|
||||
}
|
||||
if toASCII {
|
||||
for labels.reset(); !labels.done(); labels.next() {
|
||||
label := labels.label()
|
||||
if !ascii(label) {
|
||||
a, err2 := encode(acePrefix, label)
|
||||
if err == nil {
|
||||
err = err2
|
||||
}
|
||||
label = a
|
||||
labels.set(a)
|
||||
}
|
||||
n := len(label)
|
||||
if p.verifyDNSLength && err == nil && (n == 0 || n > 63) {
|
||||
err = &labelError{label, "A4"}
|
||||
}
|
||||
}
|
||||
}
|
||||
s = labels.result()
|
||||
if toASCII && p.verifyDNSLength && err == nil {
|
||||
// Compute the length of the domain name minus the root label and its dot.
|
||||
n := len(s)
|
||||
if n > 0 && s[n-1] == '.' {
|
||||
n--
|
||||
}
|
||||
if len(s) < 1 || n > 253 {
|
||||
err = &labelError{s, "A4"}
|
||||
}
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
|
||||
func normalize(p *Profile, s string) (string, error) {
|
||||
return norm.NFC.String(s), nil
|
||||
}
|
||||
|
||||
func validateRegistration(p *Profile, s string) (string, error) {
|
||||
if !norm.NFC.IsNormalString(s) {
|
||||
return s, &labelError{s, "V1"}
|
||||
}
|
||||
for i := 0; i < len(s); {
|
||||
v, sz := trie.lookupString(s[i:])
|
||||
// Copy bytes not copied so far.
|
||||
switch p.simplify(info(v).category()) {
|
||||
// TODO: handle the NV8 defined in the Unicode idna data set to allow
|
||||
// for strict conformance to IDNA2008.
|
||||
case valid, deviation:
|
||||
case disallowed, mapped, unknown, ignored:
|
||||
r, _ := utf8.DecodeRuneInString(s[i:])
|
||||
return s, runeError(r)
|
||||
}
|
||||
i += sz
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func validateAndMap(p *Profile, s string) (string, error) {
|
||||
var (
|
||||
err error
|
||||
b []byte
|
||||
k int
|
||||
)
|
||||
for i := 0; i < len(s); {
|
||||
v, sz := trie.lookupString(s[i:])
|
||||
start := i
|
||||
i += sz
|
||||
// Copy bytes not copied so far.
|
||||
switch p.simplify(info(v).category()) {
|
||||
case valid:
|
||||
continue
|
||||
case disallowed:
|
||||
if err == nil {
|
||||
r, _ := utf8.DecodeRuneInString(s[start:])
|
||||
err = runeError(r)
|
||||
}
|
||||
continue
|
||||
case mapped, deviation:
|
||||
b = append(b, s[k:start]...)
|
||||
b = info(v).appendMapping(b, s[start:i])
|
||||
case ignored:
|
||||
b = append(b, s[k:start]...)
|
||||
// drop the rune
|
||||
case unknown:
|
||||
b = append(b, s[k:start]...)
|
||||
b = append(b, "\ufffd"...)
|
||||
}
|
||||
k = i
|
||||
}
|
||||
if k == 0 {
|
||||
// No changes so far.
|
||||
s = norm.NFC.String(s)
|
||||
} else {
|
||||
b = append(b, s[k:]...)
|
||||
if norm.NFC.QuickSpan(b) != len(b) {
|
||||
b = norm.NFC.Bytes(b)
|
||||
}
|
||||
// TODO: the punycode converters require strings as input.
|
||||
s = string(b)
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
|
||||
// A labelIter allows iterating over domain name labels.
|
||||
type labelIter struct {
|
||||
orig string
|
||||
slice []string
|
||||
curStart int
|
||||
curEnd int
|
||||
i int
|
||||
}
|
||||
|
||||
func (l *labelIter) reset() {
|
||||
l.curStart = 0
|
||||
l.curEnd = 0
|
||||
l.i = 0
|
||||
}
|
||||
|
||||
func (l *labelIter) done() bool {
|
||||
return l.curStart >= len(l.orig)
|
||||
}
|
||||
|
||||
func (l *labelIter) result() string {
|
||||
if l.slice != nil {
|
||||
return strings.Join(l.slice, ".")
|
||||
}
|
||||
return l.orig
|
||||
}
|
||||
|
||||
func (l *labelIter) label() string {
|
||||
if l.slice != nil {
|
||||
return l.slice[l.i]
|
||||
}
|
||||
p := strings.IndexByte(l.orig[l.curStart:], '.')
|
||||
l.curEnd = l.curStart + p
|
||||
if p == -1 {
|
||||
l.curEnd = len(l.orig)
|
||||
}
|
||||
return l.orig[l.curStart:l.curEnd]
|
||||
}
|
||||
|
||||
// next sets the value to the next label. It skips the last label if it is empty.
|
||||
func (l *labelIter) next() {
|
||||
l.i++
|
||||
if l.slice != nil {
|
||||
if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" {
|
||||
l.curStart = len(l.orig)
|
||||
}
|
||||
} else {
|
||||
l.curStart = l.curEnd + 1
|
||||
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {
|
||||
l.curStart = len(l.orig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *labelIter) set(s string) {
|
||||
if l.slice == nil {
|
||||
l.slice = strings.Split(l.orig, ".")
|
||||
}
|
||||
l.slice[l.i] = s
|
||||
}
|
||||
|
||||
// acePrefix is the ASCII Compatible Encoding prefix.
|
||||
const acePrefix = "xn--"
|
||||
|
||||
func (p *Profile) simplify(cat category) category {
|
||||
switch cat {
|
||||
case disallowedSTD3Mapped:
|
||||
if p.useSTD3Rules {
|
||||
cat = disallowed
|
||||
} else {
|
||||
cat = mapped
|
||||
}
|
||||
case disallowedSTD3Valid:
|
||||
if p.useSTD3Rules {
|
||||
cat = disallowed
|
||||
} else {
|
||||
cat = valid
|
||||
}
|
||||
case deviation:
|
||||
if !p.transitional {
|
||||
cat = valid
|
||||
}
|
||||
case validNV8, validXV8:
|
||||
// TODO: handle V2008
|
||||
cat = valid
|
||||
}
|
||||
return cat
|
||||
}
|
||||
|
||||
func validateFromPunycode(p *Profile, s string) error {
|
||||
if !norm.NFC.IsNormalString(s) {
|
||||
return &labelError{s, "V1"}
|
||||
}
|
||||
for i := 0; i < len(s); {
|
||||
v, sz := trie.lookupString(s[i:])
|
||||
if c := p.simplify(info(v).category()); c != valid && c != deviation {
|
||||
return &labelError{s, "V6"}
|
||||
}
|
||||
i += sz
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
zwnj = "\u200c"
|
||||
zwj = "\u200d"
|
||||
)
|
||||
|
||||
type joinState int8
|
||||
|
||||
const (
|
||||
stateStart joinState = iota
|
||||
stateVirama
|
||||
stateBefore
|
||||
stateBeforeVirama
|
||||
stateAfter
|
||||
stateFAIL
|
||||
)
|
||||
|
||||
var joinStates = [][numJoinTypes]joinState{
|
||||
stateStart: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
joinZWNJ: stateFAIL,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateVirama,
|
||||
},
|
||||
stateVirama: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
},
|
||||
stateBefore: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
joiningT: stateBefore,
|
||||
joinZWNJ: stateAfter,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateBeforeVirama,
|
||||
},
|
||||
stateBeforeVirama: {
|
||||
joiningL: stateBefore,
|
||||
joiningD: stateBefore,
|
||||
joiningT: stateBefore,
|
||||
},
|
||||
stateAfter: {
|
||||
joiningL: stateFAIL,
|
||||
joiningD: stateBefore,
|
||||
joiningT: stateAfter,
|
||||
joiningR: stateStart,
|
||||
joinZWNJ: stateFAIL,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateAfter, // no-op as we can't accept joiners here
|
||||
},
|
||||
stateFAIL: {
|
||||
0: stateFAIL,
|
||||
joiningL: stateFAIL,
|
||||
joiningD: stateFAIL,
|
||||
joiningT: stateFAIL,
|
||||
joiningR: stateFAIL,
|
||||
joinZWNJ: stateFAIL,
|
||||
joinZWJ: stateFAIL,
|
||||
joinVirama: stateFAIL,
|
||||
},
|
||||
}
|
||||
|
||||
// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are
|
||||
// already implicitly satisfied by the overall implementation.
|
||||
func (p *Profile) validateLabel(s string) error {
|
||||
if s == "" {
|
||||
if p.verifyDNSLength {
|
||||
return &labelError{s, "A4"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if p.bidirule != nil && !p.bidirule(s) {
|
||||
return &labelError{s, "B"}
|
||||
}
|
||||
if p.checkHyphens {
|
||||
if len(s) > 4 && s[2] == '-' && s[3] == '-' {
|
||||
return &labelError{s, "V2"}
|
||||
}
|
||||
if s[0] == '-' || s[len(s)-1] == '-' {
|
||||
return &labelError{s, "V3"}
|
||||
}
|
||||
}
|
||||
if !p.checkJoiners {
|
||||
return nil
|
||||
}
|
||||
trie := p.trie // p.checkJoiners is only set if trie is set.
|
||||
// TODO: merge the use of this in the trie.
|
||||
v, sz := trie.lookupString(s)
|
||||
x := info(v)
|
||||
if x.isModifier() {
|
||||
return &labelError{s, "V5"}
|
||||
}
|
||||
// Quickly return in the absence of zero-width (non) joiners.
|
||||
if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 {
|
||||
return nil
|
||||
}
|
||||
st := stateStart
|
||||
for i := 0; ; {
|
||||
jt := x.joinType()
|
||||
if s[i:i+sz] == zwj {
|
||||
jt = joinZWJ
|
||||
} else if s[i:i+sz] == zwnj {
|
||||
jt = joinZWNJ
|
||||
}
|
||||
st = joinStates[st][jt]
|
||||
if x.isViramaModifier() {
|
||||
st = joinStates[st][joinVirama]
|
||||
}
|
||||
if i += sz; i == len(s) {
|
||||
break
|
||||
}
|
||||
v, sz = trie.lookupString(s[i:])
|
||||
x = info(v)
|
||||
}
|
||||
if st == stateFAIL || st == stateAfter {
|
||||
return &labelError{s, "C"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ascii(s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] >= utf8.RuneSelf {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
11
vendor/golang.org/x/net/idna/pre_go118.go
generated
vendored
Normal file
11
vendor/golang.org/x/net/idna/pre_go118.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !go1.18
|
||||
|
||||
package idna
|
||||
|
||||
const transitionalLookup = true
|
||||
217
vendor/golang.org/x/net/idna/punycode.go
generated
vendored
Normal file
217
vendor/golang.org/x/net/idna/punycode.go
generated
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package idna
|
||||
|
||||
// This file implements the Punycode algorithm from RFC 3492.
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// These parameter values are specified in section 5.
|
||||
//
|
||||
// All computation is done with int32s, so that overflow behavior is identical
|
||||
// regardless of whether int is 32-bit or 64-bit.
|
||||
const (
|
||||
base int32 = 36
|
||||
damp int32 = 700
|
||||
initialBias int32 = 72
|
||||
initialN int32 = 128
|
||||
skew int32 = 38
|
||||
tmax int32 = 26
|
||||
tmin int32 = 1
|
||||
)
|
||||
|
||||
func punyError(s string) error { return &labelError{s, "A3"} }
|
||||
|
||||
// decode decodes a string as specified in section 6.2.
|
||||
func decode(encoded string) (string, error) {
|
||||
if encoded == "" {
|
||||
return "", nil
|
||||
}
|
||||
pos := 1 + strings.LastIndex(encoded, "-")
|
||||
if pos == 1 {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
if pos == len(encoded) {
|
||||
return encoded[:len(encoded)-1], nil
|
||||
}
|
||||
output := make([]rune, 0, len(encoded))
|
||||
if pos != 0 {
|
||||
for _, r := range encoded[:pos-1] {
|
||||
output = append(output, r)
|
||||
}
|
||||
}
|
||||
i, n, bias := int32(0), initialN, initialBias
|
||||
overflow := false
|
||||
for pos < len(encoded) {
|
||||
oldI, w := i, int32(1)
|
||||
for k := base; ; k += base {
|
||||
if pos == len(encoded) {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
digit, ok := decodeDigit(encoded[pos])
|
||||
if !ok {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
pos++
|
||||
i, overflow = madd(i, digit, w)
|
||||
if overflow {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
t := k - bias
|
||||
if k <= bias {
|
||||
t = tmin
|
||||
} else if k >= bias+tmax {
|
||||
t = tmax
|
||||
}
|
||||
if digit < t {
|
||||
break
|
||||
}
|
||||
w, overflow = madd(0, w, base-t)
|
||||
if overflow {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
}
|
||||
if len(output) >= 1024 {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
x := int32(len(output) + 1)
|
||||
bias = adapt(i-oldI, x, oldI == 0)
|
||||
n += i / x
|
||||
i %= x
|
||||
if n < 0 || n > utf8.MaxRune {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
output = append(output, 0)
|
||||
copy(output[i+1:], output[i:])
|
||||
output[i] = n
|
||||
i++
|
||||
}
|
||||
return string(output), nil
|
||||
}
|
||||
|
||||
// encode encodes a string as specified in section 6.3 and prepends prefix to
|
||||
// the result.
|
||||
//
|
||||
// The "while h < length(input)" line in the specification becomes "for
|
||||
// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes.
|
||||
func encode(prefix, s string) (string, error) {
|
||||
output := make([]byte, len(prefix), len(prefix)+1+2*len(s))
|
||||
copy(output, prefix)
|
||||
delta, n, bias := int32(0), initialN, initialBias
|
||||
b, remaining := int32(0), int32(0)
|
||||
for _, r := range s {
|
||||
if r < 0x80 {
|
||||
b++
|
||||
output = append(output, byte(r))
|
||||
} else {
|
||||
remaining++
|
||||
}
|
||||
}
|
||||
h := b
|
||||
if b > 0 {
|
||||
output = append(output, '-')
|
||||
}
|
||||
overflow := false
|
||||
for remaining != 0 {
|
||||
m := int32(0x7fffffff)
|
||||
for _, r := range s {
|
||||
if m > r && r >= n {
|
||||
m = r
|
||||
}
|
||||
}
|
||||
delta, overflow = madd(delta, m-n, h+1)
|
||||
if overflow {
|
||||
return "", punyError(s)
|
||||
}
|
||||
n = m
|
||||
for _, r := range s {
|
||||
if r < n {
|
||||
delta++
|
||||
if delta < 0 {
|
||||
return "", punyError(s)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if r > n {
|
||||
continue
|
||||
}
|
||||
q := delta
|
||||
for k := base; ; k += base {
|
||||
t := k - bias
|
||||
if k <= bias {
|
||||
t = tmin
|
||||
} else if k >= bias+tmax {
|
||||
t = tmax
|
||||
}
|
||||
if q < t {
|
||||
break
|
||||
}
|
||||
output = append(output, encodeDigit(t+(q-t)%(base-t)))
|
||||
q = (q - t) / (base - t)
|
||||
}
|
||||
output = append(output, encodeDigit(q))
|
||||
bias = adapt(delta, h+1, h == b)
|
||||
delta = 0
|
||||
h++
|
||||
remaining--
|
||||
}
|
||||
delta++
|
||||
n++
|
||||
}
|
||||
return string(output), nil
|
||||
}
|
||||
|
||||
// madd computes a + (b * c), detecting overflow.
|
||||
func madd(a, b, c int32) (next int32, overflow bool) {
|
||||
p := int64(b) * int64(c)
|
||||
if p > math.MaxInt32-int64(a) {
|
||||
return 0, true
|
||||
}
|
||||
return a + int32(p), false
|
||||
}
|
||||
|
||||
func decodeDigit(x byte) (digit int32, ok bool) {
|
||||
switch {
|
||||
case '0' <= x && x <= '9':
|
||||
return int32(x - ('0' - 26)), true
|
||||
case 'A' <= x && x <= 'Z':
|
||||
return int32(x - 'A'), true
|
||||
case 'a' <= x && x <= 'z':
|
||||
return int32(x - 'a'), true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func encodeDigit(digit int32) byte {
|
||||
switch {
|
||||
case 0 <= digit && digit < 26:
|
||||
return byte(digit + 'a')
|
||||
case 26 <= digit && digit < 36:
|
||||
return byte(digit + ('0' - 26))
|
||||
}
|
||||
panic("idna: internal error in punycode encoding")
|
||||
}
|
||||
|
||||
// adapt is the bias adaptation function specified in section 6.1.
|
||||
func adapt(delta, numPoints int32, firstTime bool) int32 {
|
||||
if firstTime {
|
||||
delta /= damp
|
||||
} else {
|
||||
delta /= 2
|
||||
}
|
||||
delta += delta / numPoints
|
||||
k := int32(0)
|
||||
for delta > ((base-tmin)*tmax)/2 {
|
||||
delta /= base - tmin
|
||||
k += base
|
||||
}
|
||||
return k + (base-tmin+1)*delta/(delta+skew)
|
||||
}
|
||||
4559
vendor/golang.org/x/net/idna/tables10.0.0.go
generated
vendored
Normal file
4559
vendor/golang.org/x/net/idna/tables10.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4653
vendor/golang.org/x/net/idna/tables11.0.0.go
generated
vendored
Normal file
4653
vendor/golang.org/x/net/idna/tables11.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4733
vendor/golang.org/x/net/idna/tables12.0.0.go
generated
vendored
Normal file
4733
vendor/golang.org/x/net/idna/tables12.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4959
vendor/golang.org/x/net/idna/tables13.0.0.go
generated
vendored
Normal file
4959
vendor/golang.org/x/net/idna/tables13.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5144
vendor/golang.org/x/net/idna/tables15.0.0.go
generated
vendored
Normal file
5144
vendor/golang.org/x/net/idna/tables15.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4486
vendor/golang.org/x/net/idna/tables9.0.0.go
generated
vendored
Normal file
4486
vendor/golang.org/x/net/idna/tables9.0.0.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
51
vendor/golang.org/x/net/idna/trie.go
generated
vendored
Normal file
51
vendor/golang.org/x/net/idna/trie.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package idna
|
||||
|
||||
// Sparse block handling code.
|
||||
|
||||
type valueRange struct {
|
||||
value uint16 // header: value:stride
|
||||
lo, hi byte // header: lo:n
|
||||
}
|
||||
|
||||
type sparseBlocks struct {
|
||||
values []valueRange
|
||||
offset []uint16
|
||||
}
|
||||
|
||||
var idnaSparse = sparseBlocks{
|
||||
values: idnaSparseValues[:],
|
||||
offset: idnaSparseOffset[:],
|
||||
}
|
||||
|
||||
// Don't use newIdnaTrie to avoid unconditional linking in of the table.
|
||||
var trie = &idnaTrie{}
|
||||
|
||||
// lookup determines the type of block n and looks up the value for b.
|
||||
// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block
|
||||
// is a list of ranges with an accompanying value. Given a matching range r,
|
||||
// the value for b is by r.value + (b - r.lo) * stride.
|
||||
func (t *sparseBlocks) lookup(n uint32, b byte) uint16 {
|
||||
offset := t.offset[n]
|
||||
header := t.values[offset]
|
||||
lo := offset + 1
|
||||
hi := lo + uint16(header.lo)
|
||||
for lo < hi {
|
||||
m := lo + (hi-lo)/2
|
||||
r := t.values[m]
|
||||
if r.lo <= b && b <= r.hi {
|
||||
return r.value + uint16(b-r.lo)*header.value
|
||||
}
|
||||
if b < r.lo {
|
||||
hi = m
|
||||
} else {
|
||||
lo = m + 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
30
vendor/golang.org/x/net/idna/trie12.0.0.go
generated
vendored
Normal file
30
vendor/golang.org/x/net/idna/trie12.0.0.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !go1.16
|
||||
|
||||
package idna
|
||||
|
||||
// appendMapping appends the mapping for the respective rune. isMapped must be
|
||||
// true. A mapping is a categorization of a rune as defined in UTS #46.
|
||||
func (c info) appendMapping(b []byte, s string) []byte {
|
||||
index := int(c >> indexShift)
|
||||
if c&xorBit == 0 {
|
||||
s := mappings[index:]
|
||||
return append(b, s[1:s[0]+1]...)
|
||||
}
|
||||
b = append(b, s...)
|
||||
if c&inlineXOR == inlineXOR {
|
||||
// TODO: support and handle two-byte inline masks
|
||||
b[len(b)-1] ^= byte(index)
|
||||
} else {
|
||||
for p := len(b) - int(xorData[index]); p < len(b); p++ {
|
||||
index++
|
||||
b[p] ^= xorData[index]
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
30
vendor/golang.org/x/net/idna/trie13.0.0.go
generated
vendored
Normal file
30
vendor/golang.org/x/net/idna/trie13.0.0.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.16
|
||||
|
||||
package idna
|
||||
|
||||
// appendMapping appends the mapping for the respective rune. isMapped must be
|
||||
// true. A mapping is a categorization of a rune as defined in UTS #46.
|
||||
func (c info) appendMapping(b []byte, s string) []byte {
|
||||
index := int(c >> indexShift)
|
||||
if c&xorBit == 0 {
|
||||
p := index
|
||||
return append(b, mappings[mappingIndex[p]:mappingIndex[p+1]]...)
|
||||
}
|
||||
b = append(b, s...)
|
||||
if c&inlineXOR == inlineXOR {
|
||||
// TODO: support and handle two-byte inline masks
|
||||
b[len(b)-1] ^= byte(index)
|
||||
} else {
|
||||
for p := len(b) - int(xorData[index]); p < len(b); p++ {
|
||||
index++
|
||||
b[p] ^= xorData[index]
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
119
vendor/golang.org/x/net/idna/trieval.go
generated
vendored
Normal file
119
vendor/golang.org/x/net/idna/trieval.go
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
package idna
|
||||
|
||||
// This file contains definitions for interpreting the trie value of the idna
|
||||
// trie generated by "go run gen*.go". It is shared by both the generator
|
||||
// program and the resultant package. Sharing is achieved by the generator
|
||||
// copying gen_trieval.go to trieval.go and changing what's above this comment.
|
||||
|
||||
// info holds information from the IDNA mapping table for a single rune. It is
|
||||
// the value returned by a trie lookup. In most cases, all information fits in
|
||||
// a 16-bit value. For mappings, this value may contain an index into a slice
|
||||
// with the mapped string. Such mappings can consist of the actual mapped value
|
||||
// or an XOR pattern to be applied to the bytes of the UTF8 encoding of the
|
||||
// input rune. This technique is used by the cases packages and reduces the
|
||||
// table size significantly.
|
||||
//
|
||||
// The per-rune values have the following format:
|
||||
//
|
||||
// if mapped {
|
||||
// if inlinedXOR {
|
||||
// 15..13 inline XOR marker
|
||||
// 12..11 unused
|
||||
// 10..3 inline XOR mask
|
||||
// } else {
|
||||
// 15..3 index into xor or mapping table
|
||||
// }
|
||||
// } else {
|
||||
// 15..14 unused
|
||||
// 13 mayNeedNorm
|
||||
// 12..11 attributes
|
||||
// 10..8 joining type
|
||||
// 7..3 category type
|
||||
// }
|
||||
// 2 use xor pattern
|
||||
// 1..0 mapped category
|
||||
//
|
||||
// See the definitions below for a more detailed description of the various
|
||||
// bits.
|
||||
type info uint16
|
||||
|
||||
const (
|
||||
catSmallMask = 0x3
|
||||
catBigMask = 0xF8
|
||||
indexShift = 3
|
||||
xorBit = 0x4 // interpret the index as an xor pattern
|
||||
inlineXOR = 0xE000 // These bits are set if the XOR pattern is inlined.
|
||||
|
||||
joinShift = 8
|
||||
joinMask = 0x07
|
||||
|
||||
// Attributes
|
||||
attributesMask = 0x1800
|
||||
viramaModifier = 0x1800
|
||||
modifier = 0x1000
|
||||
rtl = 0x0800
|
||||
|
||||
mayNeedNorm = 0x2000
|
||||
)
|
||||
|
||||
// A category corresponds to a category defined in the IDNA mapping table.
|
||||
type category uint16
|
||||
|
||||
const (
|
||||
unknown category = 0 // not currently defined in unicode.
|
||||
mapped category = 1
|
||||
disallowedSTD3Mapped category = 2
|
||||
deviation category = 3
|
||||
)
|
||||
|
||||
const (
|
||||
valid category = 0x08
|
||||
validNV8 category = 0x18
|
||||
validXV8 category = 0x28
|
||||
disallowed category = 0x40
|
||||
disallowedSTD3Valid category = 0x80
|
||||
ignored category = 0xC0
|
||||
)
|
||||
|
||||
// join types and additional rune information
|
||||
const (
|
||||
joiningL = (iota + 1)
|
||||
joiningD
|
||||
joiningT
|
||||
joiningR
|
||||
|
||||
//the following types are derived during processing
|
||||
joinZWJ
|
||||
joinZWNJ
|
||||
joinVirama
|
||||
numJoinTypes
|
||||
)
|
||||
|
||||
func (c info) isMapped() bool {
|
||||
return c&0x3 != 0
|
||||
}
|
||||
|
||||
func (c info) category() category {
|
||||
small := c & catSmallMask
|
||||
if small != 0 {
|
||||
return category(small)
|
||||
}
|
||||
return category(c & catBigMask)
|
||||
}
|
||||
|
||||
func (c info) joinType() info {
|
||||
if c.isMapped() {
|
||||
return 0
|
||||
}
|
||||
return (c >> joinShift) & joinMask
|
||||
}
|
||||
|
||||
func (c info) isModifier() bool {
|
||||
return c&(modifier|catSmallMask) == modifier
|
||||
}
|
||||
|
||||
func (c info) isViramaModifier() bool {
|
||||
return c&(attributesMask|catSmallMask) == viramaModifier
|
||||
}
|
||||
223
vendor/golang.org/x/net/internal/iana/const.go
generated
vendored
Normal file
223
vendor/golang.org/x/net/internal/iana/const.go
generated
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
// go generate gen.go
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
|
||||
package iana // import "golang.org/x/net/internal/iana"
|
||||
|
||||
// Differentiated Services Field Codepoints (DSCP), Updated: 2018-05-04
|
||||
const (
|
||||
DiffServCS0 = 0x00 // CS0
|
||||
DiffServCS1 = 0x20 // CS1
|
||||
DiffServCS2 = 0x40 // CS2
|
||||
DiffServCS3 = 0x60 // CS3
|
||||
DiffServCS4 = 0x80 // CS4
|
||||
DiffServCS5 = 0xa0 // CS5
|
||||
DiffServCS6 = 0xc0 // CS6
|
||||
DiffServCS7 = 0xe0 // CS7
|
||||
DiffServAF11 = 0x28 // AF11
|
||||
DiffServAF12 = 0x30 // AF12
|
||||
DiffServAF13 = 0x38 // AF13
|
||||
DiffServAF21 = 0x48 // AF21
|
||||
DiffServAF22 = 0x50 // AF22
|
||||
DiffServAF23 = 0x58 // AF23
|
||||
DiffServAF31 = 0x68 // AF31
|
||||
DiffServAF32 = 0x70 // AF32
|
||||
DiffServAF33 = 0x78 // AF33
|
||||
DiffServAF41 = 0x88 // AF41
|
||||
DiffServAF42 = 0x90 // AF42
|
||||
DiffServAF43 = 0x98 // AF43
|
||||
DiffServEF = 0xb8 // EF
|
||||
DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
|
||||
NotECNTransport = 0x00 // Not-ECT (Not ECN-Capable Transport)
|
||||
ECNTransport1 = 0x01 // ECT(1) (ECN-Capable Transport(1))
|
||||
ECNTransport0 = 0x02 // ECT(0) (ECN-Capable Transport(0))
|
||||
CongestionExperienced = 0x03 // CE (Congestion Experienced)
|
||||
)
|
||||
|
||||
// Protocol Numbers, Updated: 2017-10-13
|
||||
const (
|
||||
ProtocolIP = 0 // IPv4 encapsulation, pseudo protocol number
|
||||
ProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option
|
||||
ProtocolICMP = 1 // Internet Control Message
|
||||
ProtocolIGMP = 2 // Internet Group Management
|
||||
ProtocolGGP = 3 // Gateway-to-Gateway
|
||||
ProtocolIPv4 = 4 // IPv4 encapsulation
|
||||
ProtocolST = 5 // Stream
|
||||
ProtocolTCP = 6 // Transmission Control
|
||||
ProtocolCBT = 7 // CBT
|
||||
ProtocolEGP = 8 // Exterior Gateway Protocol
|
||||
ProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP)
|
||||
ProtocolBBNRCCMON = 10 // BBN RCC Monitoring
|
||||
ProtocolNVPII = 11 // Network Voice Protocol
|
||||
ProtocolPUP = 12 // PUP
|
||||
ProtocolEMCON = 14 // EMCON
|
||||
ProtocolXNET = 15 // Cross Net Debugger
|
||||
ProtocolCHAOS = 16 // Chaos
|
||||
ProtocolUDP = 17 // User Datagram
|
||||
ProtocolMUX = 18 // Multiplexing
|
||||
ProtocolDCNMEAS = 19 // DCN Measurement Subsystems
|
||||
ProtocolHMP = 20 // Host Monitoring
|
||||
ProtocolPRM = 21 // Packet Radio Measurement
|
||||
ProtocolXNSIDP = 22 // XEROX NS IDP
|
||||
ProtocolTRUNK1 = 23 // Trunk-1
|
||||
ProtocolTRUNK2 = 24 // Trunk-2
|
||||
ProtocolLEAF1 = 25 // Leaf-1
|
||||
ProtocolLEAF2 = 26 // Leaf-2
|
||||
ProtocolRDP = 27 // Reliable Data Protocol
|
||||
ProtocolIRTP = 28 // Internet Reliable Transaction
|
||||
ProtocolISOTP4 = 29 // ISO Transport Protocol Class 4
|
||||
ProtocolNETBLT = 30 // Bulk Data Transfer Protocol
|
||||
ProtocolMFENSP = 31 // MFE Network Services Protocol
|
||||
ProtocolMERITINP = 32 // MERIT Internodal Protocol
|
||||
ProtocolDCCP = 33 // Datagram Congestion Control Protocol
|
||||
Protocol3PC = 34 // Third Party Connect Protocol
|
||||
ProtocolIDPR = 35 // Inter-Domain Policy Routing Protocol
|
||||
ProtocolXTP = 36 // XTP
|
||||
ProtocolDDP = 37 // Datagram Delivery Protocol
|
||||
ProtocolIDPRCMTP = 38 // IDPR Control Message Transport Proto
|
||||
ProtocolTPPP = 39 // TP++ Transport Protocol
|
||||
ProtocolIL = 40 // IL Transport Protocol
|
||||
ProtocolIPv6 = 41 // IPv6 encapsulation
|
||||
ProtocolSDRP = 42 // Source Demand Routing Protocol
|
||||
ProtocolIPv6Route = 43 // Routing Header for IPv6
|
||||
ProtocolIPv6Frag = 44 // Fragment Header for IPv6
|
||||
ProtocolIDRP = 45 // Inter-Domain Routing Protocol
|
||||
ProtocolRSVP = 46 // Reservation Protocol
|
||||
ProtocolGRE = 47 // Generic Routing Encapsulation
|
||||
ProtocolDSR = 48 // Dynamic Source Routing Protocol
|
||||
ProtocolBNA = 49 // BNA
|
||||
ProtocolESP = 50 // Encap Security Payload
|
||||
ProtocolAH = 51 // Authentication Header
|
||||
ProtocolINLSP = 52 // Integrated Net Layer Security TUBA
|
||||
ProtocolNARP = 54 // NBMA Address Resolution Protocol
|
||||
ProtocolMOBILE = 55 // IP Mobility
|
||||
ProtocolTLSP = 56 // Transport Layer Security Protocol using Kryptonet key management
|
||||
ProtocolSKIP = 57 // SKIP
|
||||
ProtocolIPv6ICMP = 58 // ICMP for IPv6
|
||||
ProtocolIPv6NoNxt = 59 // No Next Header for IPv6
|
||||
ProtocolIPv6Opts = 60 // Destination Options for IPv6
|
||||
ProtocolCFTP = 62 // CFTP
|
||||
ProtocolSATEXPAK = 64 // SATNET and Backroom EXPAK
|
||||
ProtocolKRYPTOLAN = 65 // Kryptolan
|
||||
ProtocolRVD = 66 // MIT Remote Virtual Disk Protocol
|
||||
ProtocolIPPC = 67 // Internet Pluribus Packet Core
|
||||
ProtocolSATMON = 69 // SATNET Monitoring
|
||||
ProtocolVISA = 70 // VISA Protocol
|
||||
ProtocolIPCV = 71 // Internet Packet Core Utility
|
||||
ProtocolCPNX = 72 // Computer Protocol Network Executive
|
||||
ProtocolCPHB = 73 // Computer Protocol Heart Beat
|
||||
ProtocolWSN = 74 // Wang Span Network
|
||||
ProtocolPVP = 75 // Packet Video Protocol
|
||||
ProtocolBRSATMON = 76 // Backroom SATNET Monitoring
|
||||
ProtocolSUNND = 77 // SUN ND PROTOCOL-Temporary
|
||||
ProtocolWBMON = 78 // WIDEBAND Monitoring
|
||||
ProtocolWBEXPAK = 79 // WIDEBAND EXPAK
|
||||
ProtocolISOIP = 80 // ISO Internet Protocol
|
||||
ProtocolVMTP = 81 // VMTP
|
||||
ProtocolSECUREVMTP = 82 // SECURE-VMTP
|
||||
ProtocolVINES = 83 // VINES
|
||||
ProtocolTTP = 84 // Transaction Transport Protocol
|
||||
ProtocolIPTM = 84 // Internet Protocol Traffic Manager
|
||||
ProtocolNSFNETIGP = 85 // NSFNET-IGP
|
||||
ProtocolDGP = 86 // Dissimilar Gateway Protocol
|
||||
ProtocolTCF = 87 // TCF
|
||||
ProtocolEIGRP = 88 // EIGRP
|
||||
ProtocolOSPFIGP = 89 // OSPFIGP
|
||||
ProtocolSpriteRPC = 90 // Sprite RPC Protocol
|
||||
ProtocolLARP = 91 // Locus Address Resolution Protocol
|
||||
ProtocolMTP = 92 // Multicast Transport Protocol
|
||||
ProtocolAX25 = 93 // AX.25 Frames
|
||||
ProtocolIPIP = 94 // IP-within-IP Encapsulation Protocol
|
||||
ProtocolSCCSP = 96 // Semaphore Communications Sec. Pro.
|
||||
ProtocolETHERIP = 97 // Ethernet-within-IP Encapsulation
|
||||
ProtocolENCAP = 98 // Encapsulation Header
|
||||
ProtocolGMTP = 100 // GMTP
|
||||
ProtocolIFMP = 101 // Ipsilon Flow Management Protocol
|
||||
ProtocolPNNI = 102 // PNNI over IP
|
||||
ProtocolPIM = 103 // Protocol Independent Multicast
|
||||
ProtocolARIS = 104 // ARIS
|
||||
ProtocolSCPS = 105 // SCPS
|
||||
ProtocolQNX = 106 // QNX
|
||||
ProtocolAN = 107 // Active Networks
|
||||
ProtocolIPComp = 108 // IP Payload Compression Protocol
|
||||
ProtocolSNP = 109 // Sitara Networks Protocol
|
||||
ProtocolCompaqPeer = 110 // Compaq Peer Protocol
|
||||
ProtocolIPXinIP = 111 // IPX in IP
|
||||
ProtocolVRRP = 112 // Virtual Router Redundancy Protocol
|
||||
ProtocolPGM = 113 // PGM Reliable Transport Protocol
|
||||
ProtocolL2TP = 115 // Layer Two Tunneling Protocol
|
||||
ProtocolDDX = 116 // D-II Data Exchange (DDX)
|
||||
ProtocolIATP = 117 // Interactive Agent Transfer Protocol
|
||||
ProtocolSTP = 118 // Schedule Transfer Protocol
|
||||
ProtocolSRP = 119 // SpectraLink Radio Protocol
|
||||
ProtocolUTI = 120 // UTI
|
||||
ProtocolSMP = 121 // Simple Message Protocol
|
||||
ProtocolPTP = 123 // Performance Transparency Protocol
|
||||
ProtocolISIS = 124 // ISIS over IPv4
|
||||
ProtocolFIRE = 125 // FIRE
|
||||
ProtocolCRTP = 126 // Combat Radio Transport Protocol
|
||||
ProtocolCRUDP = 127 // Combat Radio User Datagram
|
||||
ProtocolSSCOPMCE = 128 // SSCOPMCE
|
||||
ProtocolIPLT = 129 // IPLT
|
||||
ProtocolSPS = 130 // Secure Packet Shield
|
||||
ProtocolPIPE = 131 // Private IP Encapsulation within IP
|
||||
ProtocolSCTP = 132 // Stream Control Transmission Protocol
|
||||
ProtocolFC = 133 // Fibre Channel
|
||||
ProtocolRSVPE2EIGNORE = 134 // RSVP-E2E-IGNORE
|
||||
ProtocolMobilityHeader = 135 // Mobility Header
|
||||
ProtocolUDPLite = 136 // UDPLite
|
||||
ProtocolMPLSinIP = 137 // MPLS-in-IP
|
||||
ProtocolMANET = 138 // MANET Protocols
|
||||
ProtocolHIP = 139 // Host Identity Protocol
|
||||
ProtocolShim6 = 140 // Shim6 Protocol
|
||||
ProtocolWESP = 141 // Wrapped Encapsulating Security Payload
|
||||
ProtocolROHC = 142 // Robust Header Compression
|
||||
ProtocolReserved = 255 // Reserved
|
||||
)
|
||||
|
||||
// Address Family Numbers, Updated: 2018-04-02
|
||||
const (
|
||||
AddrFamilyIPv4 = 1 // IP (IP version 4)
|
||||
AddrFamilyIPv6 = 2 // IP6 (IP version 6)
|
||||
AddrFamilyNSAP = 3 // NSAP
|
||||
AddrFamilyHDLC = 4 // HDLC (8-bit multidrop)
|
||||
AddrFamilyBBN1822 = 5 // BBN 1822
|
||||
AddrFamily802 = 6 // 802 (includes all 802 media plus Ethernet "canonical format")
|
||||
AddrFamilyE163 = 7 // E.163
|
||||
AddrFamilyE164 = 8 // E.164 (SMDS, Frame Relay, ATM)
|
||||
AddrFamilyF69 = 9 // F.69 (Telex)
|
||||
AddrFamilyX121 = 10 // X.121 (X.25, Frame Relay)
|
||||
AddrFamilyIPX = 11 // IPX
|
||||
AddrFamilyAppletalk = 12 // Appletalk
|
||||
AddrFamilyDecnetIV = 13 // Decnet IV
|
||||
AddrFamilyBanyanVines = 14 // Banyan Vines
|
||||
AddrFamilyE164withSubaddress = 15 // E.164 with NSAP format subaddress
|
||||
AddrFamilyDNS = 16 // DNS (Domain Name System)
|
||||
AddrFamilyDistinguishedName = 17 // Distinguished Name
|
||||
AddrFamilyASNumber = 18 // AS Number
|
||||
AddrFamilyXTPoverIPv4 = 19 // XTP over IP version 4
|
||||
AddrFamilyXTPoverIPv6 = 20 // XTP over IP version 6
|
||||
AddrFamilyXTPnativemodeXTP = 21 // XTP native mode XTP
|
||||
AddrFamilyFibreChannelWorldWidePortName = 22 // Fibre Channel World-Wide Port Name
|
||||
AddrFamilyFibreChannelWorldWideNodeName = 23 // Fibre Channel World-Wide Node Name
|
||||
AddrFamilyGWID = 24 // GWID
|
||||
AddrFamilyL2VPN = 25 // AFI for L2VPN information
|
||||
AddrFamilyMPLSTPSectionEndpointID = 26 // MPLS-TP Section Endpoint Identifier
|
||||
AddrFamilyMPLSTPLSPEndpointID = 27 // MPLS-TP LSP Endpoint Identifier
|
||||
AddrFamilyMPLSTPPseudowireEndpointID = 28 // MPLS-TP Pseudowire Endpoint Identifier
|
||||
AddrFamilyMTIPv4 = 29 // MT IP: Multi-Topology IP version 4
|
||||
AddrFamilyMTIPv6 = 30 // MT IPv6: Multi-Topology IP version 6
|
||||
AddrFamilyEIGRPCommonServiceFamily = 16384 // EIGRP Common Service Family
|
||||
AddrFamilyEIGRPIPv4ServiceFamily = 16385 // EIGRP IPv4 Service Family
|
||||
AddrFamilyEIGRPIPv6ServiceFamily = 16386 // EIGRP IPv6 Service Family
|
||||
AddrFamilyLISPCanonicalAddressFormat = 16387 // LISP Canonical Address Format (LCAF)
|
||||
AddrFamilyBGPLS = 16388 // BGP-LS
|
||||
AddrFamily48bitMAC = 16389 // 48-bit MAC
|
||||
AddrFamily64bitMAC = 16390 // 64-bit MAC
|
||||
AddrFamilyOUI = 16391 // OUI
|
||||
AddrFamilyMACFinal24bits = 16392 // MAC/24
|
||||
AddrFamilyMACFinal40bits = 16393 // MAC/40
|
||||
AddrFamilyIPv6Initial64bits = 16394 // IPv6/64
|
||||
AddrFamilyRBridgePortID = 16395 // RBridge Port ID
|
||||
AddrFamilyTRILLNickname = 16396 // TRILL Nickname
|
||||
)
|
||||
11
vendor/golang.org/x/net/internal/socket/cmsghdr.go
generated
vendored
Normal file
11
vendor/golang.org/x/net/internal/socket/cmsghdr.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
|
||||
package socket
|
||||
|
||||
func (h *cmsghdr) len() int { return int(h.Len) }
|
||||
func (h *cmsghdr) lvl() int { return int(h.Level) }
|
||||
func (h *cmsghdr) typ() int { return int(h.Type) }
|
||||
13
vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
generated
vendored
Normal file
13
vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package socket
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||
h.Len = uint32(l)
|
||||
h.Level = int32(lvl)
|
||||
h.Type = int32(typ)
|
||||
}
|
||||
13
vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
generated
vendored
Normal file
13
vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (arm || mips || mipsle || 386 || ppc) && linux
|
||||
|
||||
package socket
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||
h.Len = uint32(l)
|
||||
h.Level = int32(lvl)
|
||||
h.Type = int32(typ)
|
||||
}
|
||||
13
vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
generated
vendored
Normal file
13
vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
|
||||
|
||||
package socket
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||
h.Len = uint64(l)
|
||||
h.Level = int32(lvl)
|
||||
h.Type = int32(typ)
|
||||
}
|
||||
13
vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
generated
vendored
Normal file
13
vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build amd64 && solaris
|
||||
|
||||
package socket
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||
h.Len = uint32(l)
|
||||
h.Level = int32(lvl)
|
||||
h.Type = int32(typ)
|
||||
}
|
||||
27
vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
generated
vendored
Normal file
27
vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
|
||||
|
||||
package socket
|
||||
|
||||
func controlHeaderLen() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func controlMessageLen(dataLen int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func controlMessageSpace(dataLen int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
type cmsghdr struct{}
|
||||
|
||||
func (h *cmsghdr) len() int { return 0 }
|
||||
func (h *cmsghdr) lvl() int { return 0 }
|
||||
func (h *cmsghdr) typ() int { return 0 }
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {}
|
||||
21
vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
generated
vendored
Normal file
21
vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
|
||||
package socket
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
func controlHeaderLen() int {
|
||||
return unix.CmsgLen(0)
|
||||
}
|
||||
|
||||
func controlMessageLen(dataLen int) int {
|
||||
return unix.CmsgLen(dataLen)
|
||||
}
|
||||
|
||||
func controlMessageSpace(dataLen int) int {
|
||||
return unix.CmsgSpace(dataLen)
|
||||
}
|
||||
11
vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go
generated
vendored
Normal file
11
vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
func (h *cmsghdr) set(l, lvl, typ int) {
|
||||
h.Len = int32(l)
|
||||
h.Level = int32(lvl)
|
||||
h.Type = int32(typ)
|
||||
}
|
||||
25
vendor/golang.org/x/net/internal/socket/complete_dontwait.go
generated
vendored
Normal file
25
vendor/golang.org/x/net/internal/socket/complete_dontwait.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// ioComplete checks the flags and result of a syscall, to be used as return
|
||||
// value in a syscall.RawConn.Read or Write callback.
|
||||
func ioComplete(flags int, operr error) bool {
|
||||
if flags&syscall.MSG_DONTWAIT != 0 {
|
||||
// Caller explicitly said don't wait, so always return immediately.
|
||||
return true
|
||||
}
|
||||
if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {
|
||||
// No data available, block for I/O and try again.
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
21
vendor/golang.org/x/net/internal/socket/complete_nodontwait.go
generated
vendored
Normal file
21
vendor/golang.org/x/net/internal/socket/complete_nodontwait.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || windows || zos
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// ioComplete checks the flags and result of a syscall, to be used as return
|
||||
// value in a syscall.RawConn.Read or Write callback.
|
||||
func ioComplete(flags int, operr error) bool {
|
||||
if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {
|
||||
// No data available, block for I/O and try again.
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
7
vendor/golang.org/x/net/internal/socket/empty.s
generated
vendored
Normal file
7
vendor/golang.org/x/net/internal/socket/empty.s
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build darwin && go1.12
|
||||
|
||||
// This exists solely so we can linkname in symbols from syscall.
|
||||
31
vendor/golang.org/x/net/internal/socket/error_unix.go
generated
vendored
Normal file
31
vendor/golang.org/x/net/internal/socket/error_unix.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
|
||||
package socket
|
||||
|
||||
import "syscall"
|
||||
|
||||
var (
|
||||
errEAGAIN error = syscall.EAGAIN
|
||||
errEINVAL error = syscall.EINVAL
|
||||
errENOENT error = syscall.ENOENT
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent allocations
|
||||
// at runtime.
|
||||
func errnoErr(errno syscall.Errno) error {
|
||||
switch errno {
|
||||
case 0:
|
||||
return nil
|
||||
case syscall.EAGAIN:
|
||||
return errEAGAIN
|
||||
case syscall.EINVAL:
|
||||
return errEINVAL
|
||||
case syscall.ENOENT:
|
||||
return errENOENT
|
||||
}
|
||||
return errno
|
||||
}
|
||||
26
vendor/golang.org/x/net/internal/socket/error_windows.go
generated
vendored
Normal file
26
vendor/golang.org/x/net/internal/socket/error_windows.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
import "syscall"
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.ERROR_IO_PENDING
|
||||
errEINVAL error = syscall.EINVAL
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent allocations
|
||||
// at runtime.
|
||||
func errnoErr(errno syscall.Errno) error {
|
||||
switch errno {
|
||||
case 0:
|
||||
return nil
|
||||
case syscall.ERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
case syscall.EINVAL:
|
||||
return errEINVAL
|
||||
}
|
||||
return errno
|
||||
}
|
||||
18
vendor/golang.org/x/net/internal/socket/iovec_32bit.go
generated
vendored
Normal file
18
vendor/golang.org/x/net/internal/socket/iovec_32bit.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (arm || mips || mipsle || 386 || ppc) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd)
|
||||
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (v *iovec) set(b []byte) {
|
||||
l := len(b)
|
||||
if l == 0 {
|
||||
return
|
||||
}
|
||||
v.Base = (*byte)(unsafe.Pointer(&b[0]))
|
||||
v.Len = uint32(l)
|
||||
}
|
||||
18
vendor/golang.org/x/net/internal/socket/iovec_64bit.go
generated
vendored
Normal file
18
vendor/golang.org/x/net/internal/socket/iovec_64bit.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos)
|
||||
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (v *iovec) set(b []byte) {
|
||||
l := len(b)
|
||||
if l == 0 {
|
||||
return
|
||||
}
|
||||
v.Base = (*byte)(unsafe.Pointer(&b[0]))
|
||||
v.Len = uint64(l)
|
||||
}
|
||||
18
vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
generated
vendored
Normal file
18
vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build amd64 && solaris
|
||||
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (v *iovec) set(b []byte) {
|
||||
l := len(b)
|
||||
if l == 0 {
|
||||
return
|
||||
}
|
||||
v.Base = (*int8)(unsafe.Pointer(&b[0]))
|
||||
v.Len = uint64(l)
|
||||
}
|
||||
11
vendor/golang.org/x/net/internal/socket/iovec_stub.go
generated
vendored
Normal file
11
vendor/golang.org/x/net/internal/socket/iovec_stub.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
|
||||
|
||||
package socket
|
||||
|
||||
type iovec struct{}
|
||||
|
||||
func (v *iovec) set(b []byte) {}
|
||||
21
vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
generated
vendored
Normal file
21
vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !aix && !linux && !netbsd
|
||||
|
||||
package socket
|
||||
|
||||
import "net"
|
||||
|
||||
type mmsghdr struct{}
|
||||
|
||||
type mmsghdrs []mmsghdr
|
||||
|
||||
func (hs mmsghdrs) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr) []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {
|
||||
return nil
|
||||
}
|
||||
195
vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
generated
vendored
Normal file
195
vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || linux || netbsd
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type mmsghdrs []mmsghdr
|
||||
|
||||
func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {
|
||||
for i := range hs {
|
||||
ms[i].N = int(hs[i].Len)
|
||||
ms[i].NN = hs[i].Hdr.controllen()
|
||||
ms[i].Flags = hs[i].Hdr.flags()
|
||||
if parseFn != nil {
|
||||
var err error
|
||||
ms[i].Addr, err = parseFn(hs[i].Hdr.name(), hint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// mmsghdrsPacker packs Message-slices into mmsghdrs (re-)using pre-allocated buffers.
|
||||
type mmsghdrsPacker struct {
|
||||
// hs are the pre-allocated mmsghdrs.
|
||||
hs mmsghdrs
|
||||
// sockaddrs is the pre-allocated buffer for the Hdr.Name buffers.
|
||||
// We use one large buffer for all messages and slice it up.
|
||||
sockaddrs []byte
|
||||
// vs are the pre-allocated iovecs.
|
||||
// We allocate one large buffer for all messages and slice it up. This allows to reuse the buffer
|
||||
// if the number of buffers per message is distributed differently between calls.
|
||||
vs []iovec
|
||||
}
|
||||
|
||||
func (p *mmsghdrsPacker) prepare(ms []Message) {
|
||||
n := len(ms)
|
||||
if n <= cap(p.hs) {
|
||||
p.hs = p.hs[:n]
|
||||
} else {
|
||||
p.hs = make(mmsghdrs, n)
|
||||
}
|
||||
if n*sizeofSockaddrInet6 <= cap(p.sockaddrs) {
|
||||
p.sockaddrs = p.sockaddrs[:n*sizeofSockaddrInet6]
|
||||
} else {
|
||||
p.sockaddrs = make([]byte, n*sizeofSockaddrInet6)
|
||||
}
|
||||
|
||||
nb := 0
|
||||
for _, m := range ms {
|
||||
nb += len(m.Buffers)
|
||||
}
|
||||
if nb <= cap(p.vs) {
|
||||
p.vs = p.vs[:nb]
|
||||
} else {
|
||||
p.vs = make([]iovec, nb)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *mmsghdrsPacker) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr, []byte) int) mmsghdrs {
|
||||
p.prepare(ms)
|
||||
hs := p.hs
|
||||
vsRest := p.vs
|
||||
saRest := p.sockaddrs
|
||||
for i := range hs {
|
||||
nvs := len(ms[i].Buffers)
|
||||
vs := vsRest[:nvs]
|
||||
vsRest = vsRest[nvs:]
|
||||
|
||||
var sa []byte
|
||||
if parseFn != nil {
|
||||
sa = saRest[:sizeofSockaddrInet6]
|
||||
saRest = saRest[sizeofSockaddrInet6:]
|
||||
} else if marshalFn != nil {
|
||||
n := marshalFn(ms[i].Addr, saRest)
|
||||
if n > 0 {
|
||||
sa = saRest[:n]
|
||||
saRest = saRest[n:]
|
||||
}
|
||||
}
|
||||
hs[i].Hdr.pack(vs, ms[i].Buffers, ms[i].OOB, sa)
|
||||
}
|
||||
return hs
|
||||
}
|
||||
|
||||
// syscaller is a helper to invoke recvmmsg and sendmmsg via the RawConn.Read/Write interface.
|
||||
// It is reusable, to amortize the overhead of allocating a closure for the function passed to
|
||||
// RawConn.Read/Write.
|
||||
type syscaller struct {
|
||||
n int
|
||||
operr error
|
||||
hs mmsghdrs
|
||||
flags int
|
||||
|
||||
boundRecvmmsgF func(uintptr) bool
|
||||
boundSendmmsgF func(uintptr) bool
|
||||
}
|
||||
|
||||
func (r *syscaller) init() {
|
||||
r.boundRecvmmsgF = r.recvmmsgF
|
||||
r.boundSendmmsgF = r.sendmmsgF
|
||||
}
|
||||
|
||||
func (r *syscaller) recvmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {
|
||||
r.n = 0
|
||||
r.operr = nil
|
||||
r.hs = hs
|
||||
r.flags = flags
|
||||
if err := c.Read(r.boundRecvmmsgF); err != nil {
|
||||
return r.n, err
|
||||
}
|
||||
if r.operr != nil {
|
||||
return r.n, os.NewSyscallError("recvmmsg", r.operr)
|
||||
}
|
||||
return r.n, nil
|
||||
}
|
||||
|
||||
func (r *syscaller) recvmmsgF(s uintptr) bool {
|
||||
r.n, r.operr = recvmmsg(s, r.hs, r.flags)
|
||||
return ioComplete(r.flags, r.operr)
|
||||
}
|
||||
|
||||
func (r *syscaller) sendmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {
|
||||
r.n = 0
|
||||
r.operr = nil
|
||||
r.hs = hs
|
||||
r.flags = flags
|
||||
if err := c.Write(r.boundSendmmsgF); err != nil {
|
||||
return r.n, err
|
||||
}
|
||||
if r.operr != nil {
|
||||
return r.n, os.NewSyscallError("sendmmsg", r.operr)
|
||||
}
|
||||
return r.n, nil
|
||||
}
|
||||
|
||||
func (r *syscaller) sendmmsgF(s uintptr) bool {
|
||||
r.n, r.operr = sendmmsg(s, r.hs, r.flags)
|
||||
return ioComplete(r.flags, r.operr)
|
||||
}
|
||||
|
||||
// mmsgTmps holds reusable temporary helpers for recvmmsg and sendmmsg.
|
||||
type mmsgTmps struct {
|
||||
packer mmsghdrsPacker
|
||||
syscaller syscaller
|
||||
}
|
||||
|
||||
var defaultMmsgTmpsPool = mmsgTmpsPool{
|
||||
p: sync.Pool{
|
||||
New: func() interface{} {
|
||||
tmps := new(mmsgTmps)
|
||||
tmps.syscaller.init()
|
||||
return tmps
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type mmsgTmpsPool struct {
|
||||
p sync.Pool
|
||||
}
|
||||
|
||||
func (p *mmsgTmpsPool) Get() *mmsgTmps {
|
||||
m := p.p.Get().(*mmsgTmps)
|
||||
// Clear fields up to the len (not the cap) of the slice,
|
||||
// assuming that the previous caller only used that many elements.
|
||||
for i := range m.packer.sockaddrs {
|
||||
m.packer.sockaddrs[i] = 0
|
||||
}
|
||||
m.packer.sockaddrs = m.packer.sockaddrs[:0]
|
||||
for i := range m.packer.vs {
|
||||
m.packer.vs[i] = iovec{}
|
||||
}
|
||||
m.packer.vs = m.packer.vs[:0]
|
||||
for i := range m.packer.hs {
|
||||
m.packer.hs[i].Len = 0
|
||||
m.packer.hs[i].Hdr = msghdr{}
|
||||
}
|
||||
m.packer.hs = m.packer.hs[:0]
|
||||
return m
|
||||
}
|
||||
|
||||
func (p *mmsgTmpsPool) Put(tmps *mmsgTmps) {
|
||||
p.p.Put(tmps)
|
||||
}
|
||||
39
vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
generated
vendored
Normal file
39
vendor/golang.org/x/net/internal/socket/msghdr_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
|
||||
for i := range vs {
|
||||
vs[i].set(bs[i])
|
||||
}
|
||||
h.setIov(vs)
|
||||
if len(oob) > 0 {
|
||||
h.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
||||
h.Controllen = uint32(len(oob))
|
||||
}
|
||||
if sa != nil {
|
||||
h.Name = (*byte)(unsafe.Pointer(&sa[0]))
|
||||
h.Namelen = uint32(len(sa))
|
||||
}
|
||||
}
|
||||
|
||||
func (h *msghdr) name() []byte {
|
||||
if h.Name != nil && h.Namelen > 0 {
|
||||
return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *msghdr) controllen() int {
|
||||
return int(h.Controllen)
|
||||
}
|
||||
|
||||
func (h *msghdr) flags() int {
|
||||
return int(h.Flags)
|
||||
}
|
||||
16
vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
generated
vendored
Normal file
16
vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || netbsd
|
||||
|
||||
package socket
|
||||
|
||||
func (h *msghdr) setIov(vs []iovec) {
|
||||
l := len(vs)
|
||||
if l == 0 {
|
||||
return
|
||||
}
|
||||
h.Iov = &vs[0]
|
||||
h.Iovlen = int32(l)
|
||||
}
|
||||
36
vendor/golang.org/x/net/internal/socket/msghdr_linux.go
generated
vendored
Normal file
36
vendor/golang.org/x/net/internal/socket/msghdr_linux.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
|
||||
for i := range vs {
|
||||
vs[i].set(bs[i])
|
||||
}
|
||||
h.setIov(vs)
|
||||
if len(oob) > 0 {
|
||||
h.setControl(oob)
|
||||
}
|
||||
if sa != nil {
|
||||
h.Name = (*byte)(unsafe.Pointer(&sa[0]))
|
||||
h.Namelen = uint32(len(sa))
|
||||
}
|
||||
}
|
||||
|
||||
func (h *msghdr) name() []byte {
|
||||
if h.Name != nil && h.Namelen > 0 {
|
||||
return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *msghdr) controllen() int {
|
||||
return int(h.Controllen)
|
||||
}
|
||||
|
||||
func (h *msghdr) flags() int {
|
||||
return int(h.Flags)
|
||||
}
|
||||
23
vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
generated
vendored
Normal file
23
vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (arm || mips || mipsle || 386 || ppc) && linux
|
||||
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (h *msghdr) setIov(vs []iovec) {
|
||||
l := len(vs)
|
||||
if l == 0 {
|
||||
return
|
||||
}
|
||||
h.Iov = &vs[0]
|
||||
h.Iovlen = uint32(l)
|
||||
}
|
||||
|
||||
func (h *msghdr) setControl(b []byte) {
|
||||
h.Control = (*byte)(unsafe.Pointer(&b[0]))
|
||||
h.Controllen = uint32(len(b))
|
||||
}
|
||||
23
vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
generated
vendored
Normal file
23
vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux
|
||||
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (h *msghdr) setIov(vs []iovec) {
|
||||
l := len(vs)
|
||||
if l == 0 {
|
||||
return
|
||||
}
|
||||
h.Iov = &vs[0]
|
||||
h.Iovlen = uint64(l)
|
||||
}
|
||||
|
||||
func (h *msghdr) setControl(b []byte) {
|
||||
h.Control = (*byte)(unsafe.Pointer(&b[0]))
|
||||
h.Controllen = uint64(len(b))
|
||||
}
|
||||
14
vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go
generated
vendored
Normal file
14
vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
func (h *msghdr) setIov(vs []iovec) {
|
||||
l := len(vs)
|
||||
if l == 0 {
|
||||
return
|
||||
}
|
||||
h.Iov = &vs[0]
|
||||
h.Iovlen = uint32(l)
|
||||
}
|
||||
35
vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
generated
vendored
Normal file
35
vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build amd64 && solaris
|
||||
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
|
||||
for i := range vs {
|
||||
vs[i].set(bs[i])
|
||||
}
|
||||
if len(vs) > 0 {
|
||||
h.Iov = &vs[0]
|
||||
h.Iovlen = int32(len(vs))
|
||||
}
|
||||
if len(oob) > 0 {
|
||||
h.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
|
||||
h.Accrightslen = int32(len(oob))
|
||||
}
|
||||
if sa != nil {
|
||||
h.Name = (*byte)(unsafe.Pointer(&sa[0]))
|
||||
h.Namelen = uint32(len(sa))
|
||||
}
|
||||
}
|
||||
|
||||
func (h *msghdr) controllen() int {
|
||||
return int(h.Accrightslen)
|
||||
}
|
||||
|
||||
func (h *msghdr) flags() int {
|
||||
return int(NativeEndian.Uint32(h.Pad_cgo_2[:]))
|
||||
}
|
||||
14
vendor/golang.org/x/net/internal/socket/msghdr_stub.go
generated
vendored
Normal file
14
vendor/golang.org/x/net/internal/socket/msghdr_stub.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos
|
||||
|
||||
package socket
|
||||
|
||||
type msghdr struct{}
|
||||
|
||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {}
|
||||
func (h *msghdr) name() []byte { return nil }
|
||||
func (h *msghdr) controllen() int { return 0 }
|
||||
func (h *msghdr) flags() int { return 0 }
|
||||
35
vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
generated
vendored
Normal file
35
vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build s390x && zos
|
||||
|
||||
package socket
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {
|
||||
for i := range vs {
|
||||
vs[i].set(bs[i])
|
||||
}
|
||||
if len(vs) > 0 {
|
||||
h.Iov = &vs[0]
|
||||
h.Iovlen = int32(len(vs))
|
||||
}
|
||||
if len(oob) > 0 {
|
||||
h.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
||||
h.Controllen = uint32(len(oob))
|
||||
}
|
||||
if sa != nil {
|
||||
h.Name = (*byte)(unsafe.Pointer(&sa[0]))
|
||||
h.Namelen = uint32(len(sa))
|
||||
}
|
||||
}
|
||||
|
||||
func (h *msghdr) controllen() int {
|
||||
return int(h.Controllen)
|
||||
}
|
||||
|
||||
func (h *msghdr) flags() int {
|
||||
return int(h.Flags)
|
||||
}
|
||||
12
vendor/golang.org/x/net/internal/socket/norace.go
generated
vendored
Normal file
12
vendor/golang.org/x/net/internal/socket/norace.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !race
|
||||
|
||||
package socket
|
||||
|
||||
func (m *Message) raceRead() {
|
||||
}
|
||||
func (m *Message) raceWrite() {
|
||||
}
|
||||
37
vendor/golang.org/x/net/internal/socket/race.go
generated
vendored
Normal file
37
vendor/golang.org/x/net/internal/socket/race.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build race
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// This package reads and writes the Message buffers using a
|
||||
// direct system call, which the race detector can't see.
|
||||
// These functions tell the race detector what is going on during the syscall.
|
||||
|
||||
func (m *Message) raceRead() {
|
||||
for _, b := range m.Buffers {
|
||||
if len(b) > 0 {
|
||||
runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
|
||||
}
|
||||
}
|
||||
if b := m.OOB; len(b) > 0 {
|
||||
runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))
|
||||
}
|
||||
}
|
||||
func (m *Message) raceWrite() {
|
||||
for _, b := range m.Buffers {
|
||||
if len(b) > 0 {
|
||||
runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
|
||||
}
|
||||
}
|
||||
if b := m.OOB; len(b) > 0 {
|
||||
runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))
|
||||
}
|
||||
}
|
||||
91
vendor/golang.org/x/net/internal/socket/rawconn.go
generated
vendored
Normal file
91
vendor/golang.org/x/net/internal/socket/rawconn.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// A Conn represents a raw connection.
|
||||
type Conn struct {
|
||||
network string
|
||||
c syscall.RawConn
|
||||
}
|
||||
|
||||
// tcpConn is an interface implemented by net.TCPConn.
|
||||
// It can be used for interface assertions to check if a net.Conn is a TCP connection.
|
||||
type tcpConn interface {
|
||||
SyscallConn() (syscall.RawConn, error)
|
||||
SetLinger(int) error
|
||||
}
|
||||
|
||||
var _ tcpConn = (*net.TCPConn)(nil)
|
||||
|
||||
// udpConn is an interface implemented by net.UDPConn.
|
||||
// It can be used for interface assertions to check if a net.Conn is a UDP connection.
|
||||
type udpConn interface {
|
||||
SyscallConn() (syscall.RawConn, error)
|
||||
ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
|
||||
}
|
||||
|
||||
var _ udpConn = (*net.UDPConn)(nil)
|
||||
|
||||
// ipConn is an interface implemented by net.IPConn.
|
||||
// It can be used for interface assertions to check if a net.Conn is an IP connection.
|
||||
type ipConn interface {
|
||||
SyscallConn() (syscall.RawConn, error)
|
||||
ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *net.IPAddr, err error)
|
||||
}
|
||||
|
||||
var _ ipConn = (*net.IPConn)(nil)
|
||||
|
||||
// NewConn returns a new raw connection.
|
||||
func NewConn(c net.Conn) (*Conn, error) {
|
||||
var err error
|
||||
var cc Conn
|
||||
switch c := c.(type) {
|
||||
case tcpConn:
|
||||
cc.network = "tcp"
|
||||
cc.c, err = c.SyscallConn()
|
||||
case udpConn:
|
||||
cc.network = "udp"
|
||||
cc.c, err = c.SyscallConn()
|
||||
case ipConn:
|
||||
cc.network = "ip"
|
||||
cc.c, err = c.SyscallConn()
|
||||
default:
|
||||
return nil, errors.New("unknown connection type")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cc, nil
|
||||
}
|
||||
|
||||
func (o *Option) get(c *Conn, b []byte) (int, error) {
|
||||
var operr error
|
||||
var n int
|
||||
fn := func(s uintptr) {
|
||||
n, operr = getsockopt(s, o.Level, o.Name, b)
|
||||
}
|
||||
if err := c.c.Control(fn); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return n, os.NewSyscallError("getsockopt", operr)
|
||||
}
|
||||
|
||||
func (o *Option) set(c *Conn, b []byte) error {
|
||||
var operr error
|
||||
fn := func(s uintptr) {
|
||||
operr = setsockopt(s, o.Level, o.Name, b)
|
||||
}
|
||||
if err := c.c.Control(fn); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.NewSyscallError("setsockopt", operr)
|
||||
}
|
||||
53
vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
generated
vendored
Normal file
53
vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
||||
for i := range ms {
|
||||
ms[i].raceWrite()
|
||||
}
|
||||
tmps := defaultMmsgTmpsPool.Get()
|
||||
defer defaultMmsgTmpsPool.Put(tmps)
|
||||
var parseFn func([]byte, string) (net.Addr, error)
|
||||
if c.network != "tcp" {
|
||||
parseFn = parseInetAddr
|
||||
}
|
||||
hs := tmps.packer.pack(ms, parseFn, nil)
|
||||
n, err := tmps.syscaller.recvmmsg(c.c, hs, flags)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
if err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil {
|
||||
return n, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
|
||||
for i := range ms {
|
||||
ms[i].raceRead()
|
||||
}
|
||||
tmps := defaultMmsgTmpsPool.Get()
|
||||
defer defaultMmsgTmpsPool.Put(tmps)
|
||||
var marshalFn func(net.Addr, []byte) int
|
||||
if c.network != "tcp" {
|
||||
marshalFn = marshalInetAddr
|
||||
}
|
||||
hs := tmps.packer.pack(ms, nil, marshalFn)
|
||||
n, err := tmps.syscaller.sendmmsg(c.c, hs, flags)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
if err := hs[:n].unpack(ms[:n], nil, ""); err != nil {
|
||||
return n, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
59
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
Normal file
59
vendor/golang.org/x/net/internal/socket/rawconn_msg.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||
m.raceWrite()
|
||||
var (
|
||||
operr error
|
||||
n int
|
||||
oobn int
|
||||
recvflags int
|
||||
from net.Addr
|
||||
)
|
||||
fn := func(s uintptr) bool {
|
||||
n, oobn, recvflags, from, operr = recvmsg(s, m.Buffers, m.OOB, flags, c.network)
|
||||
return ioComplete(flags, operr)
|
||||
}
|
||||
if err := c.c.Read(fn); err != nil {
|
||||
return err
|
||||
}
|
||||
if operr != nil {
|
||||
return os.NewSyscallError("recvmsg", operr)
|
||||
}
|
||||
m.Addr = from
|
||||
m.N = n
|
||||
m.NN = oobn
|
||||
m.Flags = recvflags
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) sendMsg(m *Message, flags int) error {
|
||||
m.raceRead()
|
||||
var (
|
||||
operr error
|
||||
n int
|
||||
)
|
||||
fn := func(s uintptr) bool {
|
||||
n, operr = sendmsg(s, m.Buffers, m.OOB, m.Addr, flags)
|
||||
return ioComplete(flags, operr)
|
||||
}
|
||||
if err := c.c.Write(fn); err != nil {
|
||||
return err
|
||||
}
|
||||
if operr != nil {
|
||||
return os.NewSyscallError("sendmsg", operr)
|
||||
}
|
||||
m.N = n
|
||||
m.NN = len(m.OOB)
|
||||
return nil
|
||||
}
|
||||
15
vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
generated
vendored
Normal file
15
vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !linux
|
||||
|
||||
package socket
|
||||
|
||||
func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
|
||||
func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
15
vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
generated
vendored
Normal file
15
vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
|
||||
|
||||
package socket
|
||||
|
||||
func (c *Conn) recvMsg(m *Message, flags int) error {
|
||||
return errNotImplemented
|
||||
}
|
||||
|
||||
func (c *Conn) sendMsg(m *Message, flags int) error {
|
||||
return errNotImplemented
|
||||
}
|
||||
280
vendor/golang.org/x/net/internal/socket/socket.go
generated
vendored
Normal file
280
vendor/golang.org/x/net/internal/socket/socket.go
generated
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package socket provides a portable interface for socket system
|
||||
// calls.
|
||||
package socket // import "golang.org/x/net/internal/socket"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
|
||||
|
||||
// An Option represents a sticky socket option.
|
||||
type Option struct {
|
||||
Level int // level
|
||||
Name int // name; must be equal or greater than 1
|
||||
Len int // length of value in bytes; must be equal or greater than 1
|
||||
}
|
||||
|
||||
// Get reads a value for the option from the kernel.
|
||||
// It returns the number of bytes written into b.
|
||||
func (o *Option) Get(c *Conn, b []byte) (int, error) {
|
||||
if o.Name < 1 || o.Len < 1 {
|
||||
return 0, errors.New("invalid option")
|
||||
}
|
||||
if len(b) < o.Len {
|
||||
return 0, errors.New("short buffer")
|
||||
}
|
||||
return o.get(c, b)
|
||||
}
|
||||
|
||||
// GetInt returns an integer value for the option.
|
||||
//
|
||||
// The Len field of Option must be either 1 or 4.
|
||||
func (o *Option) GetInt(c *Conn) (int, error) {
|
||||
if o.Len != 1 && o.Len != 4 {
|
||||
return 0, errors.New("invalid option")
|
||||
}
|
||||
var b []byte
|
||||
var bb [4]byte
|
||||
if o.Len == 1 {
|
||||
b = bb[:1]
|
||||
} else {
|
||||
b = bb[:4]
|
||||
}
|
||||
n, err := o.get(c, b)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if n != o.Len {
|
||||
return 0, errors.New("invalid option length")
|
||||
}
|
||||
if o.Len == 1 {
|
||||
return int(b[0]), nil
|
||||
}
|
||||
return int(NativeEndian.Uint32(b[:4])), nil
|
||||
}
|
||||
|
||||
// Set writes the option and value to the kernel.
|
||||
func (o *Option) Set(c *Conn, b []byte) error {
|
||||
if o.Name < 1 || o.Len < 1 {
|
||||
return errors.New("invalid option")
|
||||
}
|
||||
if len(b) < o.Len {
|
||||
return errors.New("short buffer")
|
||||
}
|
||||
return o.set(c, b)
|
||||
}
|
||||
|
||||
// SetInt writes the option and value to the kernel.
|
||||
//
|
||||
// The Len field of Option must be either 1 or 4.
|
||||
func (o *Option) SetInt(c *Conn, v int) error {
|
||||
if o.Len != 1 && o.Len != 4 {
|
||||
return errors.New("invalid option")
|
||||
}
|
||||
var b []byte
|
||||
if o.Len == 1 {
|
||||
b = []byte{byte(v)}
|
||||
} else {
|
||||
var bb [4]byte
|
||||
NativeEndian.PutUint32(bb[:o.Len], uint32(v))
|
||||
b = bb[:4]
|
||||
}
|
||||
return o.set(c, b)
|
||||
}
|
||||
|
||||
// ControlMessageSpace returns the whole length of control message.
|
||||
func ControlMessageSpace(dataLen int) int {
|
||||
return controlMessageSpace(dataLen)
|
||||
}
|
||||
|
||||
// A ControlMessage represents the head message in a stream of control
|
||||
// messages.
|
||||
//
|
||||
// A control message comprises of a header, data and a few padding
|
||||
// fields to conform to the interface to the kernel.
|
||||
//
|
||||
// See RFC 3542 for further information.
|
||||
type ControlMessage []byte
|
||||
|
||||
// Data returns the data field of the control message at the head on
|
||||
// m.
|
||||
func (m ControlMessage) Data(dataLen int) []byte {
|
||||
l := controlHeaderLen()
|
||||
if len(m) < l || len(m) < l+dataLen {
|
||||
return nil
|
||||
}
|
||||
return m[l : l+dataLen]
|
||||
}
|
||||
|
||||
// Next returns the control message at the next on m.
|
||||
//
|
||||
// Next works only for standard control messages.
|
||||
func (m ControlMessage) Next(dataLen int) ControlMessage {
|
||||
l := ControlMessageSpace(dataLen)
|
||||
if len(m) < l {
|
||||
return nil
|
||||
}
|
||||
return m[l:]
|
||||
}
|
||||
|
||||
// MarshalHeader marshals the header fields of the control message at
|
||||
// the head on m.
|
||||
func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error {
|
||||
if len(m) < controlHeaderLen() {
|
||||
return errors.New("short message")
|
||||
}
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
h.set(controlMessageLen(dataLen), lvl, typ)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseHeader parses and returns the header fields of the control
|
||||
// message at the head on m.
|
||||
func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) {
|
||||
l := controlHeaderLen()
|
||||
if len(m) < l {
|
||||
return 0, 0, 0, errors.New("short message")
|
||||
}
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil
|
||||
}
|
||||
|
||||
// Marshal marshals the control message at the head on m, and returns
|
||||
// the next control message.
|
||||
func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) {
|
||||
l := len(data)
|
||||
if len(m) < ControlMessageSpace(l) {
|
||||
return nil, errors.New("short message")
|
||||
}
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
h.set(controlMessageLen(l), lvl, typ)
|
||||
if l > 0 {
|
||||
copy(m.Data(l), data)
|
||||
}
|
||||
return m.Next(l), nil
|
||||
}
|
||||
|
||||
// Parse parses m as a single or multiple control messages.
|
||||
//
|
||||
// Parse works for both standard and compatible messages.
|
||||
func (m ControlMessage) Parse() ([]ControlMessage, error) {
|
||||
var ms []ControlMessage
|
||||
for len(m) >= controlHeaderLen() {
|
||||
h := (*cmsghdr)(unsafe.Pointer(&m[0]))
|
||||
l := h.len()
|
||||
if l <= 0 {
|
||||
return nil, errors.New("invalid header length")
|
||||
}
|
||||
if uint64(l) < uint64(controlHeaderLen()) {
|
||||
return nil, errors.New("invalid message length")
|
||||
}
|
||||
if uint64(l) > uint64(len(m)) {
|
||||
return nil, errors.New("short buffer")
|
||||
}
|
||||
// On message reception:
|
||||
//
|
||||
// |<- ControlMessageSpace --------------->|
|
||||
// |<- controlMessageLen ---------->| |
|
||||
// |<- controlHeaderLen ->| | |
|
||||
// +---------------+------+---------+------+
|
||||
// | Header | PadH | Data | PadD |
|
||||
// +---------------+------+---------+------+
|
||||
//
|
||||
// On compatible message reception:
|
||||
//
|
||||
// | ... |<- controlMessageLen ----------->|
|
||||
// | ... |<- controlHeaderLen ->| |
|
||||
// +-----+---------------+------+----------+
|
||||
// | ... | Header | PadH | Data |
|
||||
// +-----+---------------+------+----------+
|
||||
ms = append(ms, ControlMessage(m[:l]))
|
||||
ll := l - controlHeaderLen()
|
||||
if len(m) >= ControlMessageSpace(ll) {
|
||||
m = m[ControlMessageSpace(ll):]
|
||||
} else {
|
||||
m = m[controlMessageLen(ll):]
|
||||
}
|
||||
}
|
||||
return ms, nil
|
||||
}
|
||||
|
||||
// NewControlMessage returns a new stream of control messages.
|
||||
func NewControlMessage(dataLen []int) ControlMessage {
|
||||
var l int
|
||||
for i := range dataLen {
|
||||
l += ControlMessageSpace(dataLen[i])
|
||||
}
|
||||
return make([]byte, l)
|
||||
}
|
||||
|
||||
// A Message represents an IO message.
|
||||
type Message struct {
|
||||
// When writing, the Buffers field must contain at least one
|
||||
// byte to write.
|
||||
// When reading, the Buffers field will always contain a byte
|
||||
// to read.
|
||||
Buffers [][]byte
|
||||
|
||||
// OOB contains protocol-specific control or miscellaneous
|
||||
// ancillary data known as out-of-band data.
|
||||
OOB []byte
|
||||
|
||||
// Addr specifies a destination address when writing.
|
||||
// It can be nil when the underlying protocol of the raw
|
||||
// connection uses connection-oriented communication.
|
||||
// After a successful read, it may contain the source address
|
||||
// on the received packet.
|
||||
Addr net.Addr
|
||||
|
||||
N int // # of bytes read or written from/to Buffers
|
||||
NN int // # of bytes read or written from/to OOB
|
||||
Flags int // protocol-specific information on the received message
|
||||
}
|
||||
|
||||
// RecvMsg wraps recvmsg system call.
|
||||
//
|
||||
// The provided flags is a set of platform-dependent flags, such as
|
||||
// syscall.MSG_PEEK.
|
||||
func (c *Conn) RecvMsg(m *Message, flags int) error {
|
||||
return c.recvMsg(m, flags)
|
||||
}
|
||||
|
||||
// SendMsg wraps sendmsg system call.
|
||||
//
|
||||
// The provided flags is a set of platform-dependent flags, such as
|
||||
// syscall.MSG_DONTROUTE.
|
||||
func (c *Conn) SendMsg(m *Message, flags int) error {
|
||||
return c.sendMsg(m, flags)
|
||||
}
|
||||
|
||||
// RecvMsgs wraps recvmmsg system call.
|
||||
//
|
||||
// It returns the number of processed messages.
|
||||
//
|
||||
// The provided flags is a set of platform-dependent flags, such as
|
||||
// syscall.MSG_PEEK.
|
||||
//
|
||||
// Only Linux supports this.
|
||||
func (c *Conn) RecvMsgs(ms []Message, flags int) (int, error) {
|
||||
return c.recvMsgs(ms, flags)
|
||||
}
|
||||
|
||||
// SendMsgs wraps sendmmsg system call.
|
||||
//
|
||||
// It returns the number of processed messages.
|
||||
//
|
||||
// The provided flags is a set of platform-dependent flags, such as
|
||||
// syscall.MSG_DONTROUTE.
|
||||
//
|
||||
// Only Linux supports this.
|
||||
func (c *Conn) SendMsgs(ms []Message, flags int) (int, error) {
|
||||
return c.sendMsgs(ms, flags)
|
||||
}
|
||||
23
vendor/golang.org/x/net/internal/socket/sys.go
generated
vendored
Normal file
23
vendor/golang.org/x/net/internal/socket/sys.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// NativeEndian is the machine native endian implementation of ByteOrder.
|
||||
var NativeEndian binary.ByteOrder
|
||||
|
||||
func init() {
|
||||
i := uint32(1)
|
||||
b := (*[4]byte)(unsafe.Pointer(&i))
|
||||
if b[0] == 1 {
|
||||
NativeEndian = binary.LittleEndian
|
||||
} else {
|
||||
NativeEndian = binary.BigEndian
|
||||
}
|
||||
}
|
||||
15
vendor/golang.org/x/net/internal/socket/sys_bsd.go
generated
vendored
Normal file
15
vendor/golang.org/x/net/internal/socket/sys_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris
|
||||
|
||||
package socket
|
||||
|
||||
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
|
||||
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
20
vendor/golang.org/x/net/internal/socket/sys_const_unix.go
generated
vendored
Normal file
20
vendor/golang.org/x/net/internal/socket/sys_const_unix.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
|
||||
package socket
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const (
|
||||
sysAF_UNSPEC = unix.AF_UNSPEC
|
||||
sysAF_INET = unix.AF_INET
|
||||
sysAF_INET6 = unix.AF_INET6
|
||||
|
||||
sysSOCK_RAW = unix.SOCK_RAW
|
||||
|
||||
sizeofSockaddrInet4 = unix.SizeofSockaddrInet4
|
||||
sizeofSockaddrInet6 = unix.SizeofSockaddrInet6
|
||||
)
|
||||
22
vendor/golang.org/x/net/internal/socket/sys_linux.go
generated
vendored
Normal file
22
vendor/golang.org/x/net/internal/socket/sys_linux.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && !s390x && !386
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
n, _, errno := syscall.Syscall6(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
|
||||
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
n, _, errno := syscall.Syscall6(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
28
vendor/golang.org/x/net/internal/socket/sys_linux_386.go
generated
vendored
Normal file
28
vendor/golang.org/x/net/internal/socket/sys_linux_386.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x13
|
||||
sysSENDMMSG = 0x14
|
||||
)
|
||||
|
||||
func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
|
||||
func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
|
||||
|
||||
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
|
||||
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
n, errno := socketcall(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
11
vendor/golang.org/x/net/internal/socket/sys_linux_386.s
generated
vendored
Normal file
11
vendor/golang.org/x/net/internal/socket/sys_linux_386.s
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·socketcall(SB),NOSPLIT,$0-36
|
||||
JMP syscall·socketcall(SB)
|
||||
|
||||
TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
|
||||
JMP syscall·rawsocketcall(SB)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x12b
|
||||
sysSENDMMSG = 0x133
|
||||
)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_arm.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_arm.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x16d
|
||||
sysSENDMMSG = 0x176
|
||||
)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0xf3
|
||||
sysSENDMMSG = 0x10d
|
||||
)
|
||||
12
vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go
generated
vendored
Normal file
12
vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build loong64
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0xf3
|
||||
sysSENDMMSG = 0x10d
|
||||
)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_mips.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_mips.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x10ef
|
||||
sysSENDMMSG = 0x10f7
|
||||
)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x14ae
|
||||
sysSENDMMSG = 0x14b6
|
||||
)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x14ae
|
||||
sysSENDMMSG = 0x14b6
|
||||
)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x10ef
|
||||
sysSENDMMSG = 0x10f7
|
||||
)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x157
|
||||
sysSENDMMSG = 0x15d
|
||||
)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x157
|
||||
sysSENDMMSG = 0x15d
|
||||
)
|
||||
10
vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go
generated
vendored
Normal file
10
vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x157
|
||||
sysSENDMMSG = 0x15d
|
||||
)
|
||||
12
vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go
generated
vendored
Normal file
12
vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build riscv64
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0xf3
|
||||
sysSENDMMSG = 0x10d
|
||||
)
|
||||
28
vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go
generated
vendored
Normal file
28
vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x13
|
||||
sysSENDMMSG = 0x14
|
||||
)
|
||||
|
||||
func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
|
||||
func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
|
||||
|
||||
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
|
||||
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
n, errno := socketcall(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
11
vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s
generated
vendored
Normal file
11
vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·socketcall(SB),NOSPLIT,$0-72
|
||||
JMP syscall·socketcall(SB)
|
||||
|
||||
TEXT ·rawsocketcall(SB),NOSPLIT,$0-72
|
||||
JMP syscall·rawsocketcall(SB)
|
||||
25
vendor/golang.org/x/net/internal/socket/sys_netbsd.go
generated
vendored
Normal file
25
vendor/golang.org/x/net/internal/socket/sys_netbsd.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
sysRECVMMSG = 0x1db
|
||||
sysSENDMMSG = 0x1dc
|
||||
)
|
||||
|
||||
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
n, _, errno := syscall.Syscall6(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
|
||||
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
n, _, errno := syscall.Syscall6(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
184
vendor/golang.org/x/net/internal/socket/sys_posix.go
generated
vendored
Normal file
184
vendor/golang.org/x/net/internal/socket/sys_posix.go
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"net"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// marshalInetAddr writes a in sockaddr format into the buffer b.
|
||||
// The buffer must be sufficiently large (sizeofSockaddrInet4/6).
|
||||
// Returns the number of bytes written.
|
||||
func marshalInetAddr(a net.Addr, b []byte) int {
|
||||
switch a := a.(type) {
|
||||
case *net.TCPAddr:
|
||||
return marshalSockaddr(a.IP, a.Port, a.Zone, b)
|
||||
case *net.UDPAddr:
|
||||
return marshalSockaddr(a.IP, a.Port, a.Zone, b)
|
||||
case *net.IPAddr:
|
||||
return marshalSockaddr(a.IP, 0, a.Zone, b)
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func marshalSockaddr(ip net.IP, port int, zone string, b []byte) int {
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
switch runtime.GOOS {
|
||||
case "android", "illumos", "linux", "solaris", "windows":
|
||||
NativeEndian.PutUint16(b[:2], uint16(sysAF_INET))
|
||||
default:
|
||||
b[0] = sizeofSockaddrInet4
|
||||
b[1] = sysAF_INET
|
||||
}
|
||||
binary.BigEndian.PutUint16(b[2:4], uint16(port))
|
||||
copy(b[4:8], ip4)
|
||||
return sizeofSockaddrInet4
|
||||
}
|
||||
if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {
|
||||
switch runtime.GOOS {
|
||||
case "android", "illumos", "linux", "solaris", "windows":
|
||||
NativeEndian.PutUint16(b[:2], uint16(sysAF_INET6))
|
||||
default:
|
||||
b[0] = sizeofSockaddrInet6
|
||||
b[1] = sysAF_INET6
|
||||
}
|
||||
binary.BigEndian.PutUint16(b[2:4], uint16(port))
|
||||
copy(b[8:24], ip6)
|
||||
if zone != "" {
|
||||
NativeEndian.PutUint32(b[24:28], uint32(zoneCache.index(zone)))
|
||||
}
|
||||
return sizeofSockaddrInet6
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func parseInetAddr(b []byte, network string) (net.Addr, error) {
|
||||
if len(b) < 2 {
|
||||
return nil, errors.New("invalid address")
|
||||
}
|
||||
var af int
|
||||
switch runtime.GOOS {
|
||||
case "android", "illumos", "linux", "solaris", "windows":
|
||||
af = int(NativeEndian.Uint16(b[:2]))
|
||||
default:
|
||||
af = int(b[1])
|
||||
}
|
||||
var ip net.IP
|
||||
var zone string
|
||||
if af == sysAF_INET {
|
||||
if len(b) < sizeofSockaddrInet4 {
|
||||
return nil, errors.New("short address")
|
||||
}
|
||||
ip = make(net.IP, net.IPv4len)
|
||||
copy(ip, b[4:8])
|
||||
}
|
||||
if af == sysAF_INET6 {
|
||||
if len(b) < sizeofSockaddrInet6 {
|
||||
return nil, errors.New("short address")
|
||||
}
|
||||
ip = make(net.IP, net.IPv6len)
|
||||
copy(ip, b[8:24])
|
||||
if id := int(NativeEndian.Uint32(b[24:28])); id > 0 {
|
||||
zone = zoneCache.name(id)
|
||||
}
|
||||
}
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
return &net.TCPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil
|
||||
case "udp", "udp4", "udp6":
|
||||
return &net.UDPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil
|
||||
default:
|
||||
return &net.IPAddr{IP: ip, Zone: zone}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// An ipv6ZoneCache represents a cache holding partial network
|
||||
// interface information. It is used for reducing the cost of IPv6
|
||||
// addressing scope zone resolution.
|
||||
//
|
||||
// Multiple names sharing the index are managed by first-come
|
||||
// first-served basis for consistency.
|
||||
type ipv6ZoneCache struct {
|
||||
sync.RWMutex // guard the following
|
||||
lastFetched time.Time // last time routing information was fetched
|
||||
toIndex map[string]int // interface name to its index
|
||||
toName map[int]string // interface index to its name
|
||||
}
|
||||
|
||||
var zoneCache = ipv6ZoneCache{
|
||||
toIndex: make(map[string]int),
|
||||
toName: make(map[int]string),
|
||||
}
|
||||
|
||||
// update refreshes the network interface information if the cache was last
|
||||
// updated more than 1 minute ago, or if force is set. It returns whether the
|
||||
// cache was updated.
|
||||
func (zc *ipv6ZoneCache) update(ift []net.Interface, force bool) (updated bool) {
|
||||
zc.Lock()
|
||||
defer zc.Unlock()
|
||||
now := time.Now()
|
||||
if !force && zc.lastFetched.After(now.Add(-60*time.Second)) {
|
||||
return false
|
||||
}
|
||||
zc.lastFetched = now
|
||||
if len(ift) == 0 {
|
||||
var err error
|
||||
if ift, err = net.Interfaces(); err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
zc.toIndex = make(map[string]int, len(ift))
|
||||
zc.toName = make(map[int]string, len(ift))
|
||||
for _, ifi := range ift {
|
||||
zc.toIndex[ifi.Name] = ifi.Index
|
||||
if _, ok := zc.toName[ifi.Index]; !ok {
|
||||
zc.toName[ifi.Index] = ifi.Name
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (zc *ipv6ZoneCache) name(zone int) string {
|
||||
updated := zoneCache.update(nil, false)
|
||||
zoneCache.RLock()
|
||||
name, ok := zoneCache.toName[zone]
|
||||
zoneCache.RUnlock()
|
||||
if !ok && !updated {
|
||||
zoneCache.update(nil, true)
|
||||
zoneCache.RLock()
|
||||
name, ok = zoneCache.toName[zone]
|
||||
zoneCache.RUnlock()
|
||||
}
|
||||
if !ok { // last resort
|
||||
name = strconv.Itoa(zone)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func (zc *ipv6ZoneCache) index(zone string) int {
|
||||
updated := zoneCache.update(nil, false)
|
||||
zoneCache.RLock()
|
||||
index, ok := zoneCache.toIndex[zone]
|
||||
zoneCache.RUnlock()
|
||||
if !ok && !updated {
|
||||
zoneCache.update(nil, true)
|
||||
zoneCache.RLock()
|
||||
index, ok = zoneCache.toIndex[zone]
|
||||
zoneCache.RUnlock()
|
||||
}
|
||||
if !ok { // last resort
|
||||
index, _ = strconv.Atoi(zone)
|
||||
}
|
||||
return index
|
||||
}
|
||||
52
vendor/golang.org/x/net/internal/socket/sys_stub.go
generated
vendored
Normal file
52
vendor/golang.org/x/net/internal/socket/sys_stub.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos
|
||||
|
||||
package socket
|
||||
|
||||
import "net"
|
||||
|
||||
const (
|
||||
sysAF_UNSPEC = 0x0
|
||||
sysAF_INET = 0x2
|
||||
sysAF_INET6 = 0xa
|
||||
|
||||
sysSOCK_RAW = 0x3
|
||||
|
||||
sizeofSockaddrInet4 = 0x10
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
)
|
||||
|
||||
func marshalInetAddr(ip net.IP, port int, zone string) []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseInetAddr(b []byte, network string) (net.Addr, error) {
|
||||
return nil, errNotImplemented
|
||||
}
|
||||
|
||||
func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
|
||||
func setsockopt(s uintptr, level, name int, b []byte) error {
|
||||
return errNotImplemented
|
||||
}
|
||||
|
||||
func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
|
||||
return 0, 0, 0, nil, errNotImplemented
|
||||
}
|
||||
|
||||
func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
|
||||
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
|
||||
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
121
vendor/golang.org/x/net/internal/socket/sys_unix.go
generated
vendored
Normal file
121
vendor/golang.org/x/net/internal/socket/sys_unix.go
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"net"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
//go:linkname syscall_getsockopt syscall.getsockopt
|
||||
func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32) error
|
||||
|
||||
//go:linkname syscall_setsockopt syscall.setsockopt
|
||||
func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error
|
||||
|
||||
func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
|
||||
l := uint32(len(b))
|
||||
err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)
|
||||
return int(l), err
|
||||
}
|
||||
|
||||
func setsockopt(s uintptr, level, name int, b []byte) error {
|
||||
return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))
|
||||
}
|
||||
|
||||
func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
|
||||
var unixFrom unix.Sockaddr
|
||||
n, oobn, recvflags, unixFrom, err = unix.RecvmsgBuffers(int(s), buffers, oob, flags)
|
||||
if unixFrom != nil {
|
||||
from = sockaddrToAddr(unixFrom, network)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
|
||||
var unixTo unix.Sockaddr
|
||||
if to != nil {
|
||||
unixTo = addrToSockaddr(to)
|
||||
}
|
||||
return unix.SendmsgBuffers(int(s), buffers, oob, unixTo, flags)
|
||||
}
|
||||
|
||||
// addrToSockaddr converts a net.Addr to a unix.Sockaddr.
|
||||
func addrToSockaddr(a net.Addr) unix.Sockaddr {
|
||||
var (
|
||||
ip net.IP
|
||||
port int
|
||||
zone string
|
||||
)
|
||||
switch a := a.(type) {
|
||||
case *net.TCPAddr:
|
||||
ip = a.IP
|
||||
port = a.Port
|
||||
zone = a.Zone
|
||||
case *net.UDPAddr:
|
||||
ip = a.IP
|
||||
port = a.Port
|
||||
zone = a.Zone
|
||||
case *net.IPAddr:
|
||||
ip = a.IP
|
||||
zone = a.Zone
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
sa := unix.SockaddrInet4{Port: port}
|
||||
copy(sa.Addr[:], ip4)
|
||||
return &sa
|
||||
}
|
||||
|
||||
if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {
|
||||
sa := unix.SockaddrInet6{Port: port}
|
||||
copy(sa.Addr[:], ip6)
|
||||
if zone != "" {
|
||||
sa.ZoneId = uint32(zoneCache.index(zone))
|
||||
}
|
||||
return &sa
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sockaddrToAddr converts a unix.Sockaddr to a net.Addr.
|
||||
func sockaddrToAddr(sa unix.Sockaddr, network string) net.Addr {
|
||||
var (
|
||||
ip net.IP
|
||||
port int
|
||||
zone string
|
||||
)
|
||||
switch sa := sa.(type) {
|
||||
case *unix.SockaddrInet4:
|
||||
ip = make(net.IP, net.IPv4len)
|
||||
copy(ip, sa.Addr[:])
|
||||
port = sa.Port
|
||||
case *unix.SockaddrInet6:
|
||||
ip = make(net.IP, net.IPv6len)
|
||||
copy(ip, sa.Addr[:])
|
||||
port = sa.Port
|
||||
if sa.ZoneId > 0 {
|
||||
zone = zoneCache.name(int(sa.ZoneId))
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
return &net.TCPAddr{IP: ip, Port: port, Zone: zone}
|
||||
case "udp", "udp4", "udp6":
|
||||
return &net.UDPAddr{IP: ip, Port: port, Zone: zone}
|
||||
default:
|
||||
return &net.IPAddr{IP: ip, Zone: zone}
|
||||
}
|
||||
}
|
||||
55
vendor/golang.org/x/net/internal/socket/sys_windows.go
generated
vendored
Normal file
55
vendor/golang.org/x/net/internal/socket/sys_windows.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func probeProtocolStack() int {
|
||||
var p uintptr
|
||||
return int(unsafe.Sizeof(p))
|
||||
}
|
||||
|
||||
const (
|
||||
sysAF_UNSPEC = windows.AF_UNSPEC
|
||||
sysAF_INET = windows.AF_INET
|
||||
sysAF_INET6 = windows.AF_INET6
|
||||
|
||||
sysSOCK_RAW = windows.SOCK_RAW
|
||||
|
||||
sizeofSockaddrInet4 = 0x10
|
||||
sizeofSockaddrInet6 = 0x1c
|
||||
)
|
||||
|
||||
func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
|
||||
l := uint32(len(b))
|
||||
err := syscall.Getsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), (*int32)(unsafe.Pointer(&l)))
|
||||
return int(l), err
|
||||
}
|
||||
|
||||
func setsockopt(s uintptr, level, name int, b []byte) error {
|
||||
return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b)))
|
||||
}
|
||||
|
||||
func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
|
||||
return 0, 0, 0, nil, errNotImplemented
|
||||
}
|
||||
|
||||
func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
|
||||
func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
|
||||
func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {
|
||||
return 0, errNotImplemented
|
||||
}
|
||||
66
vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go
generated
vendored
Normal file
66
vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
func probeProtocolStack() int {
|
||||
return 4 // sizeof(int) on GOOS=zos GOARCH=s390x
|
||||
}
|
||||
|
||||
func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
|
||||
l := uint32(len(b))
|
||||
_, _, errno := syscall_syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)
|
||||
return int(l), errnoErr(errno)
|
||||
}
|
||||
|
||||
func setsockopt(s uintptr, level, name int, b []byte) error {
|
||||
_, _, errno := syscall_syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)
|
||||
return errnoErr(errno)
|
||||
}
|
||||
|
||||
func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {
|
||||
var h msghdr
|
||||
vs := make([]iovec, len(buffers))
|
||||
var sa []byte
|
||||
if network != "tcp" {
|
||||
sa = make([]byte, sizeofSockaddrInet6)
|
||||
}
|
||||
h.pack(vs, buffers, oob, sa)
|
||||
sn, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))
|
||||
n = int(sn)
|
||||
oobn = h.controllen()
|
||||
recvflags = h.flags()
|
||||
err = errnoErr(errno)
|
||||
if network != "tcp" {
|
||||
var err2 error
|
||||
from, err2 = parseInetAddr(sa, network)
|
||||
if err2 != nil && err == nil {
|
||||
err = err2
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {
|
||||
var h msghdr
|
||||
vs := make([]iovec, len(buffers))
|
||||
var sa []byte
|
||||
if to != nil {
|
||||
var a [sizeofSockaddrInet6]byte
|
||||
n := marshalInetAddr(to, a[:])
|
||||
sa = a[:n]
|
||||
}
|
||||
h.pack(vs, buffers, oob, sa)
|
||||
n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))
|
||||
return int(n), errnoErr(errno)
|
||||
}
|
||||
11
vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s
generated
vendored
Normal file
11
vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·syscall_syscall(SB),NOSPLIT,$0
|
||||
JMP syscall·_syscall(SB)
|
||||
|
||||
TEXT ·syscall_syscall6(SB),NOSPLIT,$0
|
||||
JMP syscall·_syscall6(SB)
|
||||
39
vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
generated
vendored
Normal file
39
vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_aix.go
|
||||
|
||||
// Added for go1.11 compatibility
|
||||
//go:build aix
|
||||
|
||||
package socket
|
||||
|
||||
type iovec struct {
|
||||
Base *byte
|
||||
Len uint64
|
||||
}
|
||||
|
||||
type msghdr struct {
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Iov *iovec
|
||||
Iovlen int32
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type mmsghdr struct {
|
||||
Hdr msghdr
|
||||
Len uint32
|
||||
Pad_cgo_0 [4]byte
|
||||
}
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofIovec = 0x10
|
||||
sizeofMsghdr = 0x30
|
||||
)
|
||||
32
vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go
generated
vendored
Normal file
32
vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_darwin.go
|
||||
|
||||
package socket
|
||||
|
||||
type iovec struct {
|
||||
Base *byte
|
||||
Len uint64
|
||||
}
|
||||
|
||||
type msghdr struct {
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Pad_cgo_0 [4]byte
|
||||
Iov *iovec
|
||||
Iovlen int32
|
||||
Pad_cgo_1 [4]byte
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofIovec = 0x10
|
||||
sizeofMsghdr = 0x30
|
||||
)
|
||||
32
vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go
generated
vendored
Normal file
32
vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_darwin.go
|
||||
|
||||
package socket
|
||||
|
||||
type iovec struct {
|
||||
Base *byte
|
||||
Len uint64
|
||||
}
|
||||
|
||||
type msghdr struct {
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Pad_cgo_0 [4]byte
|
||||
Iov *iovec
|
||||
Iovlen int32
|
||||
Pad_cgo_1 [4]byte
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofIovec = 0x10
|
||||
sizeofMsghdr = 0x30
|
||||
)
|
||||
32
vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go
generated
vendored
Normal file
32
vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_dragonfly.go
|
||||
|
||||
package socket
|
||||
|
||||
type iovec struct {
|
||||
Base *byte
|
||||
Len uint64
|
||||
}
|
||||
|
||||
type msghdr struct {
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Pad_cgo_0 [4]byte
|
||||
Iov *iovec
|
||||
Iovlen int32
|
||||
Pad_cgo_1 [4]byte
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofIovec = 0x10
|
||||
sizeofMsghdr = 0x30
|
||||
)
|
||||
30
vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go
generated
vendored
Normal file
30
vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package socket
|
||||
|
||||
type iovec struct {
|
||||
Base *byte
|
||||
Len uint32
|
||||
}
|
||||
|
||||
type msghdr struct {
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Iov *iovec
|
||||
Iovlen int32
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofIovec = 0x8
|
||||
sizeofMsghdr = 0x1c
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user