summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/net
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net')
-rw-r--r--vendor/golang.org/x/net/bpf/constants.go3
-rw-r--r--vendor/golang.org/x/net/bpf/instructions.go272
-rw-r--r--vendor/golang.org/x/net/bpf/instructions_test.go375
-rw-r--r--vendor/golang.org/x/net/context/context_test.go40
-rw-r--r--vendor/golang.org/x/net/http2/frame.go29
-rw-r--r--vendor/golang.org/x/net/http2/go18.go9
-rw-r--r--vendor/golang.org/x/net/http2/h2i/h2i.go12
-rw-r--r--vendor/golang.org/x/net/http2/not_go18.go11
-rw-r--r--vendor/golang.org/x/net/http2/server.go131
-rw-r--r--vendor/golang.org/x/net/http2/server_push_test.go59
-rw-r--r--vendor/golang.org/x/net/http2/server_test.go57
-rw-r--r--vendor/golang.org/x/net/http2/transport.go69
-rw-r--r--vendor/golang.org/x/net/http2/transport_test.go177
-rw-r--r--vendor/golang.org/x/net/http2/write.go9
-rw-r--r--vendor/golang.org/x/net/http2/writesched.go14
-rw-r--r--vendor/golang.org/x/net/http2/writesched_priority_test.go2
-rw-r--r--vendor/golang.org/x/net/http2/writesched_random_test.go2
-rw-r--r--vendor/golang.org/x/net/icmp/message.go2
-rw-r--r--vendor/golang.org/x/net/internal/netreflect/socket_test.go71
-rw-r--r--vendor/golang.org/x/net/internal/nettest/stack.go137
-rw-r--r--vendor/golang.org/x/net/ipv4/doc.go10
-rw-r--r--vendor/golang.org/x/net/ipv4/endpoint.go5
-rw-r--r--vendor/golang.org/x/net/ipv4/mocktransponder_test.go21
-rw-r--r--vendor/golang.org/x/net/ipv4/packet.go5
-rw-r--r--vendor/golang.org/x/net/ipv4/payload.go3
-rw-r--r--vendor/golang.org/x/net/ipv4/sys_darwin.go57
-rw-r--r--vendor/golang.org/x/net/ipv4/sys_windows.go1
-rw-r--r--vendor/golang.org/x/net/ipv4/unicastsockopt_test.go21
-rw-r--r--vendor/golang.org/x/net/ipv4/zsys_linux_mips.go146
-rw-r--r--vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go146
-rw-r--r--vendor/golang.org/x/net/ipv6/dgramopt_posix.go2
-rw-r--r--vendor/golang.org/x/net/ipv6/doc.go10
-rw-r--r--vendor/golang.org/x/net/ipv6/endpoint.go5
-rw-r--r--vendor/golang.org/x/net/ipv6/icmp.go3
-rw-r--r--vendor/golang.org/x/net/ipv6/payload.go3
-rw-r--r--vendor/golang.org/x/net/ipv6/unicastsockopt_test.go15
-rw-r--r--vendor/golang.org/x/net/ipv6/zsys_linux_mips.go168
-rw-r--r--vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go168
-rw-r--r--vendor/golang.org/x/net/nettest/conntest.go451
-rw-r--r--vendor/golang.org/x/net/nettest/conntest_go16.go24
-rw-r--r--vendor/golang.org/x/net/nettest/conntest_go17.go24
-rw-r--r--vendor/golang.org/x/net/nettest/conntest_test.go76
-rw-r--r--vendor/golang.org/x/net/trace/events.go20
-rw-r--r--vendor/golang.org/x/net/trace/histogram.go15
-rw-r--r--vendor/golang.org/x/net/trace/trace.go18
-rw-r--r--vendor/golang.org/x/net/trace/trace_test.go14
-rw-r--r--vendor/golang.org/x/net/websocket/websocket.go6
47 files changed, 2625 insertions, 293 deletions
diff --git a/vendor/golang.org/x/net/bpf/constants.go b/vendor/golang.org/x/net/bpf/constants.go
index 2c8bbab7f..ccf6adafb 100644
--- a/vendor/golang.org/x/net/bpf/constants.go
+++ b/vendor/golang.org/x/net/bpf/constants.go
@@ -70,6 +70,9 @@ 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.
diff --git a/vendor/golang.org/x/net/bpf/instructions.go b/vendor/golang.org/x/net/bpf/instructions.go
index 68ae6f549..3b4fd0891 100644
--- a/vendor/golang.org/x/net/bpf/instructions.go
+++ b/vendor/golang.org/x/net/bpf/instructions.go
@@ -57,6 +57,9 @@ func (ri RawInstruction) Disassemble() Instruction {
}
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}
@@ -104,6 +107,14 @@ func (ri RawInstruction) Disassemble() Instruction {
case opJumpAlways:
return Jump{Skip: ri.K}
case opJumpEqual:
+ if ri.Jt == 0 {
+ return JumpIf{
+ Cond: JumpNotEqual,
+ Val: ri.K,
+ SkipTrue: ri.Jf,
+ SkipFalse: 0,
+ }
+ }
return JumpIf{
Cond: JumpEqual,
Val: ri.K,
@@ -111,6 +122,14 @@ func (ri RawInstruction) Disassemble() Instruction {
SkipFalse: ri.Jf,
}
case opJumpGT:
+ if ri.Jt == 0 {
+ return JumpIf{
+ Cond: JumpLessOrEqual,
+ Val: ri.K,
+ SkipTrue: ri.Jf,
+ SkipFalse: 0,
+ }
+ }
return JumpIf{
Cond: JumpGreaterThan,
Val: ri.K,
@@ -118,6 +137,14 @@ func (ri RawInstruction) Disassemble() Instruction {
SkipFalse: ri.Jf,
}
case opJumpGE:
+ if ri.Jt == 0 {
+ return JumpIf{
+ Cond: JumpLessThan,
+ Val: ri.K,
+ SkipTrue: ri.Jf,
+ SkipFalse: 0,
+ }
+ }
return JumpIf{
Cond: JumpGreaterOrEqual,
Val: ri.K,
@@ -171,6 +198,18 @@ func (a LoadConstant) Assemble() (RawInstruction, error) {
return assembleLoad(a.Dst, 4, opAddrModeImmediate, a.Val)
}
+// String returns the 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
@@ -185,6 +224,18 @@ func (a LoadScratch) Assemble() (RawInstruction, error) {
return assembleLoad(a.Dst, 4, opAddrModeScratch, uint32(a.N))
}
+// String returns the 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 {
@@ -197,6 +248,23 @@ func (a LoadAbsolute) Assemble() (RawInstruction, error) {
return assembleLoad(RegA, a.Size, opAddrModeAbsolute, a.Off)
}
+// String returns the 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 {
@@ -209,6 +277,20 @@ func (a LoadIndirect) Assemble() (RawInstruction, error) {
return assembleLoad(RegA, a.Size, opAddrModeIndirect, a.Off)
}
+// String returns the 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.
//
@@ -224,6 +306,11 @@ func (a LoadMemShift) Assemble() (RawInstruction, error) {
return assembleLoad(RegX, 1, opAddrModeMemShift, a.Off)
}
+// String returns the 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 {
@@ -235,7 +322,47 @@ func (a LoadExtension) Assemble() (RawInstruction, error) {
if a.Num == ExtLen {
return assembleLoad(RegA, 4, opAddrModePacketLen, 0)
}
- return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(-0x1000+a.Num))
+ return assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(extOffset+a.Num))
+}
+
+// String returns the 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].
@@ -265,6 +392,18 @@ func (a StoreScratch) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the 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
@@ -279,6 +418,34 @@ func (a ALUOpConstant) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the 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
@@ -291,6 +458,34 @@ func (a ALUOpX) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the 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{}
@@ -301,6 +496,11 @@ func (a NegateA) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the 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
@@ -314,6 +514,11 @@ func (a Jump) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the 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 {
@@ -361,6 +566,51 @@ func (a JumpIf) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the the instruction in assembler notation.
+func (a JumpIf) String() string {
+ switch a.Cond {
+ // K == A
+ case JumpEqual:
+ return conditionalJump(a, "jeq", "jneq")
+ // K != A
+ case JumpNotEqual:
+ return fmt.Sprintf("jneq #%d,%d", a.Val, a.SkipTrue)
+ // K > A
+ case JumpGreaterThan:
+ return conditionalJump(a, "jgt", "jle")
+ // K < A
+ case JumpLessThan:
+ return fmt.Sprintf("jlt #%d,%d", a.Val, a.SkipTrue)
+ // K >= A
+ case JumpGreaterOrEqual:
+ return conditionalJump(a, "jge", "jlt")
+ // K <= A
+ case JumpLessOrEqual:
+ return fmt.Sprintf("jle #%d,%d", a.Val, a.SkipTrue)
+ // K & A != 0
+ case JumpBitsSet:
+ if a.SkipFalse > 0 {
+ return fmt.Sprintf("jset #%d,%d,%d", a.Val, a.SkipTrue, a.SkipFalse)
+ }
+ return fmt.Sprintf("jset #%d,%d", a.Val, a.SkipTrue)
+ // K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips
+ case JumpBitsNotSet:
+ return JumpIf{Cond: JumpBitsSet, SkipTrue: a.SkipFalse, SkipFalse: a.SkipTrue, Val: a.Val}.String()
+ default:
+ return fmt.Sprintf("unknown instruction: %#v", a)
+ }
+}
+
+func conditionalJump(inst JumpIf, positiveJump, negativeJump string) string {
+ if inst.SkipTrue > 0 {
+ if inst.SkipFalse > 0 {
+ return fmt.Sprintf("%s #%d,%d,%d", positiveJump, inst.Val, inst.SkipTrue, inst.SkipFalse)
+ }
+ return fmt.Sprintf("%s #%d,%d", positiveJump, inst.Val, inst.SkipTrue)
+ }
+ return fmt.Sprintf("%s #%d,%d", negativeJump, inst.Val, inst.SkipFalse)
+}
+
// RetA exits the BPF program, returning the value of register A.
type RetA struct{}
@@ -371,6 +621,11 @@ func (a RetA) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the 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
@@ -384,6 +639,11 @@ func (a RetConstant) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the 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{}
@@ -394,6 +654,11 @@ func (a TXA) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the 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{}
@@ -404,6 +669,11 @@ func (a TAX) Assemble() (RawInstruction, error) {
}, nil
}
+// String returns the 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
diff --git a/vendor/golang.org/x/net/bpf/instructions_test.go b/vendor/golang.org/x/net/bpf/instructions_test.go
index 833d1e175..dde474aba 100644
--- a/vendor/golang.org/x/net/bpf/instructions_test.go
+++ b/vendor/golang.org/x/net/bpf/instructions_test.go
@@ -5,6 +5,7 @@
package bpf
import (
+ "fmt"
"io/ioutil"
"reflect"
"strconv"
@@ -143,11 +144,6 @@ func TestInterop(t *testing.T) {
}
// Check that assembly and disassembly match each other.
-//
-// Because we offer "fake" jump conditions that don't appear in the
-// machine code, disassembly won't be a 1:1 match with the original
-// source, although the behavior will be identical. However,
-// reassembling the disassembly should produce an identical program.
func TestAsmDisasm(t *testing.T) {
prog1, err := Assemble(allInstructions)
if err != nil {
@@ -155,30 +151,375 @@ func TestAsmDisasm(t *testing.T) {
}
t.Logf("Assembled program is %d instructions long", len(prog1))
- src, allDecoded := Disassemble(prog1)
+ got, allDecoded := Disassemble(prog1)
if !allDecoded {
t.Errorf("Disassemble(Assemble(allInstructions)) produced unrecognized instructions:")
- for i, inst := range src {
+ for i, inst := range got {
if r, ok := inst.(RawInstruction); ok {
t.Logf(" insn %d, %#v --> %#v", i+1, allInstructions[i], r)
}
}
}
- prog2, err := Assemble(src)
- if err != nil {
- t.Fatalf("assembly of Disassemble(Assemble(allInstructions)) failed: %s", err)
+ if len(allInstructions) != len(got) {
+ t.Fatalf("disassembly changed program size: %d insns before, %d insns after", len(allInstructions), len(got))
}
+ if !reflect.DeepEqual(allInstructions, got) {
+ t.Errorf("program mutated by disassembly:")
+ for i := range got {
+ if !reflect.DeepEqual(allInstructions[i], got[i]) {
+ t.Logf(" insn %d, s: %#v, p1: %#v, got: %#v", i+1, allInstructions[i], prog1[i], got[i])
+ }
+ }
+ }
+}
+
+type InvalidInstruction struct{}
- if len(prog2) != len(prog1) {
- t.Fatalf("disassembly changed program size: %d insns before, %d insns after", len(prog1), len(prog2))
+func (a InvalidInstruction) Assemble() (RawInstruction, error) {
+ return RawInstruction{}, fmt.Errorf("Invalid Instruction")
+}
+
+func (a InvalidInstruction) String() string {
+ return fmt.Sprintf("unknown instruction: %#v", a)
+}
+
+func TestString(t *testing.T) {
+ testCases := []struct {
+ instruction Instruction
+ assembler string
+ }{
+ {
+ instruction: LoadConstant{Dst: RegA, Val: 42},
+ assembler: "ld #42",
+ },
+ {
+ instruction: LoadConstant{Dst: RegX, Val: 42},
+ assembler: "ldx #42",
+ },
+ {
+ instruction: LoadConstant{Dst: 0xffff, Val: 42},
+ assembler: "unknown instruction: bpf.LoadConstant{Dst:0xffff, Val:0x2a}",
+ },
+ {
+ instruction: LoadScratch{Dst: RegA, N: 3},
+ assembler: "ld M[3]",
+ },
+ {
+ instruction: LoadScratch{Dst: RegX, N: 3},
+ assembler: "ldx M[3]",
+ },
+ {
+ instruction: LoadScratch{Dst: 0xffff, N: 3},
+ assembler: "unknown instruction: bpf.LoadScratch{Dst:0xffff, N:3}",
+ },
+ {
+ instruction: LoadAbsolute{Off: 42, Size: 1},
+ assembler: "ldb [42]",
+ },
+ {
+ instruction: LoadAbsolute{Off: 42, Size: 2},
+ assembler: "ldh [42]",
+ },
+ {
+ instruction: LoadAbsolute{Off: 42, Size: 4},
+ assembler: "ld [42]",
+ },
+ {
+ instruction: LoadAbsolute{Off: 42, Size: -1},
+ assembler: "unknown instruction: bpf.LoadAbsolute{Off:0x2a, Size:-1}",
+ },
+ {
+ instruction: LoadIndirect{Off: 42, Size: 1},
+ assembler: "ldb [x + 42]",
+ },
+ {
+ instruction: LoadIndirect{Off: 42, Size: 2},
+ assembler: "ldh [x + 42]",
+ },
+ {
+ instruction: LoadIndirect{Off: 42, Size: 4},
+ assembler: "ld [x + 42]",
+ },
+ {
+ instruction: LoadIndirect{Off: 42, Size: -1},
+ assembler: "unknown instruction: bpf.LoadIndirect{Off:0x2a, Size:-1}",
+ },
+ {
+ instruction: LoadMemShift{Off: 42},
+ assembler: "ldx 4*([42]&0xf)",
+ },
+ {
+ instruction: LoadExtension{Num: ExtLen},
+ assembler: "ld #len",
+ },
+ {
+ instruction: LoadExtension{Num: ExtProto},
+ assembler: "ld #proto",
+ },
+ {
+ instruction: LoadExtension{Num: ExtType},
+ assembler: "ld #type",
+ },
+ {
+ instruction: LoadExtension{Num: ExtPayloadOffset},
+ assembler: "ld #poff",
+ },
+ {
+ instruction: LoadExtension{Num: ExtInterfaceIndex},
+ assembler: "ld #ifidx",
+ },
+ {
+ instruction: LoadExtension{Num: ExtNetlinkAttr},
+ assembler: "ld #nla",
+ },
+ {
+ instruction: LoadExtension{Num: ExtNetlinkAttrNested},
+ assembler: "ld #nlan",
+ },
+ {
+ instruction: LoadExtension{Num: ExtMark},
+ assembler: "ld #mark",
+ },
+ {
+ instruction: LoadExtension{Num: ExtQueue},
+ assembler: "ld #queue",
+ },
+ {
+ instruction: LoadExtension{Num: ExtLinkLayerType},
+ assembler: "ld #hatype",
+ },
+ {
+ instruction: LoadExtension{Num: ExtRXHash},
+ assembler: "ld #rxhash",
+ },
+ {
+ instruction: LoadExtension{Num: ExtCPUID},
+ assembler: "ld #cpu",
+ },
+ {
+ instruction: LoadExtension{Num: ExtVLANTag},
+ assembler: "ld #vlan_tci",
+ },
+ {
+ instruction: LoadExtension{Num: ExtVLANTagPresent},
+ assembler: "ld #vlan_avail",
+ },
+ {
+ instruction: LoadExtension{Num: ExtVLANProto},
+ assembler: "ld #vlan_tpid",
+ },
+ {
+ instruction: LoadExtension{Num: ExtRand},
+ assembler: "ld #rand",
+ },
+ {
+ instruction: LoadAbsolute{Off: 0xfffff038, Size: 4},
+ assembler: "ld #rand",
+ },
+ {
+ instruction: LoadExtension{Num: 0xfff},
+ assembler: "unknown instruction: bpf.LoadExtension{Num:4095}",
+ },
+ {
+ instruction: StoreScratch{Src: RegA, N: 3},
+ assembler: "st M[3]",
+ },
+ {
+ instruction: StoreScratch{Src: RegX, N: 3},
+ assembler: "stx M[3]",
+ },
+ {
+ instruction: StoreScratch{Src: 0xffff, N: 3},
+ assembler: "unknown instruction: bpf.StoreScratch{Src:0xffff, N:3}",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpAdd, Val: 42},
+ assembler: "add #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpSub, Val: 42},
+ assembler: "sub #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpMul, Val: 42},
+ assembler: "mul #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpDiv, Val: 42},
+ assembler: "div #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpOr, Val: 42},
+ assembler: "or #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpAnd, Val: 42},
+ assembler: "and #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpShiftLeft, Val: 42},
+ assembler: "lsh #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpShiftRight, Val: 42},
+ assembler: "rsh #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpMod, Val: 42},
+ assembler: "mod #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: ALUOpXor, Val: 42},
+ assembler: "xor #42",
+ },
+ {
+ instruction: ALUOpConstant{Op: 0xffff, Val: 42},
+ assembler: "unknown instruction: bpf.ALUOpConstant{Op:0xffff, Val:0x2a}",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpAdd},
+ assembler: "add x",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpSub},
+ assembler: "sub x",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpMul},
+ assembler: "mul x",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpDiv},
+ assembler: "div x",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpOr},
+ assembler: "or x",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpAnd},
+ assembler: "and x",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpShiftLeft},
+ assembler: "lsh x",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpShiftRight},
+ assembler: "rsh x",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpMod},
+ assembler: "mod x",
+ },
+ {
+ instruction: ALUOpX{Op: ALUOpXor},
+ assembler: "xor x",
+ },
+ {
+ instruction: ALUOpX{Op: 0xffff},
+ assembler: "unknown instruction: bpf.ALUOpX{Op:0xffff}",
+ },
+ {
+ instruction: NegateA{},
+ assembler: "neg",
+ },
+ {
+ instruction: Jump{Skip: 10},
+ assembler: "ja 10",
+ },
+ {
+ instruction: JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 8, SkipFalse: 9},
+ assembler: "jeq #42,8,9",
+ },
+ {
+ instruction: JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 8},
+ assembler: "jeq #42,8",
+ },
+ {
+ instruction: JumpIf{Cond: JumpEqual, Val: 42, SkipFalse: 8},
+ assembler: "jneq #42,8",
+ },
+ {
+ instruction: JumpIf{Cond: JumpNotEqual, Val: 42, SkipTrue: 8},
+ assembler: "jneq #42,8",
+ },
+ {
+ instruction: JumpIf{Cond: JumpLessThan, Val: 42, SkipTrue: 7},
+ assembler: "jlt #42,7",
+ },
+ {
+ instruction: JumpIf{Cond: JumpLessOrEqual, Val: 42, SkipTrue: 6},
+ assembler: "jle #42,6",
+ },
+ {
+ instruction: JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 4, SkipFalse: 5},
+ assembler: "jgt #42,4,5",
+ },
+ {
+ instruction: JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 4},
+ assembler: "jgt #42,4",
+ },
+ {
+ instruction: JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 3, SkipFalse: 4},
+ assembler: "jge #42,3,4",
+ },
+ {
+ instruction: JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 3},
+ assembler: "jge #42,3",
+ },
+ {
+ instruction: JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 2, SkipFalse: 3},
+ assembler: "jset #42,2,3",
+ },
+ {
+ instruction: JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 2},
+ assembler: "jset #42,2",
+ },
+ {
+ instruction: JumpIf{Cond: JumpBitsNotSet, Val: 42, SkipTrue: 2, SkipFalse: 3},
+ assembler: "jset #42,3,2",
+ },
+ {
+ instruction: JumpIf{Cond: JumpBitsNotSet, Val: 42, SkipTrue: 2},
+ assembler: "jset #42,0,2",
+ },
+ {
+ instruction: JumpIf{Cond: 0xffff, Val: 42, SkipTrue: 1, SkipFalse: 2},
+ assembler: "unknown instruction: bpf.JumpIf{Cond:0xffff, Val:0x2a, SkipTrue:0x1, SkipFalse:0x2}",
+ },
+ {
+ instruction: TAX{},
+ assembler: "tax",
+ },
+ {
+ instruction: TXA{},
+ assembler: "txa",
+ },
+ {
+ instruction: RetA{},
+ assembler: "ret a",
+ },
+ {
+ instruction: RetConstant{Val: 42},
+ assembler: "ret #42",
+ },
+ // Invalid instruction
+ {
+ instruction: InvalidInstruction{},
+ assembler: "unknown instruction: bpf.InvalidInstruction{}",
+ },
}
- if !reflect.DeepEqual(prog1, prog2) {
- t.Errorf("program mutated by disassembly:")
- for i := range prog2 {
- if !reflect.DeepEqual(prog1[i], prog2[i]) {
- t.Logf(" insn %d, s: %#v, p1: %#v, p2: %#v", i+1, allInstructions[i], prog1[i], prog2[i])
+
+ for _, testCase := range testCases {
+ if input, ok := testCase.instruction.(fmt.Stringer); ok {
+ got := input.String()
+ if got != testCase.assembler {
+ t.Errorf("String did not return expected assembler notation, expected: %s, got: %s", testCase.assembler, got)
}
+ } else {
+ t.Errorf("Instruction %#v is not a fmt.Stringer", testCase.instruction)
}
}
}
diff --git a/vendor/golang.org/x/net/context/context_test.go b/vendor/golang.org/x/net/context/context_test.go
index 9554dcf71..62844131b 100644
--- a/vendor/golang.org/x/net/context/context_test.go
+++ b/vendor/golang.org/x/net/context/context_test.go
@@ -243,45 +243,51 @@ func testDeadline(c Context, wait time.Duration, t *testing.T) {
}
func TestDeadline(t *testing.T) {
- c, _ := WithDeadline(Background(), time.Now().Add(100*time.Millisecond))
+ t.Parallel()
+ const timeUnit = 500 * time.Millisecond
+ c, _ := WithDeadline(Background(), time.Now().Add(1*timeUnit))
if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
t.Errorf("c.String() = %q want prefix %q", got, prefix)
}
- testDeadline(c, 200*time.Millisecond, t)
+ testDeadline(c, 2*timeUnit, t)
- c, _ = WithDeadline(Background(), time.Now().Add(100*time.Millisecond))
+ c, _ = WithDeadline(Background(), time.Now().Add(1*timeUnit))
o := otherContext{c}
- testDeadline(o, 200*time.Millisecond, t)
+ testDeadline(o, 2*timeUnit, t)
- c, _ = WithDeadline(Background(), time.Now().Add(100*time.Millisecond))
+ c, _ = WithDeadline(Background(), time.Now().Add(1*timeUnit))
o = otherContext{c}
- c, _ = WithDeadline(o, time.Now().Add(300*time.Millisecond))
- testDeadline(c, 200*time.Millisecond, t)
+ c, _ = WithDeadline(o, time.Now().Add(3*timeUnit))
+ testDeadline(c, 2*timeUnit, t)
}
func TestTimeout(t *testing.T) {
- c, _ := WithTimeout(Background(), 100*time.Millisecond)
+ t.Parallel()
+ const timeUnit = 500 * time.Millisecond
+ c, _ := WithTimeout(Background(), 1*timeUnit)
if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
t.Errorf("c.String() = %q want prefix %q", got, prefix)
}
- testDeadline(c, 200*time.Millisecond, t)
+ testDeadline(c, 2*timeUnit, t)
- c, _ = WithTimeout(Background(), 100*time.Millisecond)
+ c, _ = WithTimeout(Background(), 1*timeUnit)
o := otherContext{c}
- testDeadline(o, 200*time.Millisecond, t)
+ testDeadline(o, 2*timeUnit, t)
- c, _ = WithTimeout(Background(), 100*time.Millisecond)
+ c, _ = WithTimeout(Background(), 1*timeUnit)
o = otherContext{c}
- c, _ = WithTimeout(o, 300*time.Millisecond)
- testDeadline(c, 200*time.Millisecond, t)
+ c, _ = WithTimeout(o, 3*timeUnit)
+ testDeadline(c, 2*timeUnit, t)
}
func TestCanceledTimeout(t *testing.T) {
- c, _ := WithTimeout(Background(), 200*time.Millisecond)
+ t.Parallel()
+ const timeUnit = 500 * time.Millisecond
+ c, _ := WithTimeout(Background(), 2*timeUnit)
o := otherContext{c}
- c, cancel := WithTimeout(o, 400*time.Millisecond)
+ c, cancel := WithTimeout(o, 4*timeUnit)
cancel()
- time.Sleep(100 * time.Millisecond) // let cancelation propagate
+ time.Sleep(1 * timeUnit) // let cancelation propagate
select {
case <-c.Done():
default:
diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go
index b0c79b01a..358833fed 100644
--- a/vendor/golang.org/x/net/http2/frame.go
+++ b/vendor/golang.org/x/net/http2/frame.go
@@ -317,10 +317,12 @@ type Framer struct {
// non-Continuation or Continuation on a different stream is
// attempted to be written.
- logReads bool
+ logReads, logWrites bool
- debugFramer *Framer // only use for logging written writes
- debugFramerBuf *bytes.Buffer
+ debugFramer *Framer // only use for logging written writes
+ debugFramerBuf *bytes.Buffer
+ debugReadLoggerf func(string, ...interface{})
+ debugWriteLoggerf func(string, ...interface{})
}
func (fr *Framer) maxHeaderListSize() uint32 {
@@ -355,7 +357,7 @@ func (f *Framer) endWrite() error {
byte(length>>16),
byte(length>>8),
byte(length))
- if logFrameWrites {
+ if f.logWrites {
f.logWrite()
}
@@ -378,10 +380,10 @@ func (f *Framer) logWrite() {
f.debugFramerBuf.Write(f.wbuf)
fr, err := f.debugFramer.ReadFrame()
if err != nil {
- log.Printf("http2: Framer %p: failed to decode just-written frame", f)
+ f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f)
return
}
- log.Printf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
+ f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
}
func (f *Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) }
@@ -399,9 +401,12 @@ const (
// NewFramer returns a Framer that writes frames to w and reads them from r.
func NewFramer(w io.Writer, r io.Reader) *Framer {
fr := &Framer{
- w: w,
- r: r,
- logReads: logFrameReads,
+ w: w,
+ r: r,
+ logReads: logFrameReads,
+ logWrites: logFrameWrites,
+ debugReadLoggerf: log.Printf,
+ debugWriteLoggerf: log.Printf,
}
fr.getReadBuf = func(size uint32) []byte {
if cap(fr.readBuf) >= int(size) {
@@ -483,7 +488,7 @@ func (fr *Framer) ReadFrame() (Frame, error) {
return nil, err
}
if fr.logReads {
- log.Printf("http2: Framer %p: read %v", fr, summarizeFrame(f))
+ fr.debugReadLoggerf("http2: Framer %p: read %v", fr, summarizeFrame(f))
}
if fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil {
return fr.readMetaFrame(f.(*HeadersFrame))
@@ -1419,8 +1424,8 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
hdec.SetEmitEnabled(true)
hdec.SetMaxStringLength(fr.maxHeaderStringLen())
hdec.SetEmitFunc(func(hf hpack.HeaderField) {
- if VerboseLogs && logFrameReads {
- log.Printf("http2: decoded hpack field %+v", hf)
+ if VerboseLogs && fr.logReads {
+ fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
}
if !httplex.ValidHeaderFieldValue(hf.Value) {
invalid = headerFieldValueError(hf.Value)
diff --git a/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go
index 8c0dd2508..633202c39 100644
--- a/vendor/golang.org/x/net/http2/go18.go
+++ b/vendor/golang.org/x/net/http2/go18.go
@@ -8,6 +8,7 @@ package http2
import (
"crypto/tls"
+ "io"
"net/http"
)
@@ -39,3 +40,11 @@ func configureServer18(h1 *http.Server, h2 *Server) error {
func shouldLogPanic(panicValue interface{}) bool {
return panicValue != nil && panicValue != http.ErrAbortHandler
}
+
+func reqGetBody(req *http.Request) func() (io.ReadCloser, error) {
+ return req.GetBody
+}
+
+func reqBodyIsNoBody(body io.ReadCloser) bool {
+ return body == http.NoBody
+}
diff --git a/vendor/golang.org/x/net/http2/h2i/h2i.go b/vendor/golang.org/x/net/http2/h2i/h2i.go
index 228edf8a4..76c778711 100644
--- a/vendor/golang.org/x/net/http2/h2i/h2i.go
+++ b/vendor/golang.org/x/net/http2/h2i/h2i.go
@@ -88,6 +88,14 @@ func withPort(host string) string {
return host
}
+// withoutPort strips the port from addr if present.
+func withoutPort(addr string) string {
+ if h, _, err := net.SplitHostPort(addr); err == nil {
+ return h
+ }
+ return addr
+}
+
// h2i is the app's state.
type h2i struct {
host string
@@ -134,7 +142,7 @@ func main() {
func (app *h2i) Main() error {
cfg := &tls.Config{
- ServerName: app.host,
+ ServerName: withoutPort(app.host),
NextProtos: strings.Split(*flagNextProto, ","),
InsecureSkipVerify: *flagInsecure,
}
@@ -473,7 +481,7 @@ func (app *h2i) encodeHeaders(req *http.Request) []byte {
host = req.URL.Host
}
- path := req.URL.Path
+ path := req.RequestURI
if path == "" {
path = "/"
}
diff --git a/vendor/golang.org/x/net/http2/not_go18.go b/vendor/golang.org/x/net/http2/not_go18.go
index 2e600dc35..efbf83c32 100644
--- a/vendor/golang.org/x/net/http2/not_go18.go
+++ b/vendor/golang.org/x/net/http2/not_go18.go
@@ -6,7 +6,10 @@
package http2
-import "net/http"
+import (
+ "io"
+ "net/http"
+)
func configureServer18(h1 *http.Server, h2 *Server) error {
// No IdleTimeout to sync prior to Go 1.8.
@@ -16,3 +19,9 @@ func configureServer18(h1 *http.Server, h2 *Server) error {
func shouldLogPanic(panicValue interface{}) bool {
return panicValue != nil
}
+
+func reqGetBody(req *http.Request) func() (io.ReadCloser, error) {
+ return nil
+}
+
+func reqBodyIsNoBody(io.ReadCloser) bool { return false }
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index 0b6b4b08d..3c6b90ccd 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -278,6 +278,16 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
pushEnabled: true,
}
+ // The net/http package sets the write deadline from the
+ // http.Server.WriteTimeout during the TLS handshake, but then
+ // passes the connection off to us with the deadline already
+ // set. Disarm it here so that it is not applied to additional
+ // streams opened on this connection.
+ // TODO: implement WriteTimeout fully. See Issue 18437.
+ if sc.hs.WriteTimeout != 0 {
+ sc.conn.SetWriteDeadline(time.Time{})
+ }
+
if s.NewWriteScheduler != nil {
sc.writeSched = s.NewWriteScheduler()
} else {
@@ -423,6 +433,11 @@ func (sc *serverConn) maxHeaderListSize() uint32 {
return uint32(n + typicalHeaders*perFieldOverhead)
}
+func (sc *serverConn) curOpenStreams() uint32 {
+ sc.serveG.check()
+ return sc.curClientStreams + sc.curPushedStreams
+}
+
// stream represents a stream. This is the minimal metadata needed by
// the serve goroutine. Most of the actual stream state is owned by
// the http.Handler's goroutine in the responseWriter. Because the
@@ -448,8 +463,7 @@ type stream struct {
numTrailerValues int64
weight uint8
state streamState
- sentReset bool // only true once detached from streams map
- gotReset bool // only true once detacted from streams map
+ resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
gotTrailerHeader bool // HEADER frame for trailers was seen
wroteHeaders bool // whether we wrote headers (not status 100)
reqBuf []byte // if non-nil, body pipe buffer to return later at EOF
@@ -753,7 +767,7 @@ func (sc *serverConn) serve() {
fn(loopNum)
}
- if sc.inGoAway && sc.curClientStreams == 0 && !sc.needToSendGoAway && !sc.writingFrame {
+ if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame {
return
}
}
@@ -869,8 +883,34 @@ func (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error {
func (sc *serverConn) writeFrame(wr FrameWriteRequest) {
sc.serveG.check()
+ // If true, wr will not be written and wr.done will not be signaled.
var ignoreWrite bool
+ // We are not allowed to write frames on closed streams. RFC 7540 Section
+ // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
+ // a closed stream." Our server never sends PRIORITY, so that exception
+ // does not apply.
+ //
+ // The serverConn might close an open stream while the stream's handler
+ // is still running. For example, the server might close a stream when it
+ // receives bad data from the client. If this happens, the handler might
+ // attempt to write a frame after the stream has been closed (since the
+ // handler hasn't yet been notified of the close). In this case, we simply
+ // ignore the frame. The handler will notice that the stream is closed when
+ // it waits for the frame to be written.
+ //
+ // As an exception to this rule, we allow sending RST_STREAM after close.
+ // This allows us to immediately reject new streams without tracking any
+ // state for those streams (except for the queued RST_STREAM frame). This
+ // may result in duplicate RST_STREAMs in some cases, but the client should
+ // ignore those.
+ if wr.StreamID() != 0 {
+ _, isReset := wr.write.(StreamError)
+ if state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset {
+ ignoreWrite = true
+ }
+ }
+
// Don't send a 100-continue response if we've already sent headers.
// See golang.org/issue/14030.
switch wr.write.(type) {
@@ -878,6 +918,11 @@ func (sc *serverConn) writeFrame(wr FrameWriteRequest) {
wr.stream.wroteHeaders = true
case write100ContinueHeadersFrame:
if wr.stream.wroteHeaders {
+ // We do not need to notify wr.done because this frame is
+ // never written with wr.done != nil.
+ if wr.done != nil {
+ panic("wr.done != nil for write100ContinueHeadersFrame")
+ }
ignoreWrite = true
}
}
@@ -901,14 +946,15 @@ func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
if st != nil {
switch st.state {
case stateHalfClosedLocal:
- panic("internal error: attempt to send frame on half-closed-local stream")
- case stateClosed:
- if st.sentReset || st.gotReset {
- // Skip this frame.
- sc.scheduleFrameWrite()
- return
+ switch wr.write.(type) {
+ case StreamError, handlerPanicRST, writeWindowUpdate:
+ // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
+ // in this state. (We never send PRIORITY from the server, so that is not checked.)
+ default:
+ panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr))
}
- panic(fmt.Sprintf("internal error: attempt to send a write %v on a closed stream", wr))
+ case stateClosed:
+ panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr))
}
}
if wpp, ok := wr.write.(*writePushPromise); ok {
@@ -916,9 +962,7 @@ func (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {
wpp.promisedID, err = wpp.allocatePromisedID()
if err != nil {
sc.writingFrameAsync = false
- if wr.done != nil {
- wr.done <- err
- }
+ wr.replyToWriter(err)
return
}
}
@@ -951,25 +995,9 @@ func (sc *serverConn) wroteFrame(res frameWriteResult) {
sc.writingFrameAsync = false
wr := res.wr
- st := wr.stream
-
- closeStream := endsStream(wr.write)
-
- if _, ok := wr.write.(handlerPanicRST); ok {
- sc.closeStream(st, errHandlerPanicked)
- }
-
- // Reply (if requested) to the blocked ServeHTTP goroutine.
- if ch := wr.done; ch != nil {
- select {
- case ch <- res.err:
- default:
- panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wr.write))
- }
- }
- wr.write = nil // prevent use (assume it's tainted after wr.done send)
- if closeStream {
+ if writeEndsStream(wr.write) {
+ st := wr.stream
if st == nil {
panic("internal error: expecting non-nil stream")
}
@@ -982,15 +1010,29 @@ func (sc *serverConn) wroteFrame(res frameWriteResult) {
// reading data (see possible TODO at top of
// this file), we go into closed state here
// anyway, after telling the peer we're
- // hanging up on them.
- st.state = stateHalfClosedLocal // won't last long, but necessary for closeStream via resetStream
- errCancel := streamError(st.id, ErrCodeCancel)
- sc.resetStream(errCancel)
+ // hanging up on them. We'll transition to
+ // stateClosed after the RST_STREAM frame is
+ // written.
+ st.state = stateHalfClosedLocal
+ sc.resetStream(streamError(st.id, ErrCodeCancel))
case stateHalfClosedRemote:
sc.closeStream(st, errHandlerComplete)
}
+ } else {
+ switch v := wr.write.(type) {
+ case StreamError:
+ // st may be unknown if the RST_STREAM was generated to reject bad input.
+ if st, ok := sc.streams[v.StreamID]; ok {
+ sc.closeStream(st, v)
+ }
+ case handlerPanicRST:
+ sc.closeStream(wr.stream, errHandlerPanicked)
+ }
}
+ // Reply (if requested) to unblock the ServeHTTP goroutine.
+ wr.replyToWriter(res.err)
+
sc.scheduleFrameWrite()
}
@@ -1087,8 +1129,7 @@ func (sc *serverConn) resetStream(se StreamError) {
sc.serveG.check()
sc.writeFrame(FrameWriteRequest{write: se})
if st, ok := sc.streams[se.StreamID]; ok {
- st.sentReset = true
- sc.closeStream(st, se)
+ st.resetQueued = true
}
}
@@ -1252,7 +1293,6 @@ func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
return ConnectionError(ErrCodeProtocol)
}
if st != nil {
- st.gotReset = true
st.cancelCtx()
sc.closeStream(st, streamError(f.StreamID, f.ErrCode))
}
@@ -1391,7 +1431,7 @@ func (sc *serverConn) processData(f *DataFrame) error {
// type PROTOCOL_ERROR."
return ConnectionError(ErrCodeProtocol)
}
- if st == nil || state != stateOpen || st.gotTrailerHeader {
+ if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {
// This includes sending a RST_STREAM if the stream is
// in stateHalfClosedLocal (which currently means that
// the http.Handler returned, so it's done reading &
@@ -1411,6 +1451,10 @@ func (sc *serverConn) processData(f *DataFrame) error {
sc.inflow.take(int32(f.Length))
sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
+ if st != nil && st.resetQueued {
+ // Already have a stream error in flight. Don't send another.
+ return nil
+ }
return streamError(id, ErrCodeStreamClosed)
}
if st.body == nil {
@@ -1519,6 +1563,11 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
// open, let it process its own HEADERS frame (trailers at this
// point, if it's valid).
if st := sc.streams[f.StreamID]; st != nil {
+ if st.resetQueued {
+ // We're sending RST_STREAM to close the stream, so don't bother
+ // processing this frame.
+ return nil
+ }
return st.processTrailerHeaders(f)
}
@@ -1681,7 +1730,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
} else {
sc.curClientStreams++
}
- if sc.curClientStreams+sc.curPushedStreams == 1 {
+ if sc.curOpenStreams() == 1 {
sc.setConnState(http.StateActive)
}
@@ -2556,7 +2605,7 @@ func (sc *serverConn) startPush(msg startPushRequest) {
scheme: msg.url.Scheme,
authority: msg.url.Host,
path: msg.url.RequestURI(),
- header: msg.header,
+ header: cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
})
if err != nil {
// Should not happen, since we've already validated msg.url.
diff --git a/vendor/golang.org/x/net/http2/server_push_test.go b/vendor/golang.org/x/net/http2/server_push_test.go
index 3fea20870..f70edd3c7 100644
--- a/vendor/golang.org/x/net/http2/server_push_test.go
+++ b/vendor/golang.org/x/net/http2/server_push_test.go
@@ -244,6 +244,50 @@ func TestServer_Push_Success(t *testing.T) {
}
}
+func TestServer_Push_SuccessNoRace(t *testing.T) {
+ // Regression test for issue #18326. Ensure the request handler can mutate
+ // pushed request headers without racing with the PUSH_PROMISE write.
+ errc := make(chan error, 2)
+ st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
+ switch r.URL.RequestURI() {
+ case "/":
+ opt := &http.PushOptions{
+ Header: http.Header{"User-Agent": {"testagent"}},
+ }
+ if err := w.(http.Pusher).Push("/pushed", opt); err != nil {
+ errc <- fmt.Errorf("error pushing: %v", err)
+ return
+ }
+ w.WriteHeader(200)
+ errc <- nil
+
+ case "/pushed":
+ // Update request header, ensure there is no race.
+ r.Header.Set("User-Agent", "newagent")
+ r.Header.Set("Cookie", "cookie")
+ w.WriteHeader(200)
+ errc <- nil
+
+ default:
+ errc <- fmt.Errorf("unknown RequestURL %q", r.URL.RequestURI())
+ }
+ })
+
+ // Send one request, which should push one response.
+ st.greet()
+ getSlash(st)
+ for k := 0; k < 2; k++ {
+ select {
+ case <-time.After(2 * time.Second):
+ t.Errorf("timeout waiting for handler %d to finish", k)
+ case err := <-errc:
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+ }
+}
+
func TestServer_Push_RejectRecursivePush(t *testing.T) {
// Expect two requests, but might get three if there's a bug and the second push succeeds.
errc := make(chan error, 3)
@@ -386,18 +430,20 @@ func TestServer_Push_RejectForbiddenHeader(t *testing.T) {
func TestServer_Push_StateTransitions(t *testing.T) {
const body = "foo"
- startedPromise := make(chan bool)
+ gotPromise := make(chan bool)
finishedPush := make(chan bool)
+
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
switch r.URL.RequestURI() {
case "/":
if err := w.(http.Pusher).Push("/pushed", nil); err != nil {
t.Errorf("Push error: %v", err)
}
- close(startedPromise)
// Don't finish this request until the push finishes so we don't
// nondeterministically interleave output frames with the push.
<-finishedPush
+ case "/pushed":
+ <-gotPromise
}
w.Header().Set("Content-Type", "text/html")
w.Header().Set("Content-Length", strconv.Itoa(len(body)))
@@ -414,11 +460,16 @@ func TestServer_Push_StateTransitions(t *testing.T) {
t.Fatalf("streamState(2)=%v, want %v", got, want)
}
getSlash(st)
- <-startedPromise
+ // After the PUSH_PROMISE is sent, the stream should be stateHalfClosedRemote.
+ st.wantPushPromise()
if got, want := st.streamState(2), stateHalfClosedRemote; got != want {
t.Fatalf("streamState(2)=%v, want %v", got, want)
}
- st.wantPushPromise()
+ // We stall the HTTP handler for "/pushed" until the above check. If we don't
+ // stall the handler, then the handler might write HEADERS and DATA and finish
+ // the stream before we check st.streamState(2) -- should that happen, we'll
+ // see stateClosed and fail the above check.
+ close(gotPromise)
st.wantHeaders()
if df := st.wantData(); !df.StreamEnded() {
t.Fatal("expected END_STREAM flag on DATA")
diff --git a/vendor/golang.org/x/net/http2/server_test.go b/vendor/golang.org/x/net/http2/server_test.go
index 2e6146b67..dfa4cff2e 100644
--- a/vendor/golang.org/x/net/http2/server_test.go
+++ b/vendor/golang.org/x/net/http2/server_test.go
@@ -45,13 +45,22 @@ type serverTester struct {
t testing.TB
ts *httptest.Server
fr *Framer
- logBuf *bytes.Buffer
- logFilter []string // substrings to filter out
- scMu sync.Mutex // guards sc
+ serverLogBuf bytes.Buffer // logger for httptest.Server
+ logFilter []string // substrings to filter out
+ scMu sync.Mutex // guards sc
sc *serverConn
hpackDec *hpack.Decoder
decodedHeaders [][2]string
+ // If http2debug!=2, then we capture Frame debug logs that will be written
+ // to t.Log after a test fails. The read and write logs use separate locks
+ // and buffers so we don't accidentally introduce synchronization between
+ // the read and write goroutines, which may hide data races.
+ frameReadLogMu sync.Mutex
+ frameReadLogBuf bytes.Buffer
+ frameWriteLogMu sync.Mutex
+ frameWriteLogBuf bytes.Buffer
+
// writing headers:
headerBuf bytes.Buffer
hpackEnc *hpack.Encoder
@@ -75,7 +84,6 @@ var optQuiet = serverTesterOpt("quiet_logging")
func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *serverTester {
resetHooks()
- logBuf := new(bytes.Buffer)
ts := httptest.NewUnstartedServer(handler)
tlsConfig := &tls.Config{
@@ -110,9 +118,8 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
ConfigureServer(ts.Config, h2server)
st := &serverTester{
- t: t,
- ts: ts,
- logBuf: logBuf,
+ t: t,
+ ts: ts,
}
st.hpackEnc = hpack.NewEncoder(&st.headerBuf)
st.hpackDec = hpack.NewDecoder(initialHeaderTableSize, st.onHeaderField)
@@ -121,7 +128,7 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
if quiet {
ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
} else {
- ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, logBuf), "", log.LstdFlags)
+ ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, &st.serverLogBuf), "", log.LstdFlags)
}
ts.StartTLS()
@@ -142,6 +149,22 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
}
st.cc = cc
st.fr = NewFramer(cc, cc)
+ if !logFrameReads && !logFrameWrites {
+ st.fr.debugReadLoggerf = func(m string, v ...interface{}) {
+ m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
+ st.frameReadLogMu.Lock()
+ fmt.Fprintf(&st.frameReadLogBuf, m, v...)
+ st.frameReadLogMu.Unlock()
+ }
+ st.fr.debugWriteLoggerf = func(m string, v ...interface{}) {
+ m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
+ st.frameWriteLogMu.Lock()
+ fmt.Fprintf(&st.frameWriteLogBuf, m, v...)
+ st.frameWriteLogMu.Unlock()
+ }
+ st.fr.logReads = true
+ st.fr.logWrites = true
+ }
}
return st
}
@@ -201,6 +224,18 @@ func (st *serverTester) awaitIdle() {
func (st *serverTester) Close() {
if st.t.Failed() {
+ st.frameReadLogMu.Lock()
+ if st.frameReadLogBuf.Len() > 0 {
+ st.t.Logf("Framer read log:\n%s", st.frameReadLogBuf.String())
+ }
+ st.frameReadLogMu.Unlock()
+
+ st.frameWriteLogMu.Lock()
+ if st.frameWriteLogBuf.Len() > 0 {
+ st.t.Logf("Framer write log:\n%s", st.frameWriteLogBuf.String())
+ }
+ st.frameWriteLogMu.Unlock()
+
// If we failed already (and are likely in a Fatal,
// unwindowing), force close the connection, so the
// httptest.Server doesn't wait forever for the conn
@@ -1100,10 +1135,10 @@ func TestServer_RejectsLargeFrames(t *testing.T) {
if gf.ErrCode != ErrCodeFrameSize {
t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFrameSize)
}
- if st.logBuf.Len() != 0 {
+ if st.serverLogBuf.Len() != 0 {
// Previously we spun here for a bit until the GOAWAY disconnect
// timer fired, logging while we fired.
- t.Errorf("unexpected server output: %.500s\n", st.logBuf.Bytes())
+ t.Errorf("unexpected server output: %.500s\n", st.serverLogBuf.Bytes())
}
}
@@ -1227,6 +1262,7 @@ func testServerPostUnblock(t *testing.T,
inHandler <- true
errc <- handler(w, r)
})
+ defer st.Close()
st.greet()
st.writeHeaders(HeadersFrameParam{
StreamID: 1,
@@ -1244,7 +1280,6 @@ func testServerPostUnblock(t *testing.T,
case <-time.After(5 * time.Second):
t.Fatal("timeout waiting for Handler to return")
}
- st.Close()
}
func TestServer_RSTStream_Unblocks_Read(t *testing.T) {
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index 8f5f84412..0c7e859db 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -191,6 +191,7 @@ type clientStream struct {
ID uint32
resc chan resAndError
bufPipe pipe // buffered pipe with the flow-controlled response payload
+ startedWrite bool // started request body write; guarded by cc.mu
requestedGzip bool
on100 func() // optional code to run if get a 100 continue response
@@ -314,6 +315,10 @@ func authorityAddr(scheme string, authority string) (addr string) {
if a, err := idna.ToASCII(host); err == nil {
host = a
}
+ // IPv6 address literal, without a port:
+ if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
+ return host + ":" + port
+ }
return net.JoinHostPort(host, port)
}
@@ -332,8 +337,10 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
}
traceGotConn(req, cc)
res, err := cc.RoundTrip(req)
- if shouldRetryRequest(req, err) {
- continue
+ if err != nil {
+ if req, err = shouldRetryRequest(req, err); err == nil {
+ continue
+ }
}
if err != nil {
t.vlogf("RoundTrip failure: %v", err)
@@ -355,12 +362,41 @@ func (t *Transport) CloseIdleConnections() {
var (
errClientConnClosed = errors.New("http2: client conn is closed")
errClientConnUnusable = errors.New("http2: client conn not usable")
+
+ errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
+ errClientConnGotGoAwayAfterSomeReqBody = errors.New("http2: Transport received Server's graceful shutdown GOAWAY; some request body already written")
)
-func shouldRetryRequest(req *http.Request, err error) bool {
- // TODO: retry GET requests (no bodies) more aggressively, if shutdown
- // before response.
- return err == errClientConnUnusable
+// shouldRetryRequest is called by RoundTrip when a request fails to get
+// response headers. It is always called with a non-nil error.
+// It returns either a request to retry (either the same request, or a
+// modified clone), or an error if the request can't be replayed.
+func shouldRetryRequest(req *http.Request, err error) (*http.Request, error) {
+ switch err {
+ default:
+ return nil, err
+ case errClientConnUnusable, errClientConnGotGoAway:
+ return req, nil
+ case errClientConnGotGoAwayAfterSomeReqBody:
+ // If the Body is nil (or http.NoBody), it's safe to reuse
+ // this request and its Body.
+ if req.Body == nil || reqBodyIsNoBody(req.Body) {
+ return req, nil
+ }
+ // Otherwise we depend on the Request having its GetBody
+ // func defined.
+ getBody := reqGetBody(req) // Go 1.8: getBody = req.GetBody
+ if getBody == nil {
+ return nil, errors.New("http2: Transport: peer server initiated graceful shutdown after some of Request.Body was written; define Request.GetBody to avoid this error")
+ }
+ body, err := getBody()
+ if err != nil {
+ return nil, err
+ }
+ newReq := *req
+ newReq.Body = body
+ return &newReq, nil
+ }
}
func (t *Transport) dialClientConn(addr string, singleUse bool) (*ClientConn, error) {
@@ -513,6 +549,15 @@ func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
if old != nil && old.ErrCode != ErrCodeNo {
cc.goAway.ErrCode = old.ErrCode
}
+ last := f.LastStreamID
+ for streamID, cs := range cc.streams {
+ if streamID > last {
+ select {
+ case cs.resc <- resAndError{err: errClientConnGotGoAway}:
+ default:
+ }
+ }
+ }
}
func (cc *ClientConn) CanTakeNewRequest() bool {
@@ -613,8 +658,6 @@ func commaSeparatedTrailers(req *http.Request) (string, error) {
}
if len(keys) > 0 {
sort.Strings(keys)
- // TODO: could do better allocation-wise here, but trailers are rare,
- // so being lazy for now.
return strings.Join(keys, ","), nil
}
return "", nil
@@ -773,6 +816,13 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
cs.abortRequestBodyWrite(errStopReqBodyWrite)
}
if re.err != nil {
+ if re.err == errClientConnGotGoAway {
+ cc.mu.Lock()
+ if cs.startedWrite {
+ re.err = errClientConnGotGoAwayAfterSomeReqBody
+ }
+ cc.mu.Unlock()
+ }
cc.forgetStreamID(cs.ID)
return nil, re.err
}
@@ -2013,6 +2063,9 @@ func (t *Transport) getBodyWriterState(cs *clientStream, body io.Reader) (s body
resc := make(chan error, 1)
s.resc = resc
s.fn = func() {
+ cs.cc.mu.Lock()
+ cs.startedWrite = true
+ cs.cc.mu.Unlock()
resc <- cs.writeRequestBody(body, cs.req.Body)
}
s.delay = t.expectContinueTimeout()
diff --git a/vendor/golang.org/x/net/http2/transport_test.go b/vendor/golang.org/x/net/http2/transport_test.go
index f9287e575..8ef4f3388 100644
--- a/vendor/golang.org/x/net/http2/transport_test.go
+++ b/vendor/golang.org/x/net/http2/transport_test.go
@@ -2073,10 +2073,11 @@ func TestTransportHandlerBodyClose(t *testing.T) {
// https://golang.org/issue/15930
func TestTransportFlowControl(t *testing.T) {
- const (
- total = 100 << 20 // 100MB
- bufLen = 1 << 16
- )
+ const bufLen = 64 << 10
+ var total int64 = 100 << 20 // 100MB
+ if testing.Short() {
+ total = 10 << 20
+ }
var wrote int64 // updated atomically
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
@@ -2745,3 +2746,171 @@ func TestTransportCancelDataResponseRace(t *testing.T) {
t.Errorf("Got = %q; want %q", slurp, msg)
}
}
+
+func TestTransportRetryAfterGOAWAY(t *testing.T) {
+ var dialer struct {
+ sync.Mutex
+ count int
+ }
+ ct1 := make(chan *clientTester)
+ ct2 := make(chan *clientTester)
+
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ tr := &Transport{
+ TLSClientConfig: tlsConfigInsecure,
+ }
+ tr.DialTLS = func(network, addr string, cfg *tls.Config) (net.Conn, error) {
+ dialer.Lock()
+ defer dialer.Unlock()
+ dialer.count++
+ if dialer.count == 3 {
+ return nil, errors.New("unexpected number of dials")
+ }
+ cc, err := net.Dial("tcp", ln.Addr().String())
+ if err != nil {
+ return nil, fmt.Errorf("dial error: %v", err)
+ }
+ sc, err := ln.Accept()
+ if err != nil {
+ return nil, fmt.Errorf("accept error: %v", err)
+ }
+ ct := &clientTester{
+ t: t,
+ tr: tr,
+ cc: cc,
+ sc: sc,
+ fr: NewFramer(sc, sc),
+ }
+ switch dialer.count {
+ case 1:
+ ct1 <- ct
+ case 2:
+ ct2 <- ct
+ }
+ return cc, nil
+ }
+
+ errs := make(chan error, 3)
+ done := make(chan struct{})
+ defer close(done)
+
+ // Client.
+ go func() {
+ req, _ := http.NewRequest("GET", "https://dummy.tld/", nil)
+ res, err := tr.RoundTrip(req)
+ if res != nil {
+ res.Body.Close()
+ if got := res.Header.Get("Foo"); got != "bar" {
+ err = fmt.Errorf("foo header = %q; want bar", got)
+ }
+ }
+ if err != nil {
+ err = fmt.Errorf("RoundTrip: %v", err)
+ }
+ errs <- err
+ }()
+
+ connToClose := make(chan io.Closer, 2)
+
+ // Server for the first request.
+ go func() {
+ var ct *clientTester
+ select {
+ case ct = <-ct1:
+ case <-done:
+ return
+ }
+
+ connToClose <- ct.cc
+ ct.greet()
+ hf, err := ct.firstHeaders()
+ if err != nil {
+ errs <- fmt.Errorf("server1 failed reading HEADERS: %v", err)
+ return
+ }
+ t.Logf("server1 got %v", hf)
+ if err := ct.fr.WriteGoAway(0 /*max id*/, ErrCodeNo, nil); err != nil {
+ errs <- fmt.Errorf("server1 failed writing GOAWAY: %v", err)
+ return
+ }
+ errs <- nil
+ }()
+
+ // Server for the second request.
+ go func() {
+ var ct *clientTester
+ select {
+ case ct = <-ct2:
+ case <-done:
+ return
+ }
+
+ connToClose <- ct.cc
+ ct.greet()
+ hf, err := ct.firstHeaders()
+ if err != nil {
+ errs <- fmt.Errorf("server2 failed reading HEADERS: %v", err)
+ return
+ }
+ t.Logf("server2 got %v", hf)
+
+ var buf bytes.Buffer
+ enc := hpack.NewEncoder(&buf)
+ enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
+ enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"})
+ err = ct.fr.WriteHeaders(HeadersFrameParam{
+ StreamID: hf.StreamID,
+ EndHeaders: true,
+ EndStream: false,
+ BlockFragment: buf.Bytes(),
+ })
+ if err != nil {
+ errs <- fmt.Errorf("server2 failed writing response HEADERS: %v", err)
+ } else {
+ errs <- nil
+ }
+ }()
+
+ for k := 0; k < 3; k++ {
+ select {
+ case err := <-errs:
+ if err != nil {
+ t.Error(err)
+ }
+ case <-time.After(1 * time.Second):
+ t.Errorf("timed out")
+ }
+ }
+
+ for {
+ select {
+ case c := <-connToClose:
+ c.Close()
+ default:
+ return
+ }
+ }
+}
+
+func TestAuthorityAddr(t *testing.T) {
+ tests := []struct {
+ scheme, authority string
+ want string
+ }{
+ {"http", "foo.com", "foo.com:80"},
+ {"https", "foo.com", "foo.com:443"},
+ {"https", "foo.com:1234", "foo.com:1234"},
+ {"https", "1.2.3.4:1234", "1.2.3.4:1234"},
+ {"https", "1.2.3.4", "1.2.3.4:443"},
+ {"https", "[::1]:1234", "[::1]:1234"},
+ {"https", "[::1]", "[::1]:443"},
+ }
+ for _, tt := range tests {
+ got := authorityAddr(tt.scheme, tt.authority)
+ if got != tt.want {
+ t.Errorf("authorityAddr(%q, %q) = %q; want %q", tt.scheme, tt.authority, got, tt.want)
+ }
+ }
+}
diff --git a/vendor/golang.org/x/net/http2/write.go b/vendor/golang.org/x/net/http2/write.go
index 1c135fdf7..6b0dfae31 100644
--- a/vendor/golang.org/x/net/http2/write.go
+++ b/vendor/golang.org/x/net/http2/write.go
@@ -45,9 +45,10 @@ type writeContext interface {
HeaderEncoder() (*hpack.Encoder, *bytes.Buffer)
}
-// endsStream reports whether the given frame writer w will locally
-// close the stream.
-func endsStream(w writeFramer) bool {
+// writeEndsStream reports whether w writes a frame that will transition
+// the stream to a half-closed local state. This returns false for RST_STREAM,
+// which closes the entire stream (not just the local half).
+func writeEndsStream(w writeFramer) bool {
switch v := w.(type) {
case *writeData:
return v.endStream
@@ -57,7 +58,7 @@ func endsStream(w writeFramer) bool {
// This can only happen if the caller reuses w after it's
// been intentionally nil'ed out to prevent use. Keep this
// here to catch future refactoring breaking it.
- panic("endsStream called on nil writeFramer")
+ panic("writeEndsStream called on nil writeFramer")
}
return false
}
diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go
index caa77c7cb..4fe307307 100644
--- a/vendor/golang.org/x/net/http2/writesched.go
+++ b/vendor/golang.org/x/net/http2/writesched.go
@@ -160,6 +160,20 @@ func (wr FrameWriteRequest) String() string {
return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", wr.StreamID(), wr.done != nil, des)
}
+// replyToWriter sends err to wr.done and panics if the send must block
+// This does nothing if wr.done is nil.
+func (wr *FrameWriteRequest) replyToWriter(err error) {
+ if wr.done == nil {
+ return
+ }
+ select {
+ case wr.done <- err:
+ default:
+ panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wr.write))
+ }
+ wr.write = nil // prevent use (assume it's tainted after wr.done send)
+}
+
// writeQueue is used by implementations of WriteScheduler.
type writeQueue struct {
s []FrameWriteRequest
diff --git a/vendor/golang.org/x/net/http2/writesched_priority_test.go b/vendor/golang.org/x/net/http2/writesched_priority_test.go
index 2b232043c..f2b535a2c 100644
--- a/vendor/golang.org/x/net/http2/writesched_priority_test.go
+++ b/vendor/golang.org/x/net/http2/writesched_priority_test.go
@@ -434,7 +434,7 @@ func TestPriorityFlowControl(t *testing.T) {
t.Fatalf("Pop(%d)=false, want true", i)
}
if got, want := wr.DataSize(), 8; got != want {
- t.Fatalf("Pop(%d)=%d bytes, want %d bytes", got, want)
+ t.Fatalf("Pop(%d)=%d bytes, want %d bytes", i, got, want)
}
}
}
diff --git a/vendor/golang.org/x/net/http2/writesched_random_test.go b/vendor/golang.org/x/net/http2/writesched_random_test.go
index 97b0bcdbf..3bf4aa36a 100644
--- a/vendor/golang.org/x/net/http2/writesched_random_test.go
+++ b/vendor/golang.org/x/net/http2/writesched_random_test.go
@@ -30,7 +30,7 @@ func TestRandomScheduler(t *testing.T) {
t.Fatalf("got %d frames, expected 6", len(order))
}
if order[0].StreamID() != 0 || order[1].StreamID() != 0 {
- t.Fatalf("expected non-stream frames first", order[0], order[1])
+ t.Fatal("expected non-stream frames first", order[0], order[1])
}
got := make(map[uint32]bool)
for _, wr := range order[2:] {
diff --git a/vendor/golang.org/x/net/icmp/message.go b/vendor/golang.org/x/net/icmp/message.go
index ea01bba38..81140b0df 100644
--- a/vendor/golang.org/x/net/icmp/message.go
+++ b/vendor/golang.org/x/net/icmp/message.go
@@ -24,6 +24,8 @@ import (
"golang.org/x/net/ipv6"
)
+// BUG(mikio): This package is not implemented on NaCl and Plan 9.
+
var (
errMessageTooShort = errors.New("message too short")
errHeaderTooShort = errors.New("header too short")
diff --git a/vendor/golang.org/x/net/internal/netreflect/socket_test.go b/vendor/golang.org/x/net/internal/netreflect/socket_test.go
index 305665ac1..49b97ed54 100644
--- a/vendor/golang.org/x/net/internal/netreflect/socket_test.go
+++ b/vendor/golang.org/x/net/internal/netreflect/socket_test.go
@@ -5,76 +5,20 @@
package netreflect_test
import (
- "fmt"
- "io/ioutil"
"net"
"os"
- "runtime"
"testing"
"golang.org/x/net/internal/netreflect"
+ "golang.org/x/net/internal/nettest"
)
-func localPath() string {
- f, err := ioutil.TempFile("", "netreflect")
- if err != nil {
- panic(err)
- }
- path := f.Name()
- f.Close()
- os.Remove(path)
- return path
-}
-
-func newLocalListener(network string) (net.Listener, error) {
- switch network {
- case "tcp":
- if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
- return ln, nil
- }
- return net.Listen("tcp6", "[::1]:0")
- case "tcp4":
- return net.Listen("tcp4", "127.0.0.1:0")
- case "tcp6":
- return net.Listen("tcp6", "[::1]:0")
- case "unix", "unixpacket":
- return net.Listen(network, localPath())
- }
- return nil, fmt.Errorf("%s is not supported", network)
-}
-
-func newLocalPacketListener(network string) (net.PacketConn, error) {
- switch network {
- case "udp":
- if c, err := net.ListenPacket("udp4", "127.0.0.1:0"); err == nil {
- return c, nil
- }
- return net.ListenPacket("udp6", "[::1]:0")
- case "udp4":
- return net.ListenPacket("udp4", "127.0.0.1:0")
- case "udp6":
- return net.ListenPacket("udp6", "[::1]:0")
- case "unixgram":
- return net.ListenPacket(network, localPath())
- }
- return nil, fmt.Errorf("%s is not supported", network)
-}
-
func TestSocketOf(t *testing.T) {
for _, network := range []string{"tcp", "unix", "unixpacket"} {
- switch runtime.GOOS {
- case "darwin":
- if network == "unixpacket" {
- continue
- }
- case "nacl", "plan9":
+ if !nettest.TestableNetwork(network) {
continue
- case "windows":
- if network == "unix" || network == "unixpacket" {
- continue
- }
}
- ln, err := newLocalListener(network)
+ ln, err := nettest.NewLocalListener(network)
if err != nil {
t.Error(err)
continue
@@ -101,15 +45,10 @@ func TestSocketOf(t *testing.T) {
func TestPacketSocketOf(t *testing.T) {
for _, network := range []string{"udp", "unixgram"} {
- switch runtime.GOOS {
- case "nacl", "plan9":
+ if !nettest.TestableNetwork(network) {
continue
- case "windows":
- if network == "unixgram" {
- continue
- }
}
- c, err := newLocalPacketListener(network)
+ c, err := nettest.NewLocalPacketListener(network)
if err != nil {
t.Error(err)
continue
diff --git a/vendor/golang.org/x/net/internal/nettest/stack.go b/vendor/golang.org/x/net/internal/nettest/stack.go
index 5ab95305d..cc92c035b 100644
--- a/vendor/golang.org/x/net/internal/nettest/stack.go
+++ b/vendor/golang.org/x/net/internal/nettest/stack.go
@@ -2,35 +2,40 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package nettest provides utilities for IP testing.
+// Package nettest provides utilities for network testing.
package nettest // import "golang.org/x/net/internal/nettest"
-import "net"
+import (
+ "fmt"
+ "io/ioutil"
+ "net"
+ "os"
+ "runtime"
+)
-// SupportsIPv4 reports whether the platform supports IPv4 networking
-// functionality.
-func SupportsIPv4() bool {
- ln, err := net.Listen("tcp4", "127.0.0.1:0")
- if err != nil {
- return false
+var (
+ supportsIPv4 bool
+ supportsIPv6 bool
+)
+
+func init() {
+ if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
+ ln.Close()
+ supportsIPv4 = true
+ }
+ if ln, err := net.Listen("tcp6", "[::1]:0"); err == nil {
+ ln.Close()
+ supportsIPv6 = true
}
- ln.Close()
- return true
}
+// SupportsIPv4 reports whether the platform supports IPv4 networking
+// functionality.
+func SupportsIPv4() bool { return supportsIPv4 }
+
// SupportsIPv6 reports whether the platform supports IPv6 networking
// functionality.
-func SupportsIPv6() bool {
- if causesIPv6Crash() {
- return false
- }
- ln, err := net.Listen("tcp6", "[::1]:0")
- if err != nil {
- return false
- }
- ln.Close()
- return true
-}
+func SupportsIPv6() bool { return supportsIPv6 }
// SupportsRawIPSocket reports whether the platform supports raw IP
// sockets.
@@ -50,3 +55,93 @@ func SupportsIPv6MulticastDeliveryOnLoopback() bool {
func ProtocolNotSupported(err error) bool {
return protocolNotSupported(err)
}
+
+// TestableNetwork reports whether network is testable on the current
+// platform configuration.
+func TestableNetwork(network string) bool {
+ // This is based on logic from standard library's
+ // net/platform_test.go.
+ switch network {
+ case "unix", "unixgram":
+ switch runtime.GOOS {
+ case "android", "nacl", "plan9", "windows":
+ return false
+ }
+ if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
+ return false
+ }
+ case "unixpacket":
+ switch runtime.GOOS {
+ case "android", "darwin", "freebsd", "nacl", "plan9", "windows":
+ return false
+ }
+ }
+ return true
+}
+
+// NewLocalListener returns a listener which listens to a loopback IP
+// address or local file system path.
+// Network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
+func NewLocalListener(network string) (net.Listener, error) {
+ switch network {
+ case "tcp":
+ if supportsIPv4 {
+ if ln, err := net.Listen("tcp4", "127.0.0.1:0"); err == nil {
+ return ln, nil
+ }
+ }
+ if supportsIPv6 {
+ return net.Listen("tcp6", "[::1]:0")
+ }
+ case "tcp4":
+ if supportsIPv4 {
+ return net.Listen("tcp4", "127.0.0.1:0")
+ }
+ case "tcp6":
+ if supportsIPv6 {
+ return net.Listen("tcp6", "[::1]:0")
+ }
+ case "unix", "unixpacket":
+ return net.Listen(network, localPath())
+ }
+ return nil, fmt.Errorf("%s is not supported", network)
+}
+
+// NewLocalPacketListener returns a packet listener which listens to a
+// loopback IP address or local file system path.
+// Network must be "udp", "udp4", "udp6" or "unixgram".
+func NewLocalPacketListener(network string) (net.PacketConn, error) {
+ switch network {
+ case "udp":
+ if supportsIPv4 {
+ if c, err := net.ListenPacket("udp4", "127.0.0.1:0"); err == nil {
+ return c, nil
+ }
+ }
+ if supportsIPv6 {
+ return net.ListenPacket("udp6", "[::1]:0")
+ }
+ case "udp4":
+ if supportsIPv4 {
+ return net.ListenPacket("udp4", "127.0.0.1:0")
+ }
+ case "udp6":
+ if supportsIPv6 {
+ return net.ListenPacket("udp6", "[::1]:0")
+ }
+ case "unixgram":
+ return net.ListenPacket(network, localPath())
+ }
+ return nil, fmt.Errorf("%s is not supported", network)
+}
+
+func localPath() string {
+ f, err := ioutil.TempFile("", "nettest")
+ if err != nil {
+ panic(err)
+ }
+ path := f.Name()
+ f.Close()
+ os.Remove(path)
+ return path
+}
diff --git a/vendor/golang.org/x/net/ipv4/doc.go b/vendor/golang.org/x/net/ipv4/doc.go
index 7b25ea2ee..b4ce40fbc 100644
--- a/vendor/golang.org/x/net/ipv4/doc.go
+++ b/vendor/golang.org/x/net/ipv4/doc.go
@@ -23,8 +23,8 @@
// net.UDPConn and net.IPConn which are created as network connections
// that use the IPv4 transport. When a single TCP connection carrying
// a data flow of multiple packets needs to indicate the flow is
-// important, ipv4.Conn is used to set the type-of-service field on
-// the IPv4 header for each packet.
+// important, Conn is used to set the type-of-service field on the
+// IPv4 header for each packet.
//
// ln, err := net.Listen("tcp4", "0.0.0.0:1024")
// if err != nil {
@@ -96,8 +96,8 @@
// The application might set per packet control message transmissions
// between the protocol stack within the kernel. When the application
// needs a destination address on an incoming packet,
-// SetControlMessage of ipv4.PacketConn is used to enable control
-// message transmissions.
+// SetControlMessage of PacketConn is used to enable control message
+// transmissions.
//
// if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil {
// // error handling
@@ -240,3 +240,5 @@
// In the fallback case, ExcludeSourceSpecificGroup and
// IncludeSourceSpecificGroup may return an error.
package ipv4 // import "golang.org/x/net/ipv4"
+
+// BUG(mikio): This package is not implemented on NaCl and Plan 9.
diff --git a/vendor/golang.org/x/net/ipv4/endpoint.go b/vendor/golang.org/x/net/ipv4/endpoint.go
index dc7557b66..01c4e399b 100644
--- a/vendor/golang.org/x/net/ipv4/endpoint.go
+++ b/vendor/golang.org/x/net/ipv4/endpoint.go
@@ -12,6 +12,11 @@ import (
"golang.org/x/net/internal/netreflect"
)
+// BUG(mikio): On Windows, the JoinSourceSpecificGroup,
+// LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and
+// IncludeSourceSpecificGroup methods of PacketConn and RawConn are
+// not implemented.
+
// A Conn represents a network endpoint that uses the IPv4 transport.
// It is used to control basic IP-level socket options such as TOS and
// TTL.
diff --git a/vendor/golang.org/x/net/ipv4/mocktransponder_test.go b/vendor/golang.org/x/net/ipv4/mocktransponder_test.go
deleted file mode 100644
index e96c48af8..000000000
--- a/vendor/golang.org/x/net/ipv4/mocktransponder_test.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2012 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 ipv4_test
-
-import (
- "net"
- "testing"
-)
-
-func acceptor(t *testing.T, ln net.Listener, done chan<- bool) {
- defer func() { done <- true }()
-
- c, err := ln.Accept()
- if err != nil {
- t.Error(err)
- return
- }
- c.Close()
-}
diff --git a/vendor/golang.org/x/net/ipv4/packet.go b/vendor/golang.org/x/net/ipv4/packet.go
index a4ff8159b..7f3bf4898 100644
--- a/vendor/golang.org/x/net/ipv4/packet.go
+++ b/vendor/golang.org/x/net/ipv4/packet.go
@@ -9,6 +9,9 @@ import (
"syscall"
)
+// BUG(mikio): On Windows, the ReadFrom and WriteTo methods of RawConn
+// are not implemented.
+
// A packetHandler represents the IPv4 datagram handler.
type packetHandler struct {
c *net.IPConn
@@ -61,7 +64,7 @@ func slicePacket(b []byte) (h, p []byte, err error) {
//
// The IPv4 header h must contain appropriate fields that include:
//
-// Version = ipv4.Version
+// Version = <must be specified>
// Len = <must be specified>
// TOS = <must be specified>
// TotalLen = <must be specified>
diff --git a/vendor/golang.org/x/net/ipv4/payload.go b/vendor/golang.org/x/net/ipv4/payload.go
index 25ca8a5fb..be130e424 100644
--- a/vendor/golang.org/x/net/ipv4/payload.go
+++ b/vendor/golang.org/x/net/ipv4/payload.go
@@ -6,6 +6,9 @@ package ipv4
import "net"
+// BUG(mikio): On Windows, the ControlMessage for ReadFrom and WriteTo
+// methods of PacketConn is not implemented.
+
// A payloadHandler represents the IPv4 datagram payload handler.
type payloadHandler struct {
net.PacketConn
diff --git a/vendor/golang.org/x/net/ipv4/sys_darwin.go b/vendor/golang.org/x/net/ipv4/sys_darwin.go
index bc694141c..abfffca87 100644
--- a/vendor/golang.org/x/net/ipv4/sys_darwin.go
+++ b/vendor/golang.org/x/net/ipv4/sys_darwin.go
@@ -6,6 +6,8 @@ package ipv4
import (
"net"
+ "strconv"
+ "strings"
"syscall"
"unsafe"
)
@@ -36,41 +38,40 @@ var (
func init() {
// Seems like kern.osreldate is veiled on latest OS X. We use
// kern.osrelease instead.
- osver, err := syscall.Sysctl("kern.osrelease")
+ s, err := syscall.Sysctl("kern.osrelease")
if err != nil {
return
}
- var i int
- for i = range osver {
- if osver[i] == '.' {
- break
- }
+ ss := strings.Split(s, ".")
+ if len(ss) == 0 {
+ return
}
// The IP_PKTINFO and protocol-independent multicast API were
- // introduced in OS X 10.7 (Darwin 11.0.0). But it looks like
- // those features require OS X 10.8 (Darwin 12.0.0) and above.
+ // introduced in OS X 10.7 (Darwin 11). But it looks like
+ // those features require OS X 10.8 (Darwin 12) or above.
// See http://support.apple.com/kb/HT1633.
- if i > 2 || i == 2 && osver[0] >= '1' && osver[1] >= '2' {
- ctlOpts[ctlPacketInfo].name = sysIP_PKTINFO
- ctlOpts[ctlPacketInfo].length = sizeofInetPktinfo
- ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo
- ctlOpts[ctlPacketInfo].parse = parsePacketInfo
- sockOpts[ssoPacketInfo].name = sysIP_RECVPKTINFO
- sockOpts[ssoPacketInfo].typ = ssoTypeInt
- sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn
- sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP
- sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq
- sockOpts[ssoLeaveGroup].name = sysMCAST_LEAVE_GROUP
- sockOpts[ssoLeaveGroup].typ = ssoTypeGroupReq
- sockOpts[ssoJoinSourceGroup].name = sysMCAST_JOIN_SOURCE_GROUP
- sockOpts[ssoJoinSourceGroup].typ = ssoTypeGroupSourceReq
- sockOpts[ssoLeaveSourceGroup].name = sysMCAST_LEAVE_SOURCE_GROUP
- sockOpts[ssoLeaveSourceGroup].typ = ssoTypeGroupSourceReq
- sockOpts[ssoBlockSourceGroup].name = sysMCAST_BLOCK_SOURCE
- sockOpts[ssoBlockSourceGroup].typ = ssoTypeGroupSourceReq
- sockOpts[ssoUnblockSourceGroup].name = sysMCAST_UNBLOCK_SOURCE
- sockOpts[ssoUnblockSourceGroup].typ = ssoTypeGroupSourceReq
+ if mjver, err := strconv.Atoi(ss[0]); err != nil || mjver < 12 {
+ return
}
+ ctlOpts[ctlPacketInfo].name = sysIP_PKTINFO
+ ctlOpts[ctlPacketInfo].length = sizeofInetPktinfo
+ ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo
+ ctlOpts[ctlPacketInfo].parse = parsePacketInfo
+ sockOpts[ssoPacketInfo].name = sysIP_RECVPKTINFO
+ sockOpts[ssoPacketInfo].typ = ssoTypeInt
+ sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn
+ sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP
+ sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq
+ sockOpts[ssoLeaveGroup].name = sysMCAST_LEAVE_GROUP
+ sockOpts[ssoLeaveGroup].typ = ssoTypeGroupReq
+ sockOpts[ssoJoinSourceGroup].name = sysMCAST_JOIN_SOURCE_GROUP
+ sockOpts[ssoJoinSourceGroup].typ = ssoTypeGroupSourceReq
+ sockOpts[ssoLeaveSourceGroup].name = sysMCAST_LEAVE_SOURCE_GROUP
+ sockOpts[ssoLeaveSourceGroup].typ = ssoTypeGroupSourceReq
+ sockOpts[ssoBlockSourceGroup].name = sysMCAST_BLOCK_SOURCE
+ sockOpts[ssoBlockSourceGroup].typ = ssoTypeGroupSourceReq
+ sockOpts[ssoUnblockSourceGroup].name = sysMCAST_UNBLOCK_SOURCE
+ sockOpts[ssoUnblockSourceGroup].typ = ssoTypeGroupSourceReq
}
func (pi *inetPktinfo) setIfindex(i int) {
diff --git a/vendor/golang.org/x/net/ipv4/sys_windows.go b/vendor/golang.org/x/net/ipv4/sys_windows.go
index 3f4c5357b..fac00bda8 100644
--- a/vendor/golang.org/x/net/ipv4/sys_windows.go
+++ b/vendor/golang.org/x/net/ipv4/sys_windows.go
@@ -51,6 +51,7 @@ var (
ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeInt},
ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt},
+ ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt},
ssoJoinGroup: {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq},
ssoLeaveGroup: {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq},
}
diff --git a/vendor/golang.org/x/net/ipv4/unicastsockopt_test.go b/vendor/golang.org/x/net/ipv4/unicastsockopt_test.go
index b047e51f9..db5213b91 100644
--- a/vendor/golang.org/x/net/ipv4/unicastsockopt_test.go
+++ b/vendor/golang.org/x/net/ipv4/unicastsockopt_test.go
@@ -16,7 +16,7 @@ import (
func TestConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
@@ -30,8 +30,15 @@ func TestConnUnicastSocketOptions(t *testing.T) {
}
defer ln.Close()
- done := make(chan bool)
- go acceptor(t, ln, done)
+ errc := make(chan error, 1)
+ go func() {
+ c, err := ln.Accept()
+ if err != nil {
+ errc <- err
+ return
+ }
+ errc <- c.Close()
+ }()
c, err := net.Dial("tcp4", ln.Addr().String())
if err != nil {
@@ -41,7 +48,9 @@ func TestConnUnicastSocketOptions(t *testing.T) {
testUnicastSocketOptions(t, ipv4.NewConn(c))
- <-done
+ if err := <-errc; err != nil {
+ t.Errorf("server: %v", err)
+ }
}
var packetConnUnicastSocketOptionTests = []struct {
@@ -53,7 +62,7 @@ var packetConnUnicastSocketOptionTests = []struct {
func TestPacketConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
@@ -79,7 +88,7 @@ func TestPacketConnUnicastSocketOptions(t *testing.T) {
func TestRawConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
- case "nacl", "plan9":
+ case "nacl", "plan9", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go
new file mode 100644
index 000000000..4da672013
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go
@@ -0,0 +1,146 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sysIP_TOS = 0x1
+ sysIP_TTL = 0x2
+ sysIP_HDRINCL = 0x3
+ sysIP_OPTIONS = 0x4
+ sysIP_ROUTER_ALERT = 0x5
+ sysIP_RECVOPTS = 0x6
+ sysIP_RETOPTS = 0x7
+ sysIP_PKTINFO = 0x8
+ sysIP_PKTOPTIONS = 0x9
+ sysIP_MTU_DISCOVER = 0xa
+ sysIP_RECVERR = 0xb
+ sysIP_RECVTTL = 0xc
+ sysIP_RECVTOS = 0xd
+ sysIP_MTU = 0xe
+ sysIP_FREEBIND = 0xf
+ sysIP_TRANSPARENT = 0x13
+ sysIP_RECVRETOPTS = 0x7
+ sysIP_ORIGDSTADDR = 0x14
+ sysIP_RECVORIGDSTADDR = 0x14
+ sysIP_MINTTL = 0x15
+ sysIP_NODEFRAG = 0x16
+ sysIP_UNICAST_IF = 0x32
+
+ sysIP_MULTICAST_IF = 0x20
+ sysIP_MULTICAST_TTL = 0x21
+ sysIP_MULTICAST_LOOP = 0x22
+ sysIP_ADD_MEMBERSHIP = 0x23
+ sysIP_DROP_MEMBERSHIP = 0x24
+ sysIP_UNBLOCK_SOURCE = 0x25
+ sysIP_BLOCK_SOURCE = 0x26
+ sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
+ sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
+ sysIP_MSFILTER = 0x29
+ sysMCAST_JOIN_GROUP = 0x2a
+ sysMCAST_LEAVE_GROUP = 0x2d
+ sysMCAST_JOIN_SOURCE_GROUP = 0x2e
+ sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
+ sysMCAST_BLOCK_SOURCE = 0x2b
+ sysMCAST_UNBLOCK_SOURCE = 0x2c
+ sysMCAST_MSFILTER = 0x30
+ sysIP_MULTICAST_ALL = 0x31
+
+ sysICMP_FILTER = 0x1
+
+ sysSO_EE_ORIGIN_NONE = 0x0
+ sysSO_EE_ORIGIN_LOCAL = 0x1
+ sysSO_EE_ORIGIN_ICMP = 0x2
+ sysSO_EE_ORIGIN_ICMP6 = 0x3
+ sysSO_EE_ORIGIN_TXSTATUS = 0x4
+ sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
+
+ sysSOL_SOCKET = 0x1
+ sysSO_ATTACH_FILTER = 0x1a
+
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqn = 0xc
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqn struct {
+ Multiaddr [4]byte /* in_addr */
+ Address [4]byte /* in_addr */
+ Ifindex int32
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
+
+type sockFProg struct {
+ Len uint16
+ Pad_cgo_0 [2]byte
+ Filter *sockFilter
+}
+
+type sockFilter struct {
+ Code uint16
+ Jt uint8
+ Jf uint8
+ K uint32
+}
diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go
new file mode 100644
index 000000000..4da672013
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go
@@ -0,0 +1,146 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_linux.go
+
+package ipv4
+
+const (
+ sysIP_TOS = 0x1
+ sysIP_TTL = 0x2
+ sysIP_HDRINCL = 0x3
+ sysIP_OPTIONS = 0x4
+ sysIP_ROUTER_ALERT = 0x5
+ sysIP_RECVOPTS = 0x6
+ sysIP_RETOPTS = 0x7
+ sysIP_PKTINFO = 0x8
+ sysIP_PKTOPTIONS = 0x9
+ sysIP_MTU_DISCOVER = 0xa
+ sysIP_RECVERR = 0xb
+ sysIP_RECVTTL = 0xc
+ sysIP_RECVTOS = 0xd
+ sysIP_MTU = 0xe
+ sysIP_FREEBIND = 0xf
+ sysIP_TRANSPARENT = 0x13
+ sysIP_RECVRETOPTS = 0x7
+ sysIP_ORIGDSTADDR = 0x14
+ sysIP_RECVORIGDSTADDR = 0x14
+ sysIP_MINTTL = 0x15
+ sysIP_NODEFRAG = 0x16
+ sysIP_UNICAST_IF = 0x32
+
+ sysIP_MULTICAST_IF = 0x20
+ sysIP_MULTICAST_TTL = 0x21
+ sysIP_MULTICAST_LOOP = 0x22
+ sysIP_ADD_MEMBERSHIP = 0x23
+ sysIP_DROP_MEMBERSHIP = 0x24
+ sysIP_UNBLOCK_SOURCE = 0x25
+ sysIP_BLOCK_SOURCE = 0x26
+ sysIP_ADD_SOURCE_MEMBERSHIP = 0x27
+ sysIP_DROP_SOURCE_MEMBERSHIP = 0x28
+ sysIP_MSFILTER = 0x29
+ sysMCAST_JOIN_GROUP = 0x2a
+ sysMCAST_LEAVE_GROUP = 0x2d
+ sysMCAST_JOIN_SOURCE_GROUP = 0x2e
+ sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
+ sysMCAST_BLOCK_SOURCE = 0x2b
+ sysMCAST_UNBLOCK_SOURCE = 0x2c
+ sysMCAST_MSFILTER = 0x30
+ sysIP_MULTICAST_ALL = 0x31
+
+ sysICMP_FILTER = 0x1
+
+ sysSO_EE_ORIGIN_NONE = 0x0
+ sysSO_EE_ORIGIN_LOCAL = 0x1
+ sysSO_EE_ORIGIN_ICMP = 0x2
+ sysSO_EE_ORIGIN_ICMP6 = 0x3
+ sysSO_EE_ORIGIN_TXSTATUS = 0x4
+ sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
+
+ sysSOL_SOCKET = 0x1
+ sysSO_ATTACH_FILTER = 0x1a
+
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet = 0x10
+ sizeofInetPktinfo = 0xc
+ sizeofSockExtendedErr = 0x10
+
+ sizeofIPMreq = 0x8
+ sizeofIPMreqn = 0xc
+ sizeofIPMreqSource = 0xc
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPFilter = 0x4
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type inetPktinfo struct {
+ Ifindex int32
+ Spec_dst [4]byte /* in_addr */
+ Addr [4]byte /* in_addr */
+}
+
+type sockExtendedErr struct {
+ Errno uint32
+ Origin uint8
+ Type uint8
+ Code uint8
+ Pad uint8
+ Info uint32
+ Data uint32
+}
+
+type ipMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type ipMreqn struct {
+ Multiaddr [4]byte /* in_addr */
+ Address [4]byte /* in_addr */
+ Ifindex int32
+}
+
+type ipMreqSource struct {
+ Multiaddr uint32
+ Interface uint32
+ Sourceaddr uint32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpFilter struct {
+ Data uint32
+}
+
+type sockFProg struct {
+ Len uint16
+ Pad_cgo_0 [2]byte
+ Filter *sockFilter
+}
+
+type sockFilter struct {
+ Code uint16
+ Jt uint8
+ Jf uint8
+ K uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/dgramopt_posix.go b/vendor/golang.org/x/net/ipv6/dgramopt_posix.go
index 46f7f2ffb..571430848 100644
--- a/vendor/golang.org/x/net/ipv6/dgramopt_posix.go
+++ b/vendor/golang.org/x/net/ipv6/dgramopt_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux netbsd openbsd windows solaris
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
package ipv6
diff --git a/vendor/golang.org/x/net/ipv6/doc.go b/vendor/golang.org/x/net/ipv6/doc.go
index 78a779c4e..88383e915 100644
--- a/vendor/golang.org/x/net/ipv6/doc.go
+++ b/vendor/golang.org/x/net/ipv6/doc.go
@@ -24,8 +24,8 @@
// net.UDPConn and net.IPConn which are created as network connections
// that use the IPv6 transport. When a single TCP connection carrying
// a data flow of multiple packets needs to indicate the flow is
-// important, ipv6.Conn is used to set the traffic class field on the
-// IPv6 header for each packet.
+// important, Conn is used to set the traffic class field on the IPv6
+// header for each packet.
//
// ln, err := net.Listen("tcp6", "[::]:1024")
// if err != nil {
@@ -97,8 +97,8 @@
// The application might set per packet control message transmissions
// between the protocol stack within the kernel. When the application
// needs a destination address on an incoming packet,
-// SetControlMessage of ipv6.PacketConn is used to enable control
-// message transmissions.
+// SetControlMessage of PacketConn is used to enable control message
+// transmissions.
//
// if err := p.SetControlMessage(ipv6.FlagDst, true); err != nil {
// // error handling
@@ -239,3 +239,5 @@
// In the fallback case, ExcludeSourceSpecificGroup and
// IncludeSourceSpecificGroup may return an error.
package ipv6 // import "golang.org/x/net/ipv6"
+
+// BUG(mikio): This package is not implemented on NaCl and Plan 9.
diff --git a/vendor/golang.org/x/net/ipv6/endpoint.go b/vendor/golang.org/x/net/ipv6/endpoint.go
index b988782a9..f6a68ab41 100644
--- a/vendor/golang.org/x/net/ipv6/endpoint.go
+++ b/vendor/golang.org/x/net/ipv6/endpoint.go
@@ -12,6 +12,11 @@ import (
"golang.org/x/net/internal/netreflect"
)
+// BUG(mikio): On Windows, the JoinSourceSpecificGroup,
+// LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and
+// IncludeSourceSpecificGroup methods of PacketConn are not
+// implemented.
+
// A Conn represents a network endpoint that uses IPv6 transport.
// It allows to set basic IP-level socket options such as traffic
// class and hop limit.
diff --git a/vendor/golang.org/x/net/ipv6/icmp.go b/vendor/golang.org/x/net/ipv6/icmp.go
index df9e4fbe3..ff21d1071 100644
--- a/vendor/golang.org/x/net/ipv6/icmp.go
+++ b/vendor/golang.org/x/net/ipv6/icmp.go
@@ -6,6 +6,9 @@ package ipv6
import "golang.org/x/net/internal/iana"
+// BUG(mikio): On Windows, methods related to ICMPFilter are not
+// implemented.
+
// An ICMPType represents a type of ICMP message.
type ICMPType int
diff --git a/vendor/golang.org/x/net/ipv6/payload.go b/vendor/golang.org/x/net/ipv6/payload.go
index 682ff22f2..d9f822510 100644
--- a/vendor/golang.org/x/net/ipv6/payload.go
+++ b/vendor/golang.org/x/net/ipv6/payload.go
@@ -6,6 +6,9 @@ package ipv6
import "net"
+// BUG(mikio): On Windows, the ControlMessage for ReadFrom and WriteTo
+// methods of PacketConn is not implemented.
+
// A payloadHandler represents the IPv6 datagram payload handler.
type payloadHandler struct {
net.PacketConn
diff --git a/vendor/golang.org/x/net/ipv6/unicastsockopt_test.go b/vendor/golang.org/x/net/ipv6/unicastsockopt_test.go
index 1c52b3d30..e175dccf5 100644
--- a/vendor/golang.org/x/net/ipv6/unicastsockopt_test.go
+++ b/vendor/golang.org/x/net/ipv6/unicastsockopt_test.go
@@ -29,8 +29,15 @@ func TestConnUnicastSocketOptions(t *testing.T) {
}
defer ln.Close()
- done := make(chan bool)
- go acceptor(t, ln, done)
+ errc := make(chan error, 1)
+ go func() {
+ c, err := ln.Accept()
+ if err != nil {
+ errc <- err
+ return
+ }
+ errc <- c.Close()
+ }()
c, err := net.Dial("tcp6", ln.Addr().String())
if err != nil {
@@ -40,7 +47,9 @@ func TestConnUnicastSocketOptions(t *testing.T) {
testUnicastSocketOptions(t, ipv6.NewConn(c))
- <-done
+ if err := <-errc; err != nil {
+ t.Errorf("server: %v", err)
+ }
}
var packetConnUnicastSocketOptionTests = []struct {
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go
new file mode 100644
index 000000000..f5a410945
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mips.go
@@ -0,0 +1,168 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sysIPV6_ADDRFORM = 0x1
+ sysIPV6_2292PKTINFO = 0x2
+ sysIPV6_2292HOPOPTS = 0x3
+ sysIPV6_2292DSTOPTS = 0x4
+ sysIPV6_2292RTHDR = 0x5
+ sysIPV6_2292PKTOPTIONS = 0x6
+ sysIPV6_CHECKSUM = 0x7
+ sysIPV6_2292HOPLIMIT = 0x8
+ sysIPV6_NEXTHOP = 0x9
+ sysIPV6_FLOWINFO = 0xb
+
+ sysIPV6_UNICAST_HOPS = 0x10
+ sysIPV6_MULTICAST_IF = 0x11
+ sysIPV6_MULTICAST_HOPS = 0x12
+ sysIPV6_MULTICAST_LOOP = 0x13
+ sysIPV6_ADD_MEMBERSHIP = 0x14
+ sysIPV6_DROP_MEMBERSHIP = 0x15
+ sysMCAST_JOIN_GROUP = 0x2a
+ sysMCAST_LEAVE_GROUP = 0x2d
+ sysMCAST_JOIN_SOURCE_GROUP = 0x2e
+ sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
+ sysMCAST_BLOCK_SOURCE = 0x2b
+ sysMCAST_UNBLOCK_SOURCE = 0x2c
+ sysMCAST_MSFILTER = 0x30
+ sysIPV6_ROUTER_ALERT = 0x16
+ sysIPV6_MTU_DISCOVER = 0x17
+ sysIPV6_MTU = 0x18
+ sysIPV6_RECVERR = 0x19
+ sysIPV6_V6ONLY = 0x1a
+ sysIPV6_JOIN_ANYCAST = 0x1b
+ sysIPV6_LEAVE_ANYCAST = 0x1c
+
+ sysIPV6_FLOWLABEL_MGR = 0x20
+ sysIPV6_FLOWINFO_SEND = 0x21
+
+ sysIPV6_IPSEC_POLICY = 0x22
+ sysIPV6_XFRM_POLICY = 0x23
+
+ sysIPV6_RECVPKTINFO = 0x31
+ sysIPV6_PKTINFO = 0x32
+ sysIPV6_RECVHOPLIMIT = 0x33
+ sysIPV6_HOPLIMIT = 0x34
+ sysIPV6_RECVHOPOPTS = 0x35
+ sysIPV6_HOPOPTS = 0x36
+ sysIPV6_RTHDRDSTOPTS = 0x37
+ sysIPV6_RECVRTHDR = 0x38
+ sysIPV6_RTHDR = 0x39
+ sysIPV6_RECVDSTOPTS = 0x3a
+ sysIPV6_DSTOPTS = 0x3b
+ sysIPV6_RECVPATHMTU = 0x3c
+ sysIPV6_PATHMTU = 0x3d
+ sysIPV6_DONTFRAG = 0x3e
+
+ sysIPV6_RECVTCLASS = 0x42
+ sysIPV6_TCLASS = 0x43
+
+ sysIPV6_ADDR_PREFERENCES = 0x48
+
+ sysIPV6_PREFER_SRC_TMP = 0x1
+ sysIPV6_PREFER_SRC_PUBLIC = 0x2
+ sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
+ sysIPV6_PREFER_SRC_COA = 0x4
+ sysIPV6_PREFER_SRC_HOME = 0x400
+ sysIPV6_PREFER_SRC_CGA = 0x8
+ sysIPV6_PREFER_SRC_NONCGA = 0x800
+
+ sysIPV6_MINHOPCOUNT = 0x49
+
+ sysIPV6_ORIGDSTADDR = 0x4a
+ sysIPV6_RECVORIGDSTADDR = 0x4a
+ sysIPV6_TRANSPARENT = 0x4b
+ sysIPV6_UNICAST_IF = 0x4c
+
+ sysICMPV6_FILTER = 0x1
+
+ sysICMPV6_FILTER_BLOCK = 0x1
+ sysICMPV6_FILTER_PASS = 0x2
+ sysICMPV6_FILTER_BLOCKOTHERS = 0x3
+ sysICMPV6_FILTER_PASSONLY = 0x4
+
+ sysSOL_SOCKET = 0x1
+ sysSO_ATTACH_FILTER = 0x1a
+
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
+
+type sockFProg struct {
+ Len uint16
+ Pad_cgo_0 [2]byte
+ Filter *sockFilter
+}
+
+type sockFilter struct {
+ Code uint16
+ Jt uint8
+ Jf uint8
+ K uint32
+}
diff --git a/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go b/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go
new file mode 100644
index 000000000..f5a410945
--- /dev/null
+++ b/vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go
@@ -0,0 +1,168 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_linux.go
+
+package ipv6
+
+const (
+ sysIPV6_ADDRFORM = 0x1
+ sysIPV6_2292PKTINFO = 0x2
+ sysIPV6_2292HOPOPTS = 0x3
+ sysIPV6_2292DSTOPTS = 0x4
+ sysIPV6_2292RTHDR = 0x5
+ sysIPV6_2292PKTOPTIONS = 0x6
+ sysIPV6_CHECKSUM = 0x7
+ sysIPV6_2292HOPLIMIT = 0x8
+ sysIPV6_NEXTHOP = 0x9
+ sysIPV6_FLOWINFO = 0xb
+
+ sysIPV6_UNICAST_HOPS = 0x10
+ sysIPV6_MULTICAST_IF = 0x11
+ sysIPV6_MULTICAST_HOPS = 0x12
+ sysIPV6_MULTICAST_LOOP = 0x13
+ sysIPV6_ADD_MEMBERSHIP = 0x14
+ sysIPV6_DROP_MEMBERSHIP = 0x15
+ sysMCAST_JOIN_GROUP = 0x2a
+ sysMCAST_LEAVE_GROUP = 0x2d
+ sysMCAST_JOIN_SOURCE_GROUP = 0x2e
+ sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
+ sysMCAST_BLOCK_SOURCE = 0x2b
+ sysMCAST_UNBLOCK_SOURCE = 0x2c
+ sysMCAST_MSFILTER = 0x30
+ sysIPV6_ROUTER_ALERT = 0x16
+ sysIPV6_MTU_DISCOVER = 0x17
+ sysIPV6_MTU = 0x18
+ sysIPV6_RECVERR = 0x19
+ sysIPV6_V6ONLY = 0x1a
+ sysIPV6_JOIN_ANYCAST = 0x1b
+ sysIPV6_LEAVE_ANYCAST = 0x1c
+
+ sysIPV6_FLOWLABEL_MGR = 0x20
+ sysIPV6_FLOWINFO_SEND = 0x21
+
+ sysIPV6_IPSEC_POLICY = 0x22
+ sysIPV6_XFRM_POLICY = 0x23
+
+ sysIPV6_RECVPKTINFO = 0x31
+ sysIPV6_PKTINFO = 0x32
+ sysIPV6_RECVHOPLIMIT = 0x33
+ sysIPV6_HOPLIMIT = 0x34
+ sysIPV6_RECVHOPOPTS = 0x35
+ sysIPV6_HOPOPTS = 0x36
+ sysIPV6_RTHDRDSTOPTS = 0x37
+ sysIPV6_RECVRTHDR = 0x38
+ sysIPV6_RTHDR = 0x39
+ sysIPV6_RECVDSTOPTS = 0x3a
+ sysIPV6_DSTOPTS = 0x3b
+ sysIPV6_RECVPATHMTU = 0x3c
+ sysIPV6_PATHMTU = 0x3d
+ sysIPV6_DONTFRAG = 0x3e
+
+ sysIPV6_RECVTCLASS = 0x42
+ sysIPV6_TCLASS = 0x43
+
+ sysIPV6_ADDR_PREFERENCES = 0x48
+
+ sysIPV6_PREFER_SRC_TMP = 0x1
+ sysIPV6_PREFER_SRC_PUBLIC = 0x2
+ sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
+ sysIPV6_PREFER_SRC_COA = 0x4
+ sysIPV6_PREFER_SRC_HOME = 0x400
+ sysIPV6_PREFER_SRC_CGA = 0x8
+ sysIPV6_PREFER_SRC_NONCGA = 0x800
+
+ sysIPV6_MINHOPCOUNT = 0x49
+
+ sysIPV6_ORIGDSTADDR = 0x4a
+ sysIPV6_RECVORIGDSTADDR = 0x4a
+ sysIPV6_TRANSPARENT = 0x4b
+ sysIPV6_UNICAST_IF = 0x4c
+
+ sysICMPV6_FILTER = 0x1
+
+ sysICMPV6_FILTER_BLOCK = 0x1
+ sysICMPV6_FILTER_PASS = 0x2
+ sysICMPV6_FILTER_BLOCKOTHERS = 0x3
+ sysICMPV6_FILTER_PASSONLY = 0x4
+
+ sysSOL_SOCKET = 0x1
+ sysSO_ATTACH_FILTER = 0x1a
+
+ sizeofKernelSockaddrStorage = 0x80
+ sizeofSockaddrInet6 = 0x1c
+ sizeofInet6Pktinfo = 0x14
+ sizeofIPv6Mtuinfo = 0x20
+ sizeofIPv6FlowlabelReq = 0x20
+
+ sizeofIPv6Mreq = 0x14
+ sizeofGroupReq = 0x84
+ sizeofGroupSourceReq = 0x104
+
+ sizeofICMPv6Filter = 0x20
+)
+
+type kernelSockaddrStorage struct {
+ Family uint16
+ X__data [126]int8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type inet6Pktinfo struct {
+ Addr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type ipv6Mtuinfo struct {
+ Addr sockaddrInet6
+ Mtu uint32
+}
+
+type ipv6FlowlabelReq struct {
+ Dst [16]byte /* in6_addr */
+ Label uint32
+ Action uint8
+ Share uint8
+ Flags uint16
+ Expires uint16
+ Linger uint16
+ X__flr_pad uint32
+}
+
+type ipv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Ifindex int32
+}
+
+type groupReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+}
+
+type groupSourceReq struct {
+ Interface uint32
+ Group kernelSockaddrStorage
+ Source kernelSockaddrStorage
+}
+
+type icmpv6Filter struct {
+ Data [8]uint32
+}
+
+type sockFProg struct {
+ Len uint16
+ Pad_cgo_0 [2]byte
+ Filter *sockFilter
+}
+
+type sockFilter struct {
+ Code uint16
+ Jt uint8
+ Jf uint8
+ K uint32
+}
diff --git a/vendor/golang.org/x/net/nettest/conntest.go b/vendor/golang.org/x/net/nettest/conntest.go
new file mode 100644
index 000000000..c246bbe39
--- /dev/null
+++ b/vendor/golang.org/x/net/nettest/conntest.go
@@ -0,0 +1,451 @@
+// 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 nettest provides utilities for network testing.
+package nettest
+
+import (
+ "bytes"
+ "encoding/binary"
+ "io"
+ "io/ioutil"
+ "math/rand"
+ "net"
+ "sync"
+ "testing"
+ "time"
+)
+
+var (
+ aLongTimeAgo = time.Unix(233431200, 0)
+ neverTimeout = time.Time{}
+)
+
+// MakePipe creates a connection between two endpoints and returns the pair
+// as c1 and c2, such that anything written to c1 is read by c2 and vice-versa.
+// The stop function closes all resources, including c1, c2, and the underlying
+// net.Listener (if there is one), and should not be nil.
+type MakePipe func() (c1, c2 net.Conn, stop func(), err error)
+
+// TestConn tests that a net.Conn implementation properly satisfies the interface.
+// The tests should not produce any false positives, but may experience
+// false negatives. Thus, some issues may only be detected when the test is
+// run multiple times. For maximal effectiveness, run the tests under the
+// race detector.
+func TestConn(t *testing.T, mp MakePipe) {
+ testConn(t, mp)
+}
+
+type connTester func(t *testing.T, c1, c2 net.Conn)
+
+func timeoutWrapper(t *testing.T, mp MakePipe, f connTester) {
+ c1, c2, stop, err := mp()
+ if err != nil {
+ t.Fatalf("unable to make pipe: %v", err)
+ }
+ var once sync.Once
+ defer once.Do(func() { stop() })
+ timer := time.AfterFunc(time.Minute, func() {
+ once.Do(func() {
+ t.Error("test timed out; terminating pipe")
+ stop()
+ })
+ })
+ defer timer.Stop()
+ f(t, c1, c2)
+}
+
+// testBasicIO tests that the data sent on c1 is properly received on c2.
+func testBasicIO(t *testing.T, c1, c2 net.Conn) {
+ want := make([]byte, 1<<20)
+ rand.New(rand.NewSource(0)).Read(want)
+
+ dataCh := make(chan []byte)
+ go func() {
+ rd := bytes.NewReader(want)
+ if err := chunkedCopy(c1, rd); err != nil {
+ t.Errorf("unexpected c1.Write error: %v", err)
+ }
+ if err := c1.Close(); err != nil {
+ t.Errorf("unexpected c1.Close error: %v", err)
+ }
+ }()
+
+ go func() {
+ wr := new(bytes.Buffer)
+ if err := chunkedCopy(wr, c2); err != nil {
+ t.Errorf("unexpected c2.Read error: %v", err)
+ }
+ if err := c2.Close(); err != nil {
+ t.Errorf("unexpected c2.Close error: %v", err)
+ }
+ dataCh <- wr.Bytes()
+ }()
+
+ if got := <-dataCh; !bytes.Equal(got, want) {
+ t.Errorf("transmitted data differs")
+ }
+}
+
+// testPingPong tests that the two endpoints can synchronously send data to
+// each other in a typical request-response pattern.
+func testPingPong(t *testing.T, c1, c2 net.Conn) {
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ pingPonger := func(c net.Conn) {
+ defer wg.Done()
+ buf := make([]byte, 8)
+ var prev uint64
+ for {
+ if _, err := io.ReadFull(c, buf); err != nil {
+ if err == io.EOF {
+ break
+ }
+ t.Errorf("unexpected Read error: %v", err)
+ }
+
+ v := binary.LittleEndian.Uint64(buf)
+ binary.LittleEndian.PutUint64(buf, v+1)
+ if prev != 0 && prev+2 != v {
+ t.Errorf("mismatching value: got %d, want %d", v, prev+2)
+ }
+ prev = v
+ if v == 1000 {
+ break
+ }
+
+ if _, err := c.Write(buf); err != nil {
+ t.Errorf("unexpected Write error: %v", err)
+ break
+ }
+ }
+ if err := c.Close(); err != nil {
+ t.Errorf("unexpected Close error: %v", err)
+ }
+ }
+
+ wg.Add(2)
+ go pingPonger(c1)
+ go pingPonger(c2)
+
+ // Start off the chain reaction.
+ if _, err := c1.Write(make([]byte, 8)); err != nil {
+ t.Errorf("unexpected c1.Write error: %v", err)
+ }
+}
+
+// testRacyRead tests that it is safe to mutate the input Read buffer
+// immediately after cancelation has occurred.
+func testRacyRead(t *testing.T, c1, c2 net.Conn) {
+ go chunkedCopy(c2, rand.New(rand.NewSource(0)))
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ c1.SetReadDeadline(time.Now().Add(time.Millisecond))
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ b1 := make([]byte, 1024)
+ b2 := make([]byte, 1024)
+ for j := 0; j < 100; j++ {
+ _, err := c1.Read(b1)
+ copy(b1, b2) // Mutate b1 to trigger potential race
+ if err != nil {
+ checkForTimeoutError(t, err)
+ c1.SetReadDeadline(time.Now().Add(time.Millisecond))
+ }
+ }
+ }()
+ }
+}
+
+// testRacyWrite tests that it is safe to mutate the input Write buffer
+// immediately after cancelation has occurred.
+func testRacyWrite(t *testing.T, c1, c2 net.Conn) {
+ go chunkedCopy(ioutil.Discard, c2)
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ c1.SetWriteDeadline(time.Now().Add(time.Millisecond))
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ b1 := make([]byte, 1024)
+ b2 := make([]byte, 1024)
+ for j := 0; j < 100; j++ {
+ _, err := c1.Write(b1)
+ copy(b1, b2) // Mutate b1 to trigger potential race
+ if err != nil {
+ checkForTimeoutError(t, err)
+ c1.SetWriteDeadline(time.Now().Add(time.Millisecond))
+ }
+ }
+ }()
+ }
+}
+
+// testReadTimeout tests that Read timeouts do not affect Write.
+func testReadTimeout(t *testing.T, c1, c2 net.Conn) {
+ go chunkedCopy(ioutil.Discard, c2)
+
+ c1.SetReadDeadline(aLongTimeAgo)
+ _, err := c1.Read(make([]byte, 1024))
+ checkForTimeoutError(t, err)
+ if _, err := c1.Write(make([]byte, 1024)); err != nil {
+ t.Errorf("unexpected Write error: %v", err)
+ }
+}
+
+// testWriteTimeout tests that Write timeouts do not affect Read.
+func testWriteTimeout(t *testing.T, c1, c2 net.Conn) {
+ go chunkedCopy(c2, rand.New(rand.NewSource(0)))
+
+ c1.SetWriteDeadline(aLongTimeAgo)
+ _, err := c1.Write(make([]byte, 1024))
+ checkForTimeoutError(t, err)
+ if _, err := c1.Read(make([]byte, 1024)); err != nil {
+ t.Errorf("unexpected Read error: %v", err)
+ }
+}
+
+// testPastTimeout tests that a deadline set in the past immediately times out
+// Read and Write requests.
+func testPastTimeout(t *testing.T, c1, c2 net.Conn) {
+ go chunkedCopy(c2, c2)
+
+ testRoundtrip(t, c1)
+
+ c1.SetDeadline(aLongTimeAgo)
+ n, err := c1.Write(make([]byte, 1024))
+ if n != 0 {
+ t.Errorf("unexpected Write count: got %d, want 0", n)
+ }
+ checkForTimeoutError(t, err)
+ n, err = c1.Read(make([]byte, 1024))
+ if n != 0 {
+ t.Errorf("unexpected Read count: got %d, want 0", n)
+ }
+ checkForTimeoutError(t, err)
+
+ testRoundtrip(t, c1)
+}
+
+// testPresentTimeout tests that a deadline set while there are pending
+// Read and Write operations immediately times out those operations.
+func testPresentTimeout(t *testing.T, c1, c2 net.Conn) {
+ var wg sync.WaitGroup
+ defer wg.Wait()
+ wg.Add(3)
+
+ deadlineSet := make(chan bool, 1)
+ go func() {
+ defer wg.Done()
+ time.Sleep(100 * time.Millisecond)
+ deadlineSet <- true
+ c1.SetReadDeadline(aLongTimeAgo)
+ c1.SetWriteDeadline(aLongTimeAgo)
+ }()
+ go func() {
+ defer wg.Done()
+ n, err := c1.Read(make([]byte, 1024))
+ if n != 0 {
+ t.Errorf("unexpected Read count: got %d, want 0", n)
+ }
+ checkForTimeoutError(t, err)
+ if len(deadlineSet) == 0 {
+ t.Error("Read timed out before deadline is set")
+ }
+ }()
+ go func() {
+ defer wg.Done()
+ var err error
+ for err == nil {
+ _, err = c1.Write(make([]byte, 1024))
+ }
+ checkForTimeoutError(t, err)
+ if len(deadlineSet) == 0 {
+ t.Error("Write timed out before deadline is set")
+ }
+ }()
+}
+
+// testFutureTimeout tests that a future deadline will eventually time out
+// Read and Write operations.
+func testFutureTimeout(t *testing.T, c1, c2 net.Conn) {
+ var wg sync.WaitGroup
+ wg.Add(2)
+
+ c1.SetDeadline(time.Now().Add(100 * time.Millisecond))
+ go func() {
+ defer wg.Done()
+ _, err := c1.Read(make([]byte, 1024))
+ checkForTimeoutError(t, err)
+ }()
+ go func() {
+ defer wg.Done()
+ var err error
+ for err == nil {
+ _, err = c1.Write(make([]byte, 1024))
+ }
+ checkForTimeoutError(t, err)
+ }()
+ wg.Wait()
+
+ go chunkedCopy(c2, c2)
+ resyncConn(t, c1)
+ testRoundtrip(t, c1)
+}
+
+// testCloseTimeout tests that calling Close immediately times out pending
+// Read and Write operations.
+func testCloseTimeout(t *testing.T, c1, c2 net.Conn) {
+ go chunkedCopy(c2, c2)
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+ wg.Add(3)
+
+ // Test for cancelation upon connection closure.
+ c1.SetDeadline(neverTimeout)
+ go func() {
+ defer wg.Done()
+ time.Sleep(100 * time.Millisecond)
+ c1.Close()
+ }()
+ go func() {
+ defer wg.Done()
+ var err error
+ buf := make([]byte, 1024)
+ for err == nil {
+ _, err = c1.Read(buf)
+ }
+ }()
+ go func() {
+ defer wg.Done()
+ var err error
+ buf := make([]byte, 1024)
+ for err == nil {
+ _, err = c1.Write(buf)
+ }
+ }()
+}
+
+// testConcurrentMethods tests that the methods of net.Conn can safely
+// be called concurrently.
+func testConcurrentMethods(t *testing.T, c1, c2 net.Conn) {
+ go chunkedCopy(c2, c2)
+
+ // The results of the calls may be nonsensical, but this should
+ // not trigger a race detector warning.
+ var wg sync.WaitGroup
+ for i := 0; i < 100; i++ {
+ wg.Add(7)
+ go func() {
+ defer wg.Done()
+ c1.Read(make([]byte, 1024))
+ }()
+ go func() {
+ defer wg.Done()
+ c1.Write(make([]byte, 1024))
+ }()
+ go func() {
+ defer wg.Done()
+ c1.SetDeadline(time.Now().Add(10 * time.Millisecond))
+ }()
+ go func() {
+ defer wg.Done()
+ c1.SetReadDeadline(aLongTimeAgo)
+ }()
+ go func() {
+ defer wg.Done()
+ c1.SetWriteDeadline(aLongTimeAgo)
+ }()
+ go func() {
+ defer wg.Done()
+ c1.LocalAddr()
+ }()
+ go func() {
+ defer wg.Done()
+ c1.RemoteAddr()
+ }()
+ }
+ wg.Wait() // At worst, the deadline is set 10ms into the future
+
+ resyncConn(t, c1)
+ testRoundtrip(t, c1)
+}
+
+// checkForTimeoutError checks that the error satisfies the Error interface
+// and that Timeout returns true.
+func checkForTimeoutError(t *testing.T, err error) {
+ if nerr, ok := err.(net.Error); ok {
+ if !nerr.Timeout() {
+ t.Errorf("err.Timeout() = false, want true")
+ }
+ } else {
+ t.Errorf("got %T, want net.Error", err)
+ }
+}
+
+// testRoundtrip writes something into c and reads it back.
+// It assumes that everything written into c is echoed back to itself.
+func testRoundtrip(t *testing.T, c net.Conn) {
+ if err := c.SetDeadline(neverTimeout); err != nil {
+ t.Errorf("roundtrip SetDeadline error: %v", err)
+ }
+
+ const s = "Hello, world!"
+ buf := []byte(s)
+ if _, err := c.Write(buf); err != nil {
+ t.Errorf("roundtrip Write error: %v", err)
+ }
+ if _, err := io.ReadFull(c, buf); err != nil {
+ t.Errorf("roundtrip Read error: %v", err)
+ }
+ if string(buf) != s {
+ t.Errorf("roundtrip data mismatch: got %q, want %q", buf, s)
+ }
+}
+
+// resyncConn resynchronizes the connection into a sane state.
+// It assumes that everything written into c is echoed back to itself.
+// It assumes that 0xff is not currently on the wire or in the read buffer.
+func resyncConn(t *testing.T, c net.Conn) {
+ c.SetDeadline(neverTimeout)
+ errCh := make(chan error)
+ go func() {
+ _, err := c.Write([]byte{0xff})
+ errCh <- err
+ }()
+ buf := make([]byte, 1024)
+ for {
+ n, err := c.Read(buf)
+ if n > 0 && bytes.IndexByte(buf[:n], 0xff) == n-1 {
+ break
+ }
+ if err != nil {
+ t.Errorf("unexpected Read error: %v", err)
+ }
+ }
+ if err := <-errCh; err != nil {
+ t.Errorf("unexpected Write error: %v", err)
+ }
+}
+
+// chunkedCopy copies from r to w in fixed-width chunks to avoid
+// causing a Write that exceeds the maximum packet size for packet-based
+// connections like "unixpacket".
+// We assume that the maximum packet size is at least 1024.
+func chunkedCopy(w io.Writer, r io.Reader) error {
+ b := make([]byte, 1024)
+ _, err := io.CopyBuffer(struct{ io.Writer }{w}, struct{ io.Reader }{r}, b)
+ return err
+}
diff --git a/vendor/golang.org/x/net/nettest/conntest_go16.go b/vendor/golang.org/x/net/nettest/conntest_go16.go
new file mode 100644
index 000000000..4cbf48e35
--- /dev/null
+++ b/vendor/golang.org/x/net/nettest/conntest_go16.go
@@ -0,0 +1,24 @@
+// 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.
+
+// +build !go1.7
+
+package nettest
+
+import "testing"
+
+func testConn(t *testing.T, mp MakePipe) {
+ // Avoid using subtests on Go 1.6 and below.
+ timeoutWrapper(t, mp, testBasicIO)
+ timeoutWrapper(t, mp, testPingPong)
+ timeoutWrapper(t, mp, testRacyRead)
+ timeoutWrapper(t, mp, testRacyWrite)
+ timeoutWrapper(t, mp, testReadTimeout)
+ timeoutWrapper(t, mp, testWriteTimeout)
+ timeoutWrapper(t, mp, testPastTimeout)
+ timeoutWrapper(t, mp, testPresentTimeout)
+ timeoutWrapper(t, mp, testFutureTimeout)
+ timeoutWrapper(t, mp, testCloseTimeout)
+ timeoutWrapper(t, mp, testConcurrentMethods)
+}
diff --git a/vendor/golang.org/x/net/nettest/conntest_go17.go b/vendor/golang.org/x/net/nettest/conntest_go17.go
new file mode 100644
index 000000000..fa039f03f
--- /dev/null
+++ b/vendor/golang.org/x/net/nettest/conntest_go17.go
@@ -0,0 +1,24 @@
+// 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.
+
+// +build go1.7
+
+package nettest
+
+import "testing"
+
+func testConn(t *testing.T, mp MakePipe) {
+ // Use subtests on Go 1.7 and above since it is better organized.
+ t.Run("BasicIO", func(t *testing.T) { timeoutWrapper(t, mp, testBasicIO) })
+ t.Run("PingPong", func(t *testing.T) { timeoutWrapper(t, mp, testPingPong) })
+ t.Run("RacyRead", func(t *testing.T) { timeoutWrapper(t, mp, testRacyRead) })
+ t.Run("RacyWrite", func(t *testing.T) { timeoutWrapper(t, mp, testRacyWrite) })
+ t.Run("ReadTimeout", func(t *testing.T) { timeoutWrapper(t, mp, testReadTimeout) })
+ t.Run("WriteTimeout", func(t *testing.T) { timeoutWrapper(t, mp, testWriteTimeout) })
+ t.Run("PastTimeout", func(t *testing.T) { timeoutWrapper(t, mp, testPastTimeout) })
+ t.Run("PresentTimeout", func(t *testing.T) { timeoutWrapper(t, mp, testPresentTimeout) })
+ t.Run("FutureTimeout", func(t *testing.T) { timeoutWrapper(t, mp, testFutureTimeout) })
+ t.Run("CloseTimeout", func(t *testing.T) { timeoutWrapper(t, mp, testCloseTimeout) })
+ t.Run("ConcurrentMethods", func(t *testing.T) { timeoutWrapper(t, mp, testConcurrentMethods) })
+}
diff --git a/vendor/golang.org/x/net/nettest/conntest_test.go b/vendor/golang.org/x/net/nettest/conntest_test.go
new file mode 100644
index 000000000..9f9453fb5
--- /dev/null
+++ b/vendor/golang.org/x/net/nettest/conntest_test.go
@@ -0,0 +1,76 @@
+// 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.
+
+// +build go1.8
+
+package nettest
+
+import (
+ "net"
+ "os"
+ "runtime"
+ "testing"
+
+ "golang.org/x/net/internal/nettest"
+)
+
+func TestTestConn(t *testing.T) {
+ tests := []struct{ name, network string }{
+ {"TCP", "tcp"},
+ {"UnixPipe", "unix"},
+ {"UnixPacketPipe", "unixpacket"},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if !nettest.TestableNetwork(tt.network) {
+ t.Skipf("not supported on %s", runtime.GOOS)
+ }
+
+ mp := func() (c1, c2 net.Conn, stop func(), err error) {
+ ln, err := nettest.NewLocalListener(tt.network)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ // Start a connection between two endpoints.
+ var err1, err2 error
+ done := make(chan bool)
+ go func() {
+ c2, err2 = ln.Accept()
+ close(done)
+ }()
+ c1, err1 = net.Dial(ln.Addr().Network(), ln.Addr().String())
+ <-done
+
+ stop = func() {
+ if err1 == nil {
+ c1.Close()
+ }
+ if err2 == nil {
+ c2.Close()
+ }
+ ln.Close()
+ switch tt.network {
+ case "unix", "unixpacket":
+ os.Remove(ln.Addr().String())
+ }
+ }
+
+ switch {
+ case err1 != nil:
+ stop()
+ return nil, nil, nil, err1
+ case err2 != nil:
+ stop()
+ return nil, nil, nil, err2
+ default:
+ return c1, c2, stop, nil
+ }
+ }
+
+ TestConn(t, mp)
+ })
+ }
+}
diff --git a/vendor/golang.org/x/net/trace/events.go b/vendor/golang.org/x/net/trace/events.go
index e66c7e328..d8daec1a7 100644
--- a/vendor/golang.org/x/net/trace/events.go
+++ b/vendor/golang.org/x/net/trace/events.go
@@ -21,11 +21,6 @@ import (
"time"
)
-var eventsTmpl = template.Must(template.New("events").Funcs(template.FuncMap{
- "elapsed": elapsed,
- "trimSpace": strings.TrimSpace,
-}).Parse(eventsHTML))
-
const maxEventsPerLog = 100
type bucket struct {
@@ -101,7 +96,7 @@ func RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) {
famMu.RLock()
defer famMu.RUnlock()
- if err := eventsTmpl.Execute(w, data); err != nil {
+ if err := eventsTmpl().Execute(w, data); err != nil {
log.Printf("net/trace: Failed executing template: %v", err)
}
}
@@ -421,6 +416,19 @@ func freeEventLog(el *eventLog) {
}
}
+var eventsTmplCache *template.Template
+var eventsTmplOnce sync.Once
+
+func eventsTmpl() *template.Template {
+ eventsTmplOnce.Do(func() {
+ eventsTmplCache = template.Must(template.New("events").Funcs(template.FuncMap{
+ "elapsed": elapsed,
+ "trimSpace": strings.TrimSpace,
+ }).Parse(eventsHTML))
+ })
+ return eventsTmplCache
+}
+
const eventsHTML = `
<html>
<head>
diff --git a/vendor/golang.org/x/net/trace/histogram.go b/vendor/golang.org/x/net/trace/histogram.go
index bb42aa532..9bf4286c7 100644
--- a/vendor/golang.org/x/net/trace/histogram.go
+++ b/vendor/golang.org/x/net/trace/histogram.go
@@ -12,6 +12,7 @@ import (
"html/template"
"log"
"math"
+ "sync"
"golang.org/x/net/internal/timeseries"
)
@@ -320,15 +321,20 @@ func (h *histogram) newData() *data {
func (h *histogram) html() template.HTML {
buf := new(bytes.Buffer)
- if err := distTmpl.Execute(buf, h.newData()); err != nil {
+ if err := distTmpl().Execute(buf, h.newData()); err != nil {
buf.Reset()
log.Printf("net/trace: couldn't execute template: %v", err)
}
return template.HTML(buf.String())
}
-// Input: data
-var distTmpl = template.Must(template.New("distTmpl").Parse(`
+var distTmplCache *template.Template
+var distTmplOnce sync.Once
+
+func distTmpl() *template.Template {
+ distTmplOnce.Do(func() {
+ // Input: data
+ distTmplCache = template.Must(template.New("distTmpl").Parse(`
<table>
<tr>
<td style="padding:0.25em">Count: {{.Count}}</td>
@@ -354,3 +360,6 @@ var distTmpl = template.Must(template.New("distTmpl").Parse(`
{{end}}
</table>
`))
+ })
+ return distTmplCache
+}
diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go
index ecd766eb7..64f56a373 100644
--- a/vendor/golang.org/x/net/trace/trace.go
+++ b/vendor/golang.org/x/net/trace/trace.go
@@ -238,7 +238,7 @@ func Render(w io.Writer, req *http.Request, sensitive bool) {
completedMu.RLock()
defer completedMu.RUnlock()
- if err := pageTmpl.ExecuteTemplate(w, "Page", data); err != nil {
+ if err := pageTmpl().ExecuteTemplate(w, "Page", data); err != nil {
log.Printf("net/trace: Failed executing template: %v", err)
}
}
@@ -902,10 +902,18 @@ func elapsed(d time.Duration) string {
return string(b)
}
-var pageTmpl = template.Must(template.New("Page").Funcs(template.FuncMap{
- "elapsed": elapsed,
- "add": func(a, b int) int { return a + b },
-}).Parse(pageHTML))
+var pageTmplCache *template.Template
+var pageTmplOnce sync.Once
+
+func pageTmpl() *template.Template {
+ pageTmplOnce.Do(func() {
+ pageTmplCache = template.Must(template.New("Page").Funcs(template.FuncMap{
+ "elapsed": elapsed,
+ "add": func(a, b int) int { return a + b },
+ }).Parse(pageHTML))
+ })
+ return pageTmplCache
+}
const pageHTML = `
{{template "Prolog" .}}
diff --git a/vendor/golang.org/x/net/trace/trace_test.go b/vendor/golang.org/x/net/trace/trace_test.go
index c6aad86c2..bfd9dfe94 100644
--- a/vendor/golang.org/x/net/trace/trace_test.go
+++ b/vendor/golang.org/x/net/trace/trace_test.go
@@ -70,6 +70,20 @@ func TestAuthRequest(t *testing.T) {
}
}
+// TestParseTemplate checks that all templates used by this package are valid
+// as they are parsed on first usage
+func TestParseTemplate(t *testing.T) {
+ if tmpl := distTmpl(); tmpl == nil {
+ t.Error("invalid template returned from distTmpl()")
+ }
+ if tmpl := pageTmpl(); tmpl == nil {
+ t.Error("invalid template returned from pageTmpl()")
+ }
+ if tmpl := eventsTmpl(); tmpl == nil {
+ t.Error("invalid template returned from eventsTmpl()")
+ }
+}
+
func benchmarkTrace(b *testing.B, maxEvents, numEvents int) {
numSpans := (b.N + numEvents + 1) / numEvents
diff --git a/vendor/golang.org/x/net/websocket/websocket.go b/vendor/golang.org/x/net/websocket/websocket.go
index a7731d9c9..e242c89a7 100644
--- a/vendor/golang.org/x/net/websocket/websocket.go
+++ b/vendor/golang.org/x/net/websocket/websocket.go
@@ -4,6 +4,12 @@
// Package websocket implements a client and server for the WebSocket protocol
// as specified in RFC 6455.
+//
+// This package currently lacks some features found in an alternative
+// and more actively maintained WebSocket package:
+//
+// https://godoc.org/github.com/gorilla/websocket
+//
package websocket // import "golang.org/x/net/websocket"
import (