Update dependencies.
authorBrian Brazil <brian.brazil@robustperception.io>
Wed, 20 Sep 2017 12:25:37 +0000 (13:25 +0100)
committerBrian Brazil <brian.brazil@robustperception.io>
Wed, 20 Sep 2017 12:25:37 +0000 (13:25 +0100)
235 files changed:
vendor/github.com/beorn7/perks/quantile/stream.go
vendor/github.com/go-kit/kit/log/json_logger.go
vendor/github.com/go-kit/kit/log/sync.go
vendor/github.com/go-stack/stack/LICENSE.md
vendor/github.com/go-stack/stack/stack.go
vendor/github.com/golang/protobuf/proto/clone.go
vendor/github.com/golang/protobuf/proto/decode.go
vendor/github.com/golang/protobuf/proto/encode.go
vendor/github.com/golang/protobuf/proto/equal.go
vendor/github.com/golang/protobuf/proto/extensions.go
vendor/github.com/golang/protobuf/proto/lib.go
vendor/github.com/golang/protobuf/proto/message_set.go
vendor/github.com/golang/protobuf/proto/pointer_reflect.go
vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
vendor/github.com/golang/protobuf/proto/properties.go
vendor/github.com/golang/protobuf/proto/text.go
vendor/github.com/golang/protobuf/proto/text_parser.go
vendor/github.com/miekg/dns/README.md
vendor/github.com/miekg/dns/client.go
vendor/github.com/miekg/dns/clientconfig.go
vendor/github.com/miekg/dns/defaults.go
vendor/github.com/miekg/dns/dnssec.go
vendor/github.com/miekg/dns/dnssec_keygen.go
vendor/github.com/miekg/dns/dnssec_keyscan.go
vendor/github.com/miekg/dns/doc.go
vendor/github.com/miekg/dns/edns.go
vendor/github.com/miekg/dns/labels.go
vendor/github.com/miekg/dns/msg.go
vendor/github.com/miekg/dns/msg_generate.go
vendor/github.com/miekg/dns/msg_helpers.go
vendor/github.com/miekg/dns/nsecx.go
vendor/github.com/miekg/dns/reverse.go
vendor/github.com/miekg/dns/scan.go
vendor/github.com/miekg/dns/scan_rr.go
vendor/github.com/miekg/dns/server.go
vendor/github.com/miekg/dns/sig0.go
vendor/github.com/miekg/dns/tlsa.go
vendor/github.com/miekg/dns/tsig.go
vendor/github.com/miekg/dns/types.go
vendor/github.com/miekg/dns/types_generate.go
vendor/github.com/miekg/dns/udp.go
vendor/github.com/miekg/dns/udp_linux.go
vendor/github.com/miekg/dns/udp_other.go
vendor/github.com/miekg/dns/udp_plan9.go [deleted file]
vendor/github.com/miekg/dns/udp_windows.go
vendor/github.com/miekg/dns/xfr.go
vendor/github.com/miekg/dns/zmsg.go
vendor/github.com/miekg/dns/ztypes.go
vendor/github.com/pkg/errors/stack.go
vendor/github.com/prometheus/client_golang/prometheus/counter.go
vendor/github.com/prometheus/client_golang/prometheus/desc.go
vendor/github.com/prometheus/client_golang/prometheus/doc.go
vendor/github.com/prometheus/client_golang/prometheus/gauge.go
vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
vendor/github.com/prometheus/client_golang/prometheus/histogram.go
vendor/github.com/prometheus/client_golang/prometheus/http.go
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_7.go [deleted file]
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
vendor/github.com/prometheus/client_golang/prometheus/registry.go
vendor/github.com/prometheus/client_golang/prometheus/summary.go
vendor/github.com/prometheus/client_golang/prometheus/timer.go
vendor/github.com/prometheus/client_golang/prometheus/untyped.go
vendor/github.com/prometheus/client_golang/prometheus/value.go
vendor/github.com/prometheus/client_golang/prometheus/vec.go
vendor/github.com/prometheus/common/promlog/log.go
vendor/github.com/prometheus/procfs/AUTHORS.md [deleted file]
vendor/github.com/prometheus/procfs/CONTRIBUTING.md
vendor/github.com/prometheus/procfs/Makefile
vendor/github.com/prometheus/procfs/README.md
vendor/github.com/prometheus/procfs/fs.go
vendor/github.com/prometheus/procfs/ipvs.go
vendor/github.com/prometheus/procfs/proc.go
vendor/github.com/prometheus/procfs/proc_limits.go
vendor/github.com/prometheus/procfs/stat.go
vendor/golang.org/x/net/icmp/echo.go
vendor/golang.org/x/net/icmp/endpoint.go
vendor/golang.org/x/net/icmp/helper.go [deleted file]
vendor/golang.org/x/net/icmp/ipv4.go
vendor/golang.org/x/net/icmp/ipv6.go
vendor/golang.org/x/net/icmp/listen_posix.go
vendor/golang.org/x/net/icmp/message.go
vendor/golang.org/x/net/icmp/messagebody.go
vendor/golang.org/x/net/internal/iana/const.go
vendor/golang.org/x/net/internal/iana/gen.go
vendor/golang.org/x/net/ipv4/control.go
vendor/golang.org/x/net/ipv4/control_bsd.go
vendor/golang.org/x/net/ipv4/control_pktinfo.go
vendor/golang.org/x/net/ipv4/control_stub.go
vendor/golang.org/x/net/ipv4/control_unix.go
vendor/golang.org/x/net/ipv4/control_windows.go
vendor/golang.org/x/net/ipv4/defs_darwin.go
vendor/golang.org/x/net/ipv4/defs_dragonfly.go
vendor/golang.org/x/net/ipv4/defs_freebsd.go
vendor/golang.org/x/net/ipv4/defs_linux.go
vendor/golang.org/x/net/ipv4/defs_netbsd.go
vendor/golang.org/x/net/ipv4/defs_openbsd.go
vendor/golang.org/x/net/ipv4/defs_solaris.go
vendor/golang.org/x/net/ipv4/dgramopt_posix.go [deleted file]
vendor/golang.org/x/net/ipv4/dgramopt_stub.go [deleted file]
vendor/golang.org/x/net/ipv4/doc.go
vendor/golang.org/x/net/ipv4/endpoint.go
vendor/golang.org/x/net/ipv4/gen.go
vendor/golang.org/x/net/ipv4/genericopt_posix.go [deleted file]
vendor/golang.org/x/net/ipv4/genericopt_stub.go [deleted file]
vendor/golang.org/x/net/ipv4/header.go
vendor/golang.org/x/net/ipv4/helper.go
vendor/golang.org/x/net/ipv4/helper_stub.go [deleted file]
vendor/golang.org/x/net/ipv4/helper_unix.go [deleted file]
vendor/golang.org/x/net/ipv4/helper_windows.go [deleted file]
vendor/golang.org/x/net/ipv4/icmp.go
vendor/golang.org/x/net/ipv4/icmp_linux.go
vendor/golang.org/x/net/ipv4/icmp_stub.go
vendor/golang.org/x/net/ipv4/packet.go
vendor/golang.org/x/net/ipv4/payload.go
vendor/golang.org/x/net/ipv4/payload_cmsg.go
vendor/golang.org/x/net/ipv4/payload_nocmsg.go
vendor/golang.org/x/net/ipv4/sockopt.go
vendor/golang.org/x/net/ipv4/sockopt_asmreq.go [deleted file]
vendor/golang.org/x/net/ipv4/sockopt_asmreq_stub.go [deleted file]
vendor/golang.org/x/net/ipv4/sockopt_asmreq_unix.go [deleted file]
vendor/golang.org/x/net/ipv4/sockopt_asmreq_windows.go [deleted file]
vendor/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go [deleted file]
vendor/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go [deleted file]
vendor/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go [deleted file]
vendor/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go [deleted file]
vendor/golang.org/x/net/ipv4/sockopt_stub.go
vendor/golang.org/x/net/ipv4/sockopt_unix.go [deleted file]
vendor/golang.org/x/net/ipv4/sockopt_windows.go [deleted file]
vendor/golang.org/x/net/ipv4/sys_bsd.go
vendor/golang.org/x/net/ipv4/sys_darwin.go
vendor/golang.org/x/net/ipv4/sys_freebsd.go
vendor/golang.org/x/net/ipv4/sys_linux.go
vendor/golang.org/x/net/ipv4/sys_openbsd.go [deleted file]
vendor/golang.org/x/net/ipv4/sys_stub.go
vendor/golang.org/x/net/ipv4/sys_windows.go
vendor/golang.org/x/net/ipv4/syscall_linux_386.go [deleted file]
vendor/golang.org/x/net/ipv4/syscall_unix.go [deleted file]
vendor/golang.org/x/net/ipv4/thunk_linux_386.s [deleted file]
vendor/golang.org/x/net/ipv4/zsys_darwin.go
vendor/golang.org/x/net/ipv4/zsys_dragonfly.go
vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go
vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go
vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go
vendor/golang.org/x/net/ipv4/zsys_linux_386.go
vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go
vendor/golang.org/x/net/ipv4/zsys_linux_arm.go
vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go
vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go
vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go
vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go
vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go
vendor/golang.org/x/net/ipv4/zsys_netbsd.go
vendor/golang.org/x/net/ipv4/zsys_openbsd.go
vendor/golang.org/x/net/ipv4/zsys_solaris.go
vendor/golang.org/x/net/ipv6/control.go
vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go
vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go
vendor/golang.org/x/net/ipv6/control_stub.go
vendor/golang.org/x/net/ipv6/control_unix.go
vendor/golang.org/x/net/ipv6/control_windows.go
vendor/golang.org/x/net/ipv6/defs_darwin.go
vendor/golang.org/x/net/ipv6/defs_dragonfly.go
vendor/golang.org/x/net/ipv6/defs_freebsd.go
vendor/golang.org/x/net/ipv6/defs_linux.go
vendor/golang.org/x/net/ipv6/defs_netbsd.go
vendor/golang.org/x/net/ipv6/defs_openbsd.go
vendor/golang.org/x/net/ipv6/defs_solaris.go
vendor/golang.org/x/net/ipv6/dgramopt_posix.go [deleted file]
vendor/golang.org/x/net/ipv6/dgramopt_stub.go [deleted file]
vendor/golang.org/x/net/ipv6/doc.go
vendor/golang.org/x/net/ipv6/endpoint.go
vendor/golang.org/x/net/ipv6/gen.go
vendor/golang.org/x/net/ipv6/genericopt_posix.go [deleted file]
vendor/golang.org/x/net/ipv6/genericopt_stub.go [deleted file]
vendor/golang.org/x/net/ipv6/helper.go
vendor/golang.org/x/net/ipv6/helper_stub.go [deleted file]
vendor/golang.org/x/net/ipv6/helper_unix.go [deleted file]
vendor/golang.org/x/net/ipv6/helper_windows.go [deleted file]
vendor/golang.org/x/net/ipv6/icmp.go
vendor/golang.org/x/net/ipv6/icmp_bsd.go
vendor/golang.org/x/net/ipv6/icmp_linux.go
vendor/golang.org/x/net/ipv6/icmp_solaris.go
vendor/golang.org/x/net/ipv6/icmp_stub.go
vendor/golang.org/x/net/ipv6/icmp_windows.go
vendor/golang.org/x/net/ipv6/payload.go
vendor/golang.org/x/net/ipv6/payload_cmsg.go
vendor/golang.org/x/net/ipv6/payload_nocmsg.go
vendor/golang.org/x/net/ipv6/sockopt.go
vendor/golang.org/x/net/ipv6/sockopt_asmreq_unix.go [deleted file]
vendor/golang.org/x/net/ipv6/sockopt_asmreq_windows.go [deleted file]
vendor/golang.org/x/net/ipv6/sockopt_ssmreq_stub.go [deleted file]
vendor/golang.org/x/net/ipv6/sockopt_ssmreq_unix.go [deleted file]
vendor/golang.org/x/net/ipv6/sockopt_stub.go
vendor/golang.org/x/net/ipv6/sockopt_unix.go [deleted file]
vendor/golang.org/x/net/ipv6/sockopt_windows.go [deleted file]
vendor/golang.org/x/net/ipv6/sys_bsd.go
vendor/golang.org/x/net/ipv6/sys_darwin.go
vendor/golang.org/x/net/ipv6/sys_freebsd.go
vendor/golang.org/x/net/ipv6/sys_linux.go
vendor/golang.org/x/net/ipv6/sys_stub.go
vendor/golang.org/x/net/ipv6/sys_windows.go
vendor/golang.org/x/net/ipv6/syscall_linux_386.go [deleted file]
vendor/golang.org/x/net/ipv6/syscall_unix.go [deleted file]
vendor/golang.org/x/net/ipv6/thunk_linux_386.s [deleted file]
vendor/golang.org/x/net/ipv6/zsys_darwin.go
vendor/golang.org/x/net/ipv6/zsys_dragonfly.go
vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go
vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go
vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go
vendor/golang.org/x/net/ipv6/zsys_linux_386.go
vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go
vendor/golang.org/x/net/ipv6/zsys_linux_arm.go
vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go
vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go
vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go
vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go
vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go
vendor/golang.org/x/net/ipv6/zsys_netbsd.go
vendor/golang.org/x/net/ipv6/zsys_openbsd.go
vendor/golang.org/x/net/ipv6/zsys_solaris.go
vendor/gopkg.in/alecthomas/kingpin.v2/README.md
vendor/gopkg.in/alecthomas/kingpin.v2/parser.go
vendor/gopkg.in/alecthomas/kingpin.v2/values_generated.go
vendor/gopkg.in/yaml.v2/LICENSE
vendor/gopkg.in/yaml.v2/README.md
vendor/gopkg.in/yaml.v2/decode.go
vendor/gopkg.in/yaml.v2/emitterc.go
vendor/gopkg.in/yaml.v2/parserc.go
vendor/gopkg.in/yaml.v2/resolve.go
vendor/gopkg.in/yaml.v2/scannerc.go
vendor/gopkg.in/yaml.v2/yaml.go
vendor/gopkg.in/yaml.v2/yamlh.go
vendor/vendor.json

index 587b1fc5ba86281ec38b1f3ec41ab2bba0840ae3..f4cabd66956723454f73ca43c500a4a7a2aebf2a 100644 (file)
@@ -133,7 +133,7 @@ func (s *Stream) Query(q float64) float64 {
                if l == 0 {
                        return 0
                }
-               i := int(float64(l) * q)
+               i := int(math.Ceil(float64(l) * q))
                if i > 0 {
                        i -= 1
                }
index 231e09955376553bc02d38abf8f28c8e5b6f34c6..66094b4dd3f9e075f39b9b5e4ab8e65445b787cc 100644 (file)
@@ -44,9 +44,6 @@ func merge(dst map[string]interface{}, k, v interface{}) {
        default:
                key = fmt.Sprint(x)
        }
-       if x, ok := v.(error); ok {
-               v = safeError(x)
-       }
 
        // We want json.Marshaler and encoding.TextMarshaller to take priority over
        // err.Error() and v.String(). But json.Marshall (called later) does that by
index 2e8469083da1a3546a2cda5e50f6c2b6553f8559..c07cdfa043d74de07d7f138a7e50db7921756931 100644 (file)
@@ -1,4 +1,4 @@
-package log
+package log
 
 import (
        "io"
index c8ca66c5ede1ac9b4f80c149e224bd2fa406b0f1..2abf98ea835e56210fe9ba5d0fd073b45b9e21e0 100644 (file)
@@ -1,13 +1,21 @@
-Copyright 2014 Chris Hines
+The MIT License (MIT)
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+Copyright (c) 2014 Chris Hines
 
-   http://www.apache.org/licenses/LICENSE-2.0
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
 
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
index a614eeebf16dccf87f2e861482e75f82e7079035..79840edca3ee62a30b487e2bb05a157aa1da13da 100644 (file)
@@ -39,7 +39,7 @@ func Caller(skip int) Call {
        }
 
        c.pc = pcs[1]
-       if runtime.FuncForPC(pcs[0]) != sigpanic {
+       if runtime.FuncForPC(pcs[0]).Name() != "runtime.sigpanic" {
                c.pc--
        }
        c.fn = runtime.FuncForPC(c.pc)
@@ -71,6 +71,7 @@ var ErrNoFunc = errors.New("no call stack information")
 //    %s    source file
 //    %d    line number
 //    %n    function name
+//    %k    last segment of the package path
 //    %v    equivalent to %s:%d
 //
 // It accepts the '+' and '#' flags for most of the verbs as follows.
@@ -78,6 +79,7 @@ var ErrNoFunc = errors.New("no call stack information")
 //    %+s   path of source file relative to the compile time GOPATH
 //    %#s   full path of source file
 //    %+n   import path qualified function name
+//    %+k   full package path
 //    %+v   equivalent to %+s:%d
 //    %#v   equivalent to %#s:%d
 func (c Call) Format(s fmt.State, verb rune) {
@@ -111,6 +113,22 @@ func (c Call) Format(s fmt.State, verb rune) {
                buf := [6]byte{}
                s.Write(strconv.AppendInt(buf[:0], int64(line), 10))
 
+       case 'k':
+               name := c.fn.Name()
+               const pathSep = "/"
+               start, end := 0, len(name)
+               if i := strings.LastIndex(name, pathSep); i != -1 {
+                       start = i + len(pathSep)
+               }
+               const pkgSep = "."
+               if i := strings.Index(name[start:], pkgSep); i != -1 {
+                       end = start + i
+               }
+               if s.Flag('+') {
+                       start = 0
+               }
+               io.WriteString(s, name[start:end])
+
        case 'n':
                name := c.fn.Name()
                if !s.Flag('+') {
@@ -205,33 +223,6 @@ func (cs CallStack) Format(s fmt.State, verb rune) {
        s.Write(closeBracketBytes)
 }
 
-// findSigpanic intentionally executes faulting code to generate a stack trace
-// containing an entry for runtime.sigpanic.
-func findSigpanic() *runtime.Func {
-       var fn *runtime.Func
-       var p *int
-       func() int {
-               defer func() {
-                       if p := recover(); p != nil {
-                               var pcs [512]uintptr
-                               n := runtime.Callers(2, pcs[:])
-                               for _, pc := range pcs[:n] {
-                                       f := runtime.FuncForPC(pc)
-                                       if f.Name() == "runtime.sigpanic" {
-                                               fn = f
-                                               break
-                                       }
-                               }
-                       }
-               }()
-               // intentional nil pointer dereference to trigger sigpanic
-               return *p
-       }()
-       return fn
-}
-
-var sigpanic = findSigpanic()
-
 // Trace returns a CallStack for the current goroutine with element 0
 // identifying the calling function.
 func Trace() CallStack {
@@ -241,7 +232,7 @@ func Trace() CallStack {
 
        for i, pc := range pcs[:n] {
                pcFix := pc
-               if i > 0 && cs[i-1].fn != sigpanic {
+               if i > 0 && cs[i-1].fn.Name() != "runtime.sigpanic" {
                        pcFix--
                }
                cs[i] = Call{
index e98ddec9815b6da6a1483127656d5018656afccd..e392575b353afa4f22f513d3f22ff64a8f5fdbf1 100644 (file)
@@ -84,9 +84,15 @@ func mergeStruct(out, in reflect.Value) {
                mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
        }
 
-       if emIn, ok := in.Addr().Interface().(extendableProto); ok {
-               emOut := out.Addr().Interface().(extendableProto)
-               mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap())
+       if emIn, ok := extendable(in.Addr().Interface()); ok {
+               emOut, _ := extendable(out.Addr().Interface())
+               mIn, muIn := emIn.extensionsRead()
+               if mIn != nil {
+                       mOut := emOut.extensionsWrite()
+                       muIn.Lock()
+                       mergeExtension(mOut, mIn)
+                       muIn.Unlock()
+               }
        }
 
        uf := in.FieldByName("XXX_unrecognized")
index f94b9f416ecd54f6b72d1f4a6faacd43a3fb6e96..aa207298f997665117f3ba88e65646f95c83f08a 100644 (file)
@@ -61,7 +61,6 @@ var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for
 // int32, int64, uint32, uint64, bool, and enum
 // protocol buffer types.
 func DecodeVarint(buf []byte) (x uint64, n int) {
-       // x, n already 0
        for shift := uint(0); shift < 64; shift += 7 {
                if n >= len(buf) {
                        return 0, 0
@@ -78,13 +77,7 @@ func DecodeVarint(buf []byte) (x uint64, n int) {
        return 0, 0
 }
 
-// DecodeVarint reads a varint-encoded integer from the Buffer.
-// This is the format for the
-// int32, int64, uint32, uint64, bool, and enum
-// protocol buffer types.
-func (p *Buffer) DecodeVarint() (x uint64, err error) {
-       // x, err already 0
-
+func (p *Buffer) decodeVarintSlow() (x uint64, err error) {
        i := p.index
        l := len(p.buf)
 
@@ -107,6 +100,107 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) {
        return
 }
 
+// DecodeVarint reads a varint-encoded integer from the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (p *Buffer) DecodeVarint() (x uint64, err error) {
+       i := p.index
+       buf := p.buf
+
+       if i >= len(buf) {
+               return 0, io.ErrUnexpectedEOF
+       } else if buf[i] < 0x80 {
+               p.index++
+               return uint64(buf[i]), nil
+       } else if len(buf)-i < 10 {
+               return p.decodeVarintSlow()
+       }
+
+       var b uint64
+       // we already checked the first byte
+       x = uint64(buf[i]) - 0x80
+       i++
+
+       b = uint64(buf[i])
+       i++
+       x += b << 7
+       if b&0x80 == 0 {
+               goto done
+       }
+       x -= 0x80 << 7
+
+       b = uint64(buf[i])
+       i++
+       x += b << 14
+       if b&0x80 == 0 {
+               goto done
+       }
+       x -= 0x80 << 14
+
+       b = uint64(buf[i])
+       i++
+       x += b << 21
+       if b&0x80 == 0 {
+               goto done
+       }
+       x -= 0x80 << 21
+
+       b = uint64(buf[i])
+       i++
+       x += b << 28
+       if b&0x80 == 0 {
+               goto done
+       }
+       x -= 0x80 << 28
+
+       b = uint64(buf[i])
+       i++
+       x += b << 35
+       if b&0x80 == 0 {
+               goto done
+       }
+       x -= 0x80 << 35
+
+       b = uint64(buf[i])
+       i++
+       x += b << 42
+       if b&0x80 == 0 {
+               goto done
+       }
+       x -= 0x80 << 42
+
+       b = uint64(buf[i])
+       i++
+       x += b << 49
+       if b&0x80 == 0 {
+               goto done
+       }
+       x -= 0x80 << 49
+
+       b = uint64(buf[i])
+       i++
+       x += b << 56
+       if b&0x80 == 0 {
+               goto done
+       }
+       x -= 0x80 << 56
+
+       b = uint64(buf[i])
+       i++
+       x += b << 63
+       if b&0x80 == 0 {
+               goto done
+       }
+       // x -= 0x80 << 63 // Always zero.
+
+       return 0, errOverflow
+
+done:
+       p.index = i
+       return x, nil
+}
+
 // DecodeFixed64 reads a 64-bit integer from the Buffer.
 // This is the format for the
 // fixed64, sfixed64, and double protocol buffer types.
@@ -340,6 +434,8 @@ func (p *Buffer) DecodeGroup(pb Message) error {
 // Buffer and places the decoded result in pb.  If the struct
 // underlying pb does not match the data in the buffer, the results can be
 // unpredictable.
+//
+// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
 func (p *Buffer) Unmarshal(pb Message) error {
        // If the object can unmarshal itself, let it.
        if u, ok := pb.(Unmarshaler); ok {
@@ -378,6 +474,11 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
                wire := int(u & 0x7)
                if wire == WireEndGroup {
                        if is_group {
+                               if required > 0 {
+                                       // Not enough information to determine the exact field.
+                                       // (See below.)
+                                       return &RequiredNotSetError{"{Unknown}"}
+                               }
                                return nil // input is satisfied
                        }
                        return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
@@ -390,11 +491,12 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
                if !ok {
                        // Maybe it's an extension?
                        if prop.extendable {
-                               if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
+                               if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) {
                                        if err = o.skip(st, tag, wire); err == nil {
-                                               ext := e.ExtensionMap()[int32(tag)] // may be missing
+                                               extmap := e.extensionsWrite()
+                                               ext := extmap[int32(tag)] // may be missing
                                                ext.enc = append(ext.enc, o.buf[oi:o.index]...)
-                                               e.ExtensionMap()[int32(tag)] = ext
+                                               extmap[int32(tag)] = ext
                                        }
                                        continue
                                }
index eb7e0474ef6a864804c235931f57350408e9e2f0..8b84d1b22d4c0933820cb4872e29c918e5429be2 100644 (file)
@@ -70,6 +70,10 @@ var (
 
        // ErrNil is the error returned if Marshal is called with nil.
        ErrNil = errors.New("proto: Marshal called with nil")
+
+       // ErrTooLarge is the error returned if Marshal is called with a
+       // message that encodes to >2GB.
+       ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
 )
 
 // The fundamental encoders that put bytes on the wire.
@@ -78,6 +82,10 @@ var (
 
 const maxVarintBytes = 10 // maximum length of a varint
 
+// maxMarshalSize is the largest allowed size of an encoded protobuf,
+// since C++ and Java use signed int32s for the size.
+const maxMarshalSize = 1<<31 - 1
+
 // EncodeVarint returns the varint encoding of x.
 // This is the format for the
 // int32, int64, uint32, uint64, bool, and enum
@@ -166,11 +174,11 @@ func sizeFixed32(x uint64) int {
 // This is the format used for the sint64 protocol buffer type.
 func (p *Buffer) EncodeZigzag64(x uint64) error {
        // use signed number to get arithmetic right shift.
-       return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+       return p.EncodeVarint((x << 1) ^ uint64((int64(x) >> 63)))
 }
 
 func sizeZigzag64(x uint64) int {
-       return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+       return sizeVarint((x << 1) ^ uint64((int64(x) >> 63)))
 }
 
 // EncodeZigzag32 writes a zigzag-encoded 32-bit integer
@@ -226,10 +234,6 @@ func Marshal(pb Message) ([]byte, error) {
        }
        p := NewBuffer(nil)
        err := p.Marshal(pb)
-       var state errorState
-       if err != nil && !state.shouldContinue(err, nil) {
-               return nil, err
-       }
        if p.buf == nil && err == nil {
                // Return a non-nil slice on success.
                return []byte{}, nil
@@ -258,11 +262,8 @@ func (p *Buffer) Marshal(pb Message) error {
        // Can the object marshal itself?
        if m, ok := pb.(Marshaler); ok {
                data, err := m.Marshal()
-               if err != nil {
-                       return err
-               }
                p.buf = append(p.buf, data...)
-               return nil
+               return err
        }
 
        t, base, err := getbase(pb)
@@ -274,9 +275,12 @@ func (p *Buffer) Marshal(pb Message) error {
        }
 
        if collectStats {
-               stats.Encode++
+               (stats).Encode++ // Parens are to work around a goimports bug.
        }
 
+       if len(p.buf) > maxMarshalSize {
+               return ErrTooLarge
+       }
        return err
 }
 
@@ -298,7 +302,7 @@ func Size(pb Message) (n int) {
        }
 
        if collectStats {
-               stats.Size++
+               (stats).Size++ // Parens are to work around a goimports bug.
        }
 
        return
@@ -1003,7 +1007,6 @@ func size_slice_struct_message(p *Properties, base structPointer) (n int) {
                if p.isMarshaler {
                        m := structPointer_Interface(structp, p.stype).(Marshaler)
                        data, _ := m.Marshal()
-                       n += len(p.tagcode)
                        n += sizeRawBytes(data)
                        continue
                }
@@ -1062,10 +1065,32 @@ func size_slice_struct_group(p *Properties, base structPointer) (n int) {
 
 // Encode an extension map.
 func (o *Buffer) enc_map(p *Properties, base structPointer) error {
-       v := *structPointer_ExtMap(base, p.field)
-       if err := encodeExtensionMap(v); err != nil {
+       exts := structPointer_ExtMap(base, p.field)
+       if err := encodeExtensionsMap(*exts); err != nil {
                return err
        }
+
+       return o.enc_map_body(*exts)
+}
+
+func (o *Buffer) enc_exts(p *Properties, base structPointer) error {
+       exts := structPointer_Extensions(base, p.field)
+
+       v, mu := exts.extensionsRead()
+       if v == nil {
+               return nil
+       }
+
+       mu.Lock()
+       defer mu.Unlock()
+       if err := encodeExtensionsMap(v); err != nil {
+               return err
+       }
+
+       return o.enc_map_body(v)
+}
+
+func (o *Buffer) enc_map_body(v map[int32]Extension) error {
        // Fast-path for common cases: zero or one extensions.
        if len(v) <= 1 {
                for _, e := range v {
@@ -1088,8 +1113,13 @@ func (o *Buffer) enc_map(p *Properties, base structPointer) error {
 }
 
 func size_map(p *Properties, base structPointer) int {
-       v := *structPointer_ExtMap(base, p.field)
-       return sizeExtensionMap(v)
+       v := structPointer_ExtMap(base, p.field)
+       return extensionsMapSize(*v)
+}
+
+func size_exts(p *Properties, base structPointer) int {
+       v := structPointer_Extensions(base, p.field)
+       return extensionsSize(v)
 }
 
 // Encode a map field.
@@ -1118,7 +1148,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
                if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
                        return err
                }
-               if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
+               if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil {
                        return err
                }
                return nil
@@ -1128,11 +1158,6 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
        for _, key := range v.MapKeys() {
                val := v.MapIndex(key)
 
-               // The only illegal map entry values are nil message pointers.
-               if val.Kind() == reflect.Ptr && val.IsNil() {
-                       return errors.New("proto: map has nil element")
-               }
-
                keycopy.Set(key)
                valcopy.Set(val)
 
@@ -1220,6 +1245,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
                                        return err
                                }
                        }
+                       if len(o.buf) > maxMarshalSize {
+                               return ErrTooLarge
+                       }
                }
        }
 
@@ -1236,6 +1264,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
        // Add unrecognized fields at the end.
        if prop.unrecField.IsValid() {
                v := *structPointer_Bytes(base, prop.unrecField)
+               if len(o.buf)+len(v) > maxMarshalSize {
+                       return ErrTooLarge
+               }
                if len(v) > 0 {
                        o.buf = append(o.buf, v...)
                }
index f5db1def3c2483e5fb7879bfe318dea69964147c..2ed1cf596664d3dedb372fc051a04b79da040f21 100644 (file)
@@ -54,13 +54,17 @@ Equality is defined in this way:
     in a proto3 .proto file, fields are not "set"; specifically,
     zero length proto3 "bytes" fields are equal (nil == {}).
   - Two repeated fields are equal iff their lengths are the same,
-    and their corresponding elements are equal (a "bytes" field,
-    although represented by []byte, is not a repeated field)
+    and their corresponding elements are equal. Note a "bytes" field,
+    although represented by []byte, is not a repeated field and the
+    rule for the scalar fields described above applies.
   - Two unset fields are equal.
   - Two unknown field sets are equal if their current
     encoded state is equal.
   - Two extension sets are equal iff they have corresponding
     elements that are pairwise equal.
+  - Two map fields are equal iff their lengths are the same,
+    and they contain the same set of elements. Zero-length map
+    fields are equal.
   - Every other combination of things are not equal.
 
 The return value is undefined if a and b are not protocol buffers.
@@ -121,9 +125,16 @@ func equalStruct(v1, v2 reflect.Value) bool {
                }
        }
 
+       if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() {
+               em2 := v2.FieldByName("XXX_InternalExtensions")
+               if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {
+                       return false
+               }
+       }
+
        if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
                em2 := v2.FieldByName("XXX_extensions")
-               if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
+               if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
                        return false
                }
        }
@@ -184,6 +195,13 @@ func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
                }
                return true
        case reflect.Ptr:
+               // Maps may have nil values in them, so check for nil.
+               if v1.IsNil() && v2.IsNil() {
+                       return true
+               }
+               if v1.IsNil() != v2.IsNil() {
+                       return false
+               }
                return equalAny(v1.Elem(), v2.Elem(), prop)
        case reflect.Slice:
                if v1.Type().Elem().Kind() == reflect.Uint8 {
@@ -223,8 +241,14 @@ func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
 }
 
 // base is the struct type that the extensions are based on.
-// em1 and em2 are extension maps.
-func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
+// x1 and x2 are InternalExtensions.
+func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {
+       em1, _ := x1.extensionsRead()
+       em2, _ := x2.extensionsRead()
+       return equalExtMap(base, em1, em2)
+}
+
+func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
        if len(em1) != len(em2) {
                return false
        }
index 054f4f1df78872e3e9a5ec2ad41a937e463631f5..eaad21831263eecc5add3fa980847857d2123bf2 100644 (file)
@@ -52,14 +52,99 @@ type ExtensionRange struct {
        Start, End int32 // both inclusive
 }
 
-// extendableProto is an interface implemented by any protocol buffer that may be extended.
+// extendableProto is an interface implemented by any protocol buffer generated by the current
+// proto compiler that may be extended.
 type extendableProto interface {
+       Message
+       ExtensionRangeArray() []ExtensionRange
+       extensionsWrite() map[int32]Extension
+       extensionsRead() (map[int32]Extension, sync.Locker)
+}
+
+// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
+// version of the proto compiler that may be extended.
+type extendableProtoV1 interface {
        Message
        ExtensionRangeArray() []ExtensionRange
        ExtensionMap() map[int32]Extension
 }
 
+// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
+type extensionAdapter struct {
+       extendableProtoV1
+}
+
+func (e extensionAdapter) extensionsWrite() map[int32]Extension {
+       return e.ExtensionMap()
+}
+
+func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
+       return e.ExtensionMap(), notLocker{}
+}
+
+// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
+type notLocker struct{}
+
+func (n notLocker) Lock()   {}
+func (n notLocker) Unlock() {}
+
+// extendable returns the extendableProto interface for the given generated proto message.
+// If the proto message has the old extension format, it returns a wrapper that implements
+// the extendableProto interface.
+func extendable(p interface{}) (extendableProto, bool) {
+       if ep, ok := p.(extendableProto); ok {
+               return ep, ok
+       }
+       if ep, ok := p.(extendableProtoV1); ok {
+               return extensionAdapter{ep}, ok
+       }
+       return nil, false
+}
+
+// XXX_InternalExtensions is an internal representation of proto extensions.
+//
+// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
+// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
+//
+// The methods of XXX_InternalExtensions are not concurrency safe in general,
+// but calls to logically read-only methods such as has and get may be executed concurrently.
+type XXX_InternalExtensions struct {
+       // The struct must be indirect so that if a user inadvertently copies a
+       // generated message and its embedded XXX_InternalExtensions, they
+       // avoid the mayhem of a copied mutex.
+       //
+       // The mutex serializes all logically read-only operations to p.extensionMap.
+       // It is up to the client to ensure that write operations to p.extensionMap are
+       // mutually exclusive with other accesses.
+       p *struct {
+               mu           sync.Mutex
+               extensionMap map[int32]Extension
+       }
+}
+
+// extensionsWrite returns the extension map, creating it on first use.
+func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
+       if e.p == nil {
+               e.p = new(struct {
+                       mu           sync.Mutex
+                       extensionMap map[int32]Extension
+               })
+               e.p.extensionMap = make(map[int32]Extension)
+       }
+       return e.p.extensionMap
+}
+
+// extensionsRead returns the extensions map for read-only use.  It may be nil.
+// The caller must hold the returned mutex's lock when accessing Elements within the map.
+func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
+       if e.p == nil {
+               return nil, nil
+       }
+       return e.p.extensionMap, &e.p.mu
+}
+
 var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
+var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
 
 // ExtensionDesc represents an extension specification.
 // Used in generated code from the protocol compiler.
@@ -69,6 +154,7 @@ type ExtensionDesc struct {
        Field         int32       // field number
        Name          string      // fully-qualified name of extension, for text formatting
        Tag           string      // protobuf tag style
+       Filename      string      // name of the file in which the extension is defined
 }
 
 func (ed *ExtensionDesc) repeated() bool {
@@ -92,8 +178,13 @@ type Extension struct {
 }
 
 // SetRawExtension is for testing only.
-func SetRawExtension(base extendableProto, id int32, b []byte) {
-       base.ExtensionMap()[id] = Extension{enc: b}
+func SetRawExtension(base Message, id int32, b []byte) {
+       epb, ok := extendable(base)
+       if !ok {
+               return
+       }
+       extmap := epb.extensionsWrite()
+       extmap[id] = Extension{enc: b}
 }
 
 // isExtensionField returns true iff the given field number is in an extension range.
@@ -108,8 +199,12 @@ func isExtensionField(pb extendableProto, field int32) bool {
 
 // checkExtensionTypes checks that the given extension is valid for pb.
 func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
+       var pbi interface{} = pb
        // Check the extended type.
-       if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b {
+       if ea, ok := pbi.(extensionAdapter); ok {
+               pbi = ea.extendableProtoV1
+       }
+       if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
                return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
        }
        // Check the range.
@@ -155,8 +250,19 @@ func extensionProperties(ed *ExtensionDesc) *Properties {
        return prop
 }
 
-// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m.
-func encodeExtensionMap(m map[int32]Extension) error {
+// encode encodes any unmarshaled (unencoded) extensions in e.
+func encodeExtensions(e *XXX_InternalExtensions) error {
+       m, mu := e.extensionsRead()
+       if m == nil {
+               return nil // fast path
+       }
+       mu.Lock()
+       defer mu.Unlock()
+       return encodeExtensionsMap(m)
+}
+
+// encode encodes any unmarshaled (unencoded) extensions in e.
+func encodeExtensionsMap(m map[int32]Extension) error {
        for k, e := range m {
                if e.value == nil || e.desc == nil {
                        // Extension is only in its encoded form.
@@ -184,7 +290,17 @@ func encodeExtensionMap(m map[int32]Extension) error {
        return nil
 }
 
-func sizeExtensionMap(m map[int32]Extension) (n int) {
+func extensionsSize(e *XXX_InternalExtensions) (n int) {
+       m, mu := e.extensionsRead()
+       if m == nil {
+               return 0
+       }
+       mu.Lock()
+       defer mu.Unlock()
+       return extensionsMapSize(m)
+}
+
+func extensionsMapSize(m map[int32]Extension) (n int) {
        for _, e := range m {
                if e.value == nil || e.desc == nil {
                        // Extension is only in its encoded form.
@@ -209,26 +325,51 @@ func sizeExtensionMap(m map[int32]Extension) (n int) {
 }
 
 // HasExtension returns whether the given extension is present in pb.
-func HasExtension(pb extendableProto, extension *ExtensionDesc) bool {
+func HasExtension(pb Message, extension *ExtensionDesc) bool {
        // TODO: Check types, field numbers, etc.?
-       _, ok := pb.ExtensionMap()[extension.Field]
+       epb, ok := extendable(pb)
+       if !ok {
+               return false
+       }
+       extmap, mu := epb.extensionsRead()
+       if extmap == nil {
+               return false
+       }
+       mu.Lock()
+       _, ok = extmap[extension.Field]
+       mu.Unlock()
        return ok
 }
 
 // ClearExtension removes the given extension from pb.
-func ClearExtension(pb extendableProto, extension *ExtensionDesc) {
+func ClearExtension(pb Message, extension *ExtensionDesc) {
+       epb, ok := extendable(pb)
+       if !ok {
+               return
+       }
        // TODO: Check types, field numbers, etc.?
-       delete(pb.ExtensionMap(), extension.Field)
+       extmap := epb.extensionsWrite()
+       delete(extmap, extension.Field)
 }
 
 // GetExtension parses and returns the given extension of pb.
 // If the extension is not present and has no default value it returns ErrMissingExtension.
-func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
-       if err := checkExtensionTypes(pb, extension); err != nil {
+func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
+       epb, ok := extendable(pb)
+       if !ok {
+               return nil, errors.New("proto: not an extendable proto")
+       }
+
+       if err := checkExtensionTypes(epb, extension); err != nil {
                return nil, err
        }
 
-       emap := pb.ExtensionMap()
+       emap, mu := epb.extensionsRead()
+       if emap == nil {
+               return defaultExtensionValue(extension)
+       }
+       mu.Lock()
+       defer mu.Unlock()
        e, ok := emap[extension.Field]
        if !ok {
                // defaultExtensionValue returns the default value or
@@ -332,10 +473,9 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 // GetExtensions returns a slice of the extensions present in pb that are also listed in es.
 // The returned slice has the same length as es; missing extensions will appear as nil elements.
 func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
-       epb, ok := pb.(extendableProto)
+       epb, ok := extendable(pb)
        if !ok {
-               err = errors.New("proto: not an extendable proto")
-               return
+               return nil, errors.New("proto: not an extendable proto")
        }
        extensions = make([]interface{}, len(es))
        for i, e := range es {
@@ -350,9 +490,44 @@ func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, e
        return
 }
 
+// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
+// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
+// just the Field field, which defines the extension's field number.
+func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
+       epb, ok := extendable(pb)
+       if !ok {
+               return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
+       }
+       registeredExtensions := RegisteredExtensions(pb)
+
+       emap, mu := epb.extensionsRead()
+       if emap == nil {
+               return nil, nil
+       }
+       mu.Lock()
+       defer mu.Unlock()
+       extensions := make([]*ExtensionDesc, 0, len(emap))
+       for extid, e := range emap {
+               desc := e.desc
+               if desc == nil {
+                       desc = registeredExtensions[extid]
+                       if desc == nil {
+                               desc = &ExtensionDesc{Field: extid}
+                       }
+               }
+
+               extensions = append(extensions, desc)
+       }
+       return extensions, nil
+}
+
 // SetExtension sets the specified extension of pb to the specified value.
-func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error {
-       if err := checkExtensionTypes(pb, extension); err != nil {
+func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
+       epb, ok := extendable(pb)
+       if !ok {
+               return errors.New("proto: not an extendable proto")
+       }
+       if err := checkExtensionTypes(epb, extension); err != nil {
                return err
        }
        typ := reflect.TypeOf(extension.ExtensionType)
@@ -368,10 +543,23 @@ func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{
                return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
        }
 
-       pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value}
+       extmap := epb.extensionsWrite()
+       extmap[extension.Field] = Extension{desc: extension, value: value}
        return nil
 }
 
+// ClearAllExtensions clears all extensions from pb.
+func ClearAllExtensions(pb Message) {
+       epb, ok := extendable(pb)
+       if !ok {
+               return
+       }
+       m := epb.extensionsWrite()
+       for k := range m {
+               delete(m, k)
+       }
+}
+
 // A global registry of extensions.
 // The generated code will register the generated descriptors by calling RegisterExtension.
 
index 0de8f8dffd0880ceea9abd8176eaa2adb1e11109..1c225504a013c5da68f5b46caa5c110dd32db6cf 100644 (file)
@@ -73,7 +73,6 @@ for a protocol buffer variable v:
 When the .proto file specifies `syntax="proto3"`, there are some differences:
 
   - Non-repeated fields of non-message type are values instead of pointers.
-  - Getters are only generated for message and oneof fields.
   - Enum types do not get an Enum method.
 
 The simplest way to describe this is to see an example.
@@ -308,7 +307,7 @@ func GetStats() Stats { return stats }
 // temporary Buffer and are fine for most applications.
 type Buffer struct {
        buf   []byte // encode/decode byte stream
-       index int    // write point
+       index int    // read point
 
        // pools of basic types to amortize allocation.
        bools   []bool
@@ -889,6 +888,10 @@ func isProto3Zero(v reflect.Value) bool {
        return false
 }
 
+// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
+// to assert that that code is compatible with this version of the proto package.
+const ProtoPackageIsVersion2 = true
+
 // ProtoPackageIsVersion1 is referenced from generated protocol buffer files
 // to assert that that code is compatible with this version of the proto package.
 const ProtoPackageIsVersion1 = true
index e25e01e637483854ff51d528627d83065d525827..fd982decd66e4846031a72a785470be20afe99a5 100644 (file)
@@ -149,9 +149,21 @@ func skipVarint(buf []byte) []byte {
 
 // MarshalMessageSet encodes the extension map represented by m in the message set wire format.
 // It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
-func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
-       if err := encodeExtensionMap(m); err != nil {
-               return nil, err
+func MarshalMessageSet(exts interface{}) ([]byte, error) {
+       var m map[int32]Extension
+       switch exts := exts.(type) {
+       case *XXX_InternalExtensions:
+               if err := encodeExtensions(exts); err != nil {
+                       return nil, err
+               }
+               m, _ = exts.extensionsRead()
+       case map[int32]Extension:
+               if err := encodeExtensionsMap(exts); err != nil {
+                       return nil, err
+               }
+               m = exts
+       default:
+               return nil, errors.New("proto: not an extension map")
        }
 
        // Sort extension IDs to provide a deterministic encoding.
@@ -178,7 +190,17 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
 
 // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
 // It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
-func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
+func UnmarshalMessageSet(buf []byte, exts interface{}) error {
+       var m map[int32]Extension
+       switch exts := exts.(type) {
+       case *XXX_InternalExtensions:
+               m = exts.extensionsWrite()
+       case map[int32]Extension:
+               m = exts
+       default:
+               return errors.New("proto: not an extension map")
+       }
+
        ms := new(messageSet)
        if err := Unmarshal(buf, ms); err != nil {
                return err
@@ -209,7 +231,16 @@ func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
 
 // MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
 // It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
-func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
+func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
+       var m map[int32]Extension
+       switch exts := exts.(type) {
+       case *XXX_InternalExtensions:
+               m, _ = exts.extensionsRead()
+       case map[int32]Extension:
+               m = exts
+       default:
+               return nil, errors.New("proto: not an extension map")
+       }
        var b bytes.Buffer
        b.WriteByte('{')
 
@@ -252,7 +283,7 @@ func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
 
 // UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
 // It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
-func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error {
+func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error {
        // Common-case fast path.
        if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
                return nil
index 749919d250a1acffc5588a004501ee6b829d9059..fb512e2e16dce05683722f810c279367bdc68fe9 100644 (file)
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build appengine
+// +build appengine js
 
 // This file contains an implementation of proto field accesses using package reflect.
 // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
@@ -139,6 +139,11 @@ func structPointer_StringSlice(p structPointer, f field) *[]string {
        return structPointer_ifield(p, f).(*[]string)
 }
 
+// Extensions returns the address of an extension map field in the struct.
+func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
+       return structPointer_ifield(p, f).(*XXX_InternalExtensions)
+}
+
 // ExtMap returns the address of an extension map field in the struct.
 func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
        return structPointer_ifield(p, f).(*map[int32]Extension)
index e9be0fe92ee708ad56688e024dadb2b21821be8c..6b5567d47cd396b25370f8c06bad3b851776658f 100644 (file)
@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build !appengine
+// +build !appengine,!js
 
 // This file contains the implementation of the proto field accesses using package unsafe.
 
@@ -126,6 +126,10 @@ func structPointer_StringSlice(p structPointer, f field) *[]string {
 }
 
 // ExtMap returns the address of an extension map field in the struct.
+func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
+       return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
 func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
        return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 }
index 4fe2ec22e8630f4db61789f2e925fb72f0831f1b..ec2289c0058e47e3d20fa2bef7a3979529aa7512 100644 (file)
@@ -473,17 +473,13 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock
                        p.dec = (*Buffer).dec_slice_int64
                        p.packedDec = (*Buffer).dec_slice_packed_int64
                case reflect.Uint8:
-                       p.enc = (*Buffer).enc_slice_byte
                        p.dec = (*Buffer).dec_slice_byte
-                       p.size = size_slice_byte
-                       // This is a []byte, which is either a bytes field,
-                       // or the value of a map field. In the latter case,
-                       // we always encode an empty []byte, so we should not
-                       // use the proto3 enc/size funcs.
-                       // f == nil iff this is the key/value of a map field.
-                       if p.proto3 && f != nil {
+                       if p.proto3 {
                                p.enc = (*Buffer).enc_proto3_slice_byte
                                p.size = size_proto3_slice_byte
+                       } else {
+                               p.enc = (*Buffer).enc_slice_byte
+                               p.size = size_slice_byte
                        }
                case reflect.Float32, reflect.Float64:
                        switch t2.Bits() {
@@ -682,7 +678,8 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
        propertiesMap[t] = prop
 
        // build properties
-       prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType)
+       prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
+               reflect.PtrTo(t).Implements(extendableProtoV1Type)
        prop.unrecField = invalidField
        prop.Prop = make([]*Properties, t.NumField())
        prop.order = make([]int, t.NumField())
@@ -693,15 +690,22 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
                name := f.Name
                p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
 
-               if f.Name == "XXX_extensions" { // special case
+               if f.Name == "XXX_InternalExtensions" { // special case
+                       p.enc = (*Buffer).enc_exts
+                       p.dec = nil // not needed
+                       p.size = size_exts
+               } else if f.Name == "XXX_extensions" { // special case
                        p.enc = (*Buffer).enc_map
                        p.dec = nil // not needed
                        p.size = size_map
-               }
-               if f.Name == "XXX_unrecognized" { // special case
+               } else if f.Name == "XXX_unrecognized" { // special case
                        prop.unrecField = toField(&f)
                }
-               oneof := f.Tag.Get("protobuf_oneof") != "" // special case
+               oneof := f.Tag.Get("protobuf_oneof") // special case
+               if oneof != "" {
+                       // Oneof fields don't use the traditional protobuf tag.
+                       p.OrigName = oneof
+               }
                prop.Prop[i] = p
                prop.order[i] = i
                if debug {
@@ -711,7 +715,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
                        }
                        print("\n")
                }
-               if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof {
+               if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
                        fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
                }
        }
@@ -840,7 +844,29 @@ func RegisterType(x Message, name string) {
 }
 
 // MessageName returns the fully-qualified proto name for the given message type.
-func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] }
+func MessageName(x Message) string {
+       type xname interface {
+               XXX_MessageName() string
+       }
+       if m, ok := x.(xname); ok {
+               return m.XXX_MessageName()
+       }
+       return revProtoTypes[reflect.TypeOf(x)]
+}
 
 // MessageType returns the message type (pointer to struct) for a named message.
 func MessageType(name string) reflect.Type { return protoTypes[name] }
+
+// A registry of all linked proto files.
+var (
+       protoFiles = make(map[string][]byte) // file name => fileDescriptor
+)
+
+// RegisterFile is called from generated code and maps from the
+// full file name of a .proto file to its compressed FileDescriptorProto.
+func RegisterFile(filename string, fileDescriptor []byte) {
+       protoFiles[filename] = fileDescriptor
+}
+
+// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
+func FileDescriptor(filename string) []byte { return protoFiles[filename] }
index 37c953570d341e8cc203ffe91822512f54fa06ea..965876bf033b64fac26deb2730244625d033fa41 100644 (file)
@@ -154,7 +154,7 @@ func (w *textWriter) indent() { w.ind++ }
 
 func (w *textWriter) unindent() {
        if w.ind == 0 {
-               log.Printf("proto: textWriter unindented too far")
+               log.Print("proto: textWriter unindented too far")
                return
        }
        w.ind--
@@ -455,7 +455,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 
        // Extensions (the XXX_extensions field).
        pv := sv.Addr()
-       if pv.Type().Implements(extendableProtoType) {
+       if _, ok := extendable(pv.Interface()); ok {
                if err := tm.writeExtensions(w, pv); err != nil {
                        return err
                }
@@ -513,7 +513,7 @@ func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Propert
        switch v.Kind() {
        case reflect.Slice:
                // Should only be a []byte; repeated fields are handled in writeStruct.
-               if err := writeString(w, string(v.Interface().([]byte))); err != nil {
+               if err := writeString(w, string(v.Bytes())); err != nil {
                        return err
                }
        case reflect.String:
@@ -689,17 +689,22 @@ func (s int32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 // pv is assumed to be a pointer to a protocol message struct that is extendable.
 func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
        emap := extensionMaps[pv.Type().Elem()]
-       ep := pv.Interface().(extendableProto)
+       ep, _ := extendable(pv.Interface())
 
        // Order the extensions by ID.
        // This isn't strictly necessary, but it will give us
        // canonical output, which will also make testing easier.
-       m := ep.ExtensionMap()
+       m, mu := ep.extensionsRead()
+       if m == nil {
+               return nil
+       }
+       mu.Lock()
        ids := make([]int32, 0, len(m))
        for id := range m {
                ids = append(ids, id)
        }
        sort.Sort(int32Slice(ids))
+       mu.Unlock()
 
        for _, extNum := range ids {
                ext := m[extNum]
index b5e1c8e1f46585b8f07e6603e66b7bfbc264b07f..5e14513f28c9041020ee559c9ec437361720024f 100644 (file)
@@ -44,6 +44,9 @@ import (
        "unicode/utf8"
 )
 
+// Error string emitted when deserializing Any and fields are already set
+const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set"
+
 type ParseError struct {
        Message string
        Line    int // 1-based line number
@@ -508,8 +511,16 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
                                if err != nil {
                                        return p.errorf("failed to marshal message of type %q: %v", messageName, err)
                                }
+                               if fieldSet["type_url"] {
+                                       return p.errorf(anyRepeatedlyUnpacked, "type_url")
+                               }
+                               if fieldSet["value"] {
+                                       return p.errorf(anyRepeatedlyUnpacked, "value")
+                               }
                                sv.FieldByName("TypeUrl").SetString(extName)
                                sv.FieldByName("Value").SetBytes(b)
+                               fieldSet["type_url"] = true
+                               fieldSet["value"] = true
                                continue
                        }
 
@@ -550,7 +561,7 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
                                }
                                reqFieldErr = err
                        }
-                       ep := sv.Addr().Interface().(extendableProto)
+                       ep := sv.Addr().Interface().(Message)
                        if !rep {
                                SetExtension(ep, desc, ext.Interface())
                        } else {
@@ -581,7 +592,11 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
                        props = oop.Prop
                        nv := reflect.New(oop.Type.Elem())
                        dst = nv.Elem().Field(0)
-                       sv.Field(oop.Field).Set(nv)
+                       field := sv.Field(oop.Field)
+                       if !field.IsNil() {
+                               return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name)
+                       }
+                       field.Set(nv)
                }
                if !dst.IsValid() {
                        return p.errorf("unknown field name %q in %v", name, st)
@@ -602,8 +617,9 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 
                        // The map entry should be this sequence of tokens:
                        //      < key : KEY value : VALUE >
-                       // Technically the "key" and "value" could come in any order,
-                       // but in practice they won't.
+                       // However, implementations may omit key or value, and technically
+                       // we should support them in any order.  See b/28924776 for a time
+                       // this went wrong.
 
                        tok := p.next()
                        var terminator string
@@ -615,32 +631,39 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
                        default:
                                return p.errorf("expected '{' or '<', found %q", tok.value)
                        }
-                       if err := p.consumeToken("key"); err != nil {
-                               return err
-                       }
-                       if err := p.consumeToken(":"); err != nil {
-                               return err
-                       }
-                       if err := p.readAny(key, props.mkeyprop); err != nil {
-                               return err
-                       }
-                       if err := p.consumeOptionalSeparator(); err != nil {
-                               return err
-                       }
-                       if err := p.consumeToken("value"); err != nil {
-                               return err
-                       }
-                       if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
-                               return err
-                       }
-                       if err := p.readAny(val, props.mvalprop); err != nil {
-                               return err
-                       }
-                       if err := p.consumeOptionalSeparator(); err != nil {
-                               return err
-                       }
-                       if err := p.consumeToken(terminator); err != nil {
-                               return err
+                       for {
+                               tok := p.next()
+                               if tok.err != nil {
+                                       return tok.err
+                               }
+                               if tok.value == terminator {
+                                       break
+                               }
+                               switch tok.value {
+                               case "key":
+                                       if err := p.consumeToken(":"); err != nil {
+                                               return err
+                                       }
+                                       if err := p.readAny(key, props.mkeyprop); err != nil {
+                                               return err
+                                       }
+                                       if err := p.consumeOptionalSeparator(); err != nil {
+                                               return err
+                                       }
+                               case "value":
+                                       if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
+                                               return err
+                                       }
+                                       if err := p.readAny(val, props.mvalprop); err != nil {
+                                               return err
+                                       }
+                                       if err := p.consumeOptionalSeparator(); err != nil {
+                                               return err
+                                       }
+                               default:
+                                       p.back()
+                                       return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value)
+                               }
                        }
 
                        dst.SetMapIndex(key, val)
@@ -663,7 +686,8 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
                                return err
                        }
                        reqFieldErr = err
-               } else if props.Required {
+               }
+               if props.Required {
                        reqCount--
                }
 
@@ -772,12 +796,12 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
                fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
                return p.readAny(fv.Index(fv.Len()-1), props)
        case reflect.Bool:
-               // Either "true", "false", 1 or 0.
+               // true/1/t/True or false/f/0/False.
                switch tok.value {
-               case "true", "1":
+               case "true", "1", "t", "True":
                        fv.SetBool(true)
                        return nil
-               case "false", "0":
+               case "false", "0", "f", "False":
                        fv.SetBool(false)
                        return nil
                }
@@ -841,7 +865,7 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
                return p.readStruct(fv, terminator)
        case reflect.Uint32:
                if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
-                       fv.SetUint(uint64(x))
+                       fv.SetUint(x)
                        return nil
                }
        case reflect.Uint64:
index 83b4183eb80dc300ece0e6e0152ab8cfb9124ed9..32a49cbf50c4e640e6a4505acd2ea00fda2f4675 100644 (file)
@@ -1,4 +1,5 @@
 [![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns)
+[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns)
 
 # Alternative (more granular) approach to a DNS library
 
@@ -12,18 +13,19 @@ can build servers and resolvers with it.
 
 We try to keep the "master" branch as sane as possible and at the bleeding edge
 of standards, avoiding breaking changes wherever reasonable. We support the last
-two versions of Go, currently: 1.5 and 1.6.
+two versions of Go, currently: 1.7 and 1.8.
 
 # Goals
 
 * KISS;
 * Fast;
-* Small API, if its easy to code in Go, don't make a function for it.
+* Small API. If it's easy to code in Go, don't make a function for it.
 
 # Users
 
 A not-so-up-to-date-list-that-may-be-actually-current:
 
+* https://github.com/coredns/coredns
 * https://cloudflare.com
 * https://github.com/abh/geodns
 * http://www.statdns.com/
@@ -50,6 +52,14 @@ A not-so-up-to-date-list-that-may-be-actually-current:
 * https://dnslookup.org
 * https://github.com/looterz/grimd
 * https://github.com/phamhongviet/serf-dns
+* https://github.com/mehrdadrad/mylg
+* https://github.com/bamarni/dockness
+* https://github.com/fffaraz/microdns
+* http://quilt.io
+* https://github.com/ipdcode/hades (JD.COM)
+* https://github.com/StackExchange/dnscontrol/
+* https://www.dnsperf.com/
+* https://dnssectest.net/
 
 Send pull request if you want to be listed here.
 
@@ -138,6 +148,7 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
 * 6975 - Algorithm Understanding in DNSSEC
 * 7043 - EUI48/EUI64 records
 * 7314 - DNS (EDNS) EXPIRE Option
+* 7828 - edns-tcp-keepalive EDNS0 Option
 * 7553 - URI record
 * 7858 - DNS over TLS: Initiation and Performance Considerations (draft)
 * 7873 - Domain Name System (DNS) Cookies (draft-ietf-dnsop-cookies)
index 1302e4e04c6d323f73fc2f84d7a48a6630d2f95b..1c14a19d893df1574af4c5705a2bba95f5dbd80a 100644 (file)
@@ -4,6 +4,7 @@ package dns
 
 import (
        "bytes"
+       "context"
        "crypto/tls"
        "encoding/binary"
        "io"
@@ -39,7 +40,7 @@ type Client struct {
 }
 
 // Exchange performs a synchronous UDP query. It sends the message m to the address
-// contained in a and waits for an reply. Exchange does not retry a failed query, nor
+// contained in a and waits for a reply. Exchange does not retry a failed query, nor
 // will it fall back to TCP in case of truncation.
 // See client.Exchange for more information on setting larger buffer sizes.
 func Exchange(m *Msg, a string) (r *Msg, err error) {
@@ -70,6 +71,43 @@ func Exchange(m *Msg, a string) (r *Msg, err error) {
        return r, err
 }
 
+// ExchangeContext performs a synchronous UDP query, like Exchange. It
+// additionally obeys deadlines from the passed Context.
+func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
+       // Combine context deadline with built-in timeout. Context chooses whichever
+       // is sooner.
+       timeoutCtx, cancel := context.WithTimeout(ctx, dnsTimeout)
+       defer cancel()
+       deadline, _ := timeoutCtx.Deadline()
+
+       co := new(Conn)
+       dialer := net.Dialer{}
+       co.Conn, err = dialer.DialContext(timeoutCtx, "udp", a)
+       if err != nil {
+               return nil, err
+       }
+
+       defer co.Conn.Close()
+
+       opt := m.IsEdns0()
+       // If EDNS0 is used use that for size.
+       if opt != nil && opt.UDPSize() >= MinMsgSize {
+               co.UDPSize = opt.UDPSize()
+       }
+
+       co.SetWriteDeadline(deadline)
+       if err = co.WriteMsg(m); err != nil {
+               return nil, err
+       }
+
+       co.SetReadDeadline(deadline)
+       r, err = co.ReadMsg()
+       if err == nil && r.Id != m.Id {
+               err = ErrId
+       }
+       return r, err
+}
+
 // ExchangeConn performs a synchronous query. It sends the message m via the connection
 // c and waits for a reply. The connection c is not closed by ExchangeConn.
 // This function is going away, but can easily be mimicked:
@@ -93,8 +131,8 @@ func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
        return r, err
 }
 
-// Exchange performs an synchronous query. It sends the message m to the address
-// contained in a and waits for an reply. Basic use pattern with a *dns.Client:
+// Exchange performs a synchronous query. It sends the message m to the address
+// contained in a and waits for a reply. Basic use pattern with a *dns.Client:
 //
 //     c := new(dns.Client)
 //     in, rtt, err := c.Exchange(message, "127.0.0.1:53")
@@ -103,11 +141,21 @@ func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
 // case of truncation.
 // It is up to the caller to create a message that allows for larger responses to be
 // returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger
-// buffer, see SetEdns0. Messsages without an OPT RR will fallback to the historic limit
+// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit
 // of 512 bytes.
 func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
+       return c.ExchangeContext(context.Background(), m, a)
+}
+
+// ExchangeContext acts like Exchange, but honors the deadline on the provided
+// context, if present. If there is both a context deadline and a configured
+// timeout on the client, the earliest of the two takes effect.
+func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (
+       r *Msg,
+       rtt time.Duration,
+       err error) {
        if !c.SingleInflight {
-               return c.exchange(m, a)
+               return c.exchange(ctx, m, a)
        }
        // This adds a bunch of garbage, TODO(miek).
        t := "nop"
@@ -119,14 +167,14 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
                cl = cl1
        }
        r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
-               return c.exchange(m, a)
+               return c.exchange(ctx, m, a)
        })
+       if r != nil && shared {
+               r = r.Copy()
+       }
        if err != nil {
                return r, rtt, err
        }
-       if shared {
-               return r.Copy(), rtt, nil
-       }
        return r, rtt, nil
 }
 
@@ -154,7 +202,7 @@ func (c *Client) writeTimeout() time.Duration {
        return dnsTimeout
 }
 
-func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
+func (c *Client) exchange(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
        var co *Conn
        network := "udp"
        tls := false
@@ -180,10 +228,13 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
                deadline = time.Now().Add(c.Timeout)
        }
 
+       dialDeadline := deadlineOrTimeoutOrCtx(ctx, deadline, c.dialTimeout())
+       dialTimeout := dialDeadline.Sub(time.Now())
+
        if tls {
-               co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, c.dialTimeout())
+               co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, dialTimeout)
        } else {
-               co, err = DialTimeout(network, a, c.dialTimeout())
+               co, err = DialTimeout(network, a, dialTimeout)
        }
 
        if err != nil {
@@ -202,12 +253,12 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
        }
 
        co.TsigSecret = c.TsigSecret
-       co.SetWriteDeadline(deadlineOrTimeout(deadline, c.writeTimeout()))
+       co.SetWriteDeadline(deadlineOrTimeoutOrCtx(ctx, deadline, c.writeTimeout()))
        if err = co.WriteMsg(m); err != nil {
                return nil, 0, err
        }
 
-       co.SetReadDeadline(deadlineOrTimeout(deadline, c.readTimeout()))
+       co.SetReadDeadline(deadlineOrTimeoutOrCtx(ctx, deadline, c.readTimeout()))
        r, err = co.ReadMsg()
        if err == nil && r.Id != m.Id {
                err = ErrId
@@ -300,6 +351,18 @@ func tcpMsgLen(t io.Reader) (int, error) {
        if err != nil {
                return 0, err
        }
+
+       // As seen with my local router/switch, retursn 1 byte on the above read,
+       // resulting a a ShortRead. Just write it out (instead of loop) and read the
+       // other byte.
+       if n == 1 {
+               n1, err := t.Read(p[1:])
+               if err != nil {
+                       return 0, err
+               }
+               n += n1
+       }
+
        if n != 2 {
                return 0, ErrShortRead
        }
@@ -400,7 +463,7 @@ func (co *Conn) Write(p []byte) (n int, err error) {
                n, err := io.Copy(w, bytes.NewReader(p))
                return int(n), err
        }
-       n, err = co.Conn.(*net.UDPConn).Write(p)
+       n, err = co.Conn.Write(p)
        return n, err
 }
 
@@ -447,9 +510,22 @@ func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout
        return conn, nil
 }
 
+// deadlineOrTimeout chooses between the provided deadline and timeout
+// by always preferring the deadline so long as it's non-zero (regardless
+// of which is bigger), and returns the equivalent deadline value.
 func deadlineOrTimeout(deadline time.Time, timeout time.Duration) time.Time {
        if deadline.IsZero() {
                return time.Now().Add(timeout)
        }
        return deadline
 }
+
+// deadlineOrTimeoutOrCtx returns the earliest of: a context deadline, or the
+// output of deadlineOrtimeout.
+func deadlineOrTimeoutOrCtx(ctx context.Context, deadline time.Time, timeout time.Duration) time.Time {
+       result := deadlineOrTimeout(deadline, timeout)
+       if ctxDeadline, ok := ctx.Deadline(); ok && ctxDeadline.Before(result) {
+               result = ctxDeadline
+       }
+       return result
+}
index cfa9ad0b228ee17fc80f743d5cddaa2eebb175bb..0a1f5a92c57616ccc877a0a20d1b183f01d05c62 100644 (file)
@@ -97,3 +97,35 @@ func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
        }
        return c, nil
 }
+
+// NameList returns all of the names that should be queried based on the
+// config. It is based off of go's net/dns name building, but it does not
+// check the length of the resulting names.
+func (c *ClientConfig) NameList(name string) []string {
+       // if this domain is already fully qualified, no append needed.
+       if IsFqdn(name) {
+               return []string{name}
+       }
+
+       // Check to see if the name has more labels than Ndots. Do this before making
+       // the domain fully qualified.
+       hasNdots := CountLabel(name) > c.Ndots
+       // Make the domain fully qualified.
+       name = Fqdn(name)
+
+       // Make a list of names based off search.
+       names := []string{}
+
+       // If name has enough dots, try that first.
+       if hasNdots {
+               names = append(names, name)
+       }
+       for _, s := range c.Search {
+               names = append(names, Fqdn(name+s))
+       }
+       // If we didn't have enough dots, try after suffixes.
+       if !hasNdots {
+               names = append(names, name)
+       }
+       return names
+}
index cf456165f4354ddc59d26353a90dbdb8130063f6..c34890eecc737809b950926683349b01452d38e3 100644 (file)
@@ -13,9 +13,12 @@ const hexDigit = "0123456789abcdef"
 // SetReply creates a reply message from a request message.
 func (dns *Msg) SetReply(request *Msg) *Msg {
        dns.Id = request.Id
-       dns.RecursionDesired = request.RecursionDesired // Copy rd bit
        dns.Response = true
-       dns.Opcode = OpcodeQuery
+       dns.Opcode = request.Opcode
+       if dns.Opcode == OpcodeQuery {
+               dns.RecursionDesired = request.RecursionDesired // Copy rd bit
+               dns.CheckingDisabled = request.CheckingDisabled // Copy cd bit
+       }
        dns.Rcode = RcodeSuccess
        if len(request.Question) > 0 {
                dns.Question = make([]Question, 1)
@@ -102,11 +105,11 @@ func (dns *Msg) SetAxfr(z string) *Msg {
 // SetTsig appends a TSIG RR to the message.
 // This is only a skeleton TSIG RR that is added as the last RR in the
 // additional section. The Tsig is calculated when the message is being send.
-func (dns *Msg) SetTsig(z, algo string, fudge, timesigned int64) *Msg {
+func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) *Msg {
        t := new(TSIG)
        t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
        t.Algorithm = algo
-       t.Fudge = 300
+       t.Fudge = fudge
        t.TimeSigned = uint64(timesigned)
        t.OrigId = dns.Id
        dns.Extra = append(dns.Extra, t)
index f5f3fbdd899fe400c664bed04d718a57d2209b1a..3bd55388d8133644b3a1d545e48e99a39a1fba8c 100644 (file)
@@ -43,7 +43,7 @@ const (
        PRIVATEOID uint8 = 254
 )
 
-// Map for algorithm names.
+// AlgorithmToString is a map of algorithm IDs to algorithm names.
 var AlgorithmToString = map[uint8]string{
        RSAMD5:           "RSAMD5",
        DH:               "DH",
@@ -61,10 +61,10 @@ var AlgorithmToString = map[uint8]string{
        PRIVATEOID:       "PRIVATEOID",
 }
 
-// Map of algorithm strings.
+// StringToAlgorithm is the reverse of AlgorithmToString.
 var StringToAlgorithm = reverseInt8(AlgorithmToString)
 
-// Map of algorithm crypto hashes.
+// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
 var AlgorithmToHash = map[uint8]crypto.Hash{
        RSAMD5:           crypto.MD5, // Deprecated in RFC 6725
        RSASHA1:          crypto.SHA1,
@@ -85,7 +85,7 @@ const (
        SHA512       // Experimental
 )
 
-// Map for hash names.
+// HashToString is a map of hash IDs to names.
 var HashToString = map[uint8]string{
        SHA1:   "SHA1",
        SHA256: "SHA256",
@@ -94,7 +94,7 @@ var HashToString = map[uint8]string{
        SHA512: "SHA512",
 }
 
-// Map of hash strings.
+// StringToHash is a map of names to hash IDs.
 var StringToHash = reverseInt8(HashToString)
 
 // DNSKEY flag values.
@@ -208,9 +208,6 @@ func (k *DNSKEY) ToDS(h uint8) *DS {
        // "|" denotes concatenation
        // DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
 
-       // digest buffer
-       digest := append(owner, wire...) // another copy
-
        var hash crypto.Hash
        switch h {
        case SHA1:
@@ -226,7 +223,8 @@ func (k *DNSKEY) ToDS(h uint8) *DS {
        }
 
        s := hash.New()
-       s.Write(digest)
+       s.Write(owner)
+       s.Write(wire)
        ds.Digest = hex.EncodeToString(s.Sum(nil))
        return ds
 }
@@ -297,7 +295,6 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
        if err != nil {
                return err
        }
-       signdata = append(signdata, wire...)
 
        hash, ok := AlgorithmToHash[rr.Algorithm]
        if !ok {
@@ -306,6 +303,7 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
 
        h := hash.New()
        h.Write(signdata)
+       h.Write(wire)
 
        signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm)
        if err != nil {
@@ -415,7 +413,6 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
        if err != nil {
                return err
        }
-       signeddata = append(signeddata, wire...)
 
        sigbuf := rr.sigBuf()           // Get the binary signature data
        if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
@@ -438,6 +435,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
 
                h := hash.New()
                h.Write(signeddata)
+               h.Write(wire)
                return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf)
 
        case ECDSAP256SHA256, ECDSAP384SHA384:
@@ -452,6 +450,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
 
                h := hash.New()
                h.Write(signeddata)
+               h.Write(wire)
                if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
                        return nil
                }
@@ -516,7 +515,7 @@ func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
        }
        // Remainder
        expo += uint64(keybuf[keyoff])
-       if expo > 2<<31 {
+       if expo > (2<<31)+1 {
                // Larger expo than supported.
                // println("dns: F5 primes (or larger) are not supported")
                return nil
index 229a079370b742295b99fe3ee9342b77bfb4fd0d..5e4b7741a69dbf1551bfaa1e8464c9002e8965cd 100644 (file)
@@ -121,17 +121,17 @@ func (k *DNSKEY) setPublicKeyDSA(_Q, _P, _G, _Y *big.Int) bool {
 // RFC 3110: Section 2. RSA Public KEY Resource Records
 func exponentToBuf(_E int) []byte {
        var buf []byte
-       i := big.NewInt(int64(_E))
-       if len(i.Bytes()) < 256 {
-               buf = make([]byte, 1)
-               buf[0] = uint8(len(i.Bytes()))
+       i := big.NewInt(int64(_E)).Bytes()
+       if len(i) < 256 {
+               buf = make([]byte, 1, 1+len(i))
+               buf[0] = uint8(len(i))
        } else {
-               buf = make([]byte, 3)
+               buf = make([]byte, 3, 3+len(i))
                buf[0] = 0
-               buf[1] = uint8(len(i.Bytes()) >> 8)
-               buf[2] = uint8(len(i.Bytes()))
+               buf[1] = uint8(len(i) >> 8)
+               buf[2] = uint8(len(i))
        }
-       buf = append(buf, i.Bytes()...)
+       buf = append(buf, i...)
        return buf
 }
 
index c0b54dc7640a1d30b1529c2a9f4edfedd3729e2c..4f8d830b85899461e0173f98e0d6847c7cba59d2 100644 (file)
@@ -14,7 +14,7 @@ import (
 // NewPrivateKey returns a PrivateKey by parsing the string s.
 // s should be in the same form of the BIND private key files.
 func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) {
-       if s[len(s)-1] != '\n' { // We need a closing newline
+       if s == "" || s[len(s)-1] != '\n' { // We need a closing newline
                return k.ReadPrivateKey(strings.NewReader(s+"\n"), "")
        }
        return k.ReadPrivateKey(strings.NewReader(s), "")
@@ -36,7 +36,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er
                return nil, ErrPrivKey
        }
        // TODO(mg): check if the pubkey matches the private key
-       algo, err := strconv.Atoi(strings.SplitN(m["algorithm"], " ", 2)[0])
+       algo, err := strconv.ParseUint(strings.SplitN(m["algorithm"], " ", 2)[0], 10, 8)
        if err != nil {
                return nil, ErrPrivKey
        }
index f3555e433992d88e4d154945378f1ab2d13c5274..e38753d7d8a7ab1a94ab8e0475f745304641130f 100644 (file)
@@ -203,7 +203,7 @@ RFC 6895 sets aside a range of type codes for private use. This range
 is 65,280 - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these
 can be used, before requesting an official type code from IANA.
 
-see http://miek.nl/posts/2014/Sep/21/Private%20RRs%20and%20IDN%20in%20Go%20DNS/ for more
+see http://miek.nl/2014/September/21/idn-and-private-rr-in-go-dns/ for more
 information.
 
 EDNS0
index 7a58aa9b17b683241fb989ea4717c4506e140e6d..dbff3714cf5626f5e7aee30987f44582e5c24af9 100644 (file)
@@ -4,25 +4,27 @@ import (
        "encoding/binary"
        "encoding/hex"
        "errors"
+       "fmt"
        "net"
        "strconv"
 )
 
 // EDNS0 Option codes.
 const (
-       EDNS0LLQ         = 0x1     // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
-       EDNS0UL          = 0x2     // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
-       EDNS0NSID        = 0x3     // nsid (RFC5001)
-       EDNS0DAU         = 0x5     // DNSSEC Algorithm Understood
-       EDNS0DHU         = 0x6     // DS Hash Understood
-       EDNS0N3U         = 0x7     // NSEC3 Hash Understood
-       EDNS0SUBNET      = 0x8     // client-subnet (RFC6891)
-       EDNS0EXPIRE      = 0x9     // EDNS0 expire
-       EDNS0COOKIE      = 0xa     // EDNS0 Cookie
-       EDNS0SUBNETDRAFT = 0x50fa  // Don't use! Use EDNS0SUBNET
-       EDNS0LOCALSTART  = 0xFDE9  // Beginning of range reserved for local/experimental use (RFC6891)
-       EDNS0LOCALEND    = 0xFFFE  // End of range reserved for local/experimental use (RFC6891)
-       _DO              = 1 << 15 // dnssec ok
+       EDNS0LLQ          = 0x1     // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
+       EDNS0UL           = 0x2     // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
+       EDNS0NSID         = 0x3     // nsid (RFC5001)
+       EDNS0DAU          = 0x5     // DNSSEC Algorithm Understood
+       EDNS0DHU          = 0x6     // DS Hash Understood
+       EDNS0N3U          = 0x7     // NSEC3 Hash Understood
+       EDNS0SUBNET       = 0x8     // client-subnet (RFC6891)
+       EDNS0EXPIRE       = 0x9     // EDNS0 expire
+       EDNS0COOKIE       = 0xa     // EDNS0 Cookie
+       EDNS0TCPKEEPALIVE = 0xb     // EDNS0 tcp keep alive (RFC7828)
+       EDNS0SUBNETDRAFT  = 0x50fa  // Don't use! Use EDNS0SUBNET
+       EDNS0LOCALSTART   = 0xFDE9  // Beginning of range reserved for local/experimental use (RFC6891)
+       EDNS0LOCALEND     = 0xFFFE  // End of range reserved for local/experimental use (RFC6891)
+       _DO               = 1 << 15 // dnssec ok
 )
 
 // OPT is the EDNS0 RR appended to messages to convey extra (meta) information.
@@ -128,8 +130,18 @@ func (rr *OPT) Do() bool {
 }
 
 // SetDo sets the DO (DNSSEC OK) bit.
-func (rr *OPT) SetDo() {
-       rr.Hdr.Ttl |= _DO
+// If we pass an argument, set the DO bit to that value.
+// It is possible to pass 2 or more arguments. Any arguments after the 1st is silently ignored.
+func (rr *OPT) SetDo(do ...bool) {
+       if len(do) == 1 {
+               if do[0] {
+                       rr.Hdr.Ttl |= _DO
+               } else {
+                       rr.Hdr.Ttl &^= _DO
+               }
+       } else {
+               rr.Hdr.Ttl |= _DO
+       }
 }
 
 // EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it.
@@ -145,7 +157,7 @@ type EDNS0 interface {
        String() string
 }
 
-// The nsid EDNS0 option is used to retrieve a nameserver
+// EDNS0_NSID option is used to retrieve a nameserver
 // identifier. When sending a request Nsid must be set to the empty string
 // The identifier is an opaque string encoded as hex.
 // Basic use pattern for creating an nsid option:
@@ -185,7 +197,7 @@ func (e *EDNS0_NSID) String() string        { return string(e.Nsid) }
 //     e := new(dns.EDNS0_SUBNET)
 //     e.Code = dns.EDNS0SUBNET
 //     e.Family = 1    // 1 for IPv4 source address, 2 for IPv6
-//     e.NetMask = 32  // 32 for IPV4, 128 for IPv6
+//     e.SourceNetmask = 32    // 32 for IPV4, 128 for IPv6
 //     e.SourceScope = 0
 //     e.Address = net.ParseIP("127.0.0.1").To4()      // for IPv4
 //     // e.Address = net.ParseIP("2001:7b8:32a::2")   // for IPV6
@@ -289,7 +301,7 @@ func (e *EDNS0_SUBNET) String() (s string) {
        return
 }
 
-// The Cookie EDNS0 option
+// The EDNS0_COOKIE option is used to add a DNS Cookie to a message.
 //
 //     o := new(dns.OPT)
 //     o.Hdr.Name = "."
@@ -530,3 +542,56 @@ func (e *EDNS0_LOCAL) unpack(b []byte) error {
        }
        return nil
 }
+
+// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep
+// the TCP connection alive. See RFC 7828.
+type EDNS0_TCP_KEEPALIVE struct {
+       Code    uint16 // Always EDNSTCPKEEPALIVE
+       Length  uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present;
+       Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order.
+}
+
+func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE }
+
+func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) {
+       if e.Timeout != 0 && e.Length != 2 {
+               return nil, errors.New("dns: timeout specified but length is not 2")
+       }
+       if e.Timeout == 0 && e.Length != 0 {
+               return nil, errors.New("dns: timeout not specified but length is not 0")
+       }
+       b := make([]byte, 4+e.Length)
+       binary.BigEndian.PutUint16(b[0:], e.Code)
+       binary.BigEndian.PutUint16(b[2:], e.Length)
+       if e.Length == 2 {
+               binary.BigEndian.PutUint16(b[4:], e.Timeout)
+       }
+       return b, nil
+}
+
+func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error {
+       if len(b) < 4 {
+               return ErrBuf
+       }
+       e.Length = binary.BigEndian.Uint16(b[2:4])
+       if e.Length != 0 && e.Length != 2 {
+               return errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10))
+       }
+       if e.Length == 2 {
+               if len(b) < 6 {
+                       return ErrBuf
+               }
+               e.Timeout = binary.BigEndian.Uint16(b[4:6])
+       }
+       return nil
+}
+
+func (e *EDNS0_TCP_KEEPALIVE) String() (s string) {
+       s = "use tcp keep-alive"
+       if e.Length == 0 {
+               s += ", timeout omitted"
+       } else {
+               s += fmt.Sprintf(", timeout %dms", e.Timeout*100)
+       }
+       return
+}
index fca5c7dd2d1549dacaa987f3f5fdcf44321a288d..9538d9c3a63de8f137d4b9c9e7bbd0d9e51bd262 100644 (file)
@@ -1,5 +1,7 @@
 package dns
 
+import "strings"
+
 // Holds a bunch of helper functions for dealing with labels.
 
 // SplitDomainName splits a name string into it's labels.
@@ -50,6 +52,7 @@ func SplitDomainName(s string) (labels []string) {
 //
 // s1 and s2 must be syntactically valid domain names.
 func CompareDomainName(s1, s2 string) (n int) {
+       s1, s2 = strings.ToLower(s1), strings.ToLower(s2)
        s1 = Fqdn(s1)
        s2 = Fqdn(s2)
        l1 := Split(s1)
index ec2f7ab7bb7e296d0ab086450049f9287bc0d4ee..605fe6c5c35c7cb3e31392fc65b783863d1fb510 100644 (file)
@@ -9,42 +9,35 @@
 package dns
 
 //go:generate go run msg_generate.go
+//go:generate go run compress_generate.go
 
 import (
        crand "crypto/rand"
        "encoding/binary"
+       "fmt"
        "math/big"
        "math/rand"
        "strconv"
+       "sync"
 )
 
-func init() {
-       // Initialize default math/rand source using crypto/rand to provide better
-       // security without the performance trade-off.
-       buf := make([]byte, 8)
-       _, err := crand.Read(buf)
-       if err != nil {
-               // Failed to read from cryptographic source, fallback to default initial
-               // seed (1) by returning early
-               return
-       }
-       seed := binary.BigEndian.Uint64(buf)
-       rand.Seed(int64(seed))
-}
-
-const maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
+const (
+       maxCompressionOffset    = 2 << 13 // We have 14 bits for the compression pointer
+       maxDomainNameWireOctets = 255     // See RFC 1035 section 2.3.4
+)
 
 var (
        ErrAlg           error = &Error{err: "bad algorithm"}                  // ErrAlg indicates an error with the (DNSSEC) algorithm.
        ErrAuth          error = &Error{err: "bad authentication"}             // ErrAuth indicates an error in the TSIG authentication.
-       ErrBuf           error = &Error{err: "buffer size too small"}          // ErrBuf indicates that the buffer used it too small for the message.
-       ErrConnEmpty     error = &Error{err: "conn has no connection"}         // ErrConnEmpty indicates a connection is being uses before it is initialized.
+       ErrBuf           error = &Error{err: "buffer size too small"}          // ErrBuf indicates that the buffer used is too small for the message.
+       ErrConnEmpty     error = &Error{err: "conn has no connection"}         // ErrConnEmpty indicates a connection is being used before it is initialized.
        ErrExtendedRcode error = &Error{err: "bad extended rcode"}             // ErrExtendedRcode ...
        ErrFqdn          error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot.
        ErrId            error = &Error{err: "id mismatch"}                    // ErrId indicates there is a mismatch with the message's ID.
        ErrKeyAlg        error = &Error{err: "bad key algorithm"}              // ErrKeyAlg indicates that the algorithm in the key is not valid.
        ErrKey           error = &Error{err: "bad key"}
        ErrKeySize       error = &Error{err: "bad key size"}
+       ErrLongDomain    error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)}
        ErrNoSig         error = &Error{err: "no signature found"}
        ErrPrivKey       error = &Error{err: "bad private key"}
        ErrRcode         error = &Error{err: "bad rcode"}
@@ -58,7 +51,7 @@ var (
        ErrTruncated     error = &Error{err: "failed to unpack truncated message"} // ErrTruncated indicates that we failed to unpack a truncated message. We unpacked as much as we had so Msg can still be used, if desired.
 )
 
-// Id, by default, returns a 16 bits random number to be used as a
+// Id by default, returns a 16 bits random number to be used as a
 // message id. The random provided should be good enough. This being a
 // variable the function can be reassigned to a custom function.
 // For instance, to make it return a static value:
@@ -66,11 +59,45 @@ var (
 //     dns.Id = func() uint16 { return 3 }
 var Id func() uint16 = id
 
+var (
+       idLock sync.Mutex
+       idRand *rand.Rand
+)
+
 // id returns a 16 bits random number to be used as a
 // message id. The random provided should be good enough.
 func id() uint16 {
-       id32 := rand.Uint32()
-       return uint16(id32)
+       idLock.Lock()
+
+       if idRand == nil {
+               // This (partially) works around
+               // https://github.com/golang/go/issues/11833 by only
+               // seeding idRand upon the first call to id.
+
+               var seed int64
+               var buf [8]byte
+
+               if _, err := crand.Read(buf[:]); err == nil {
+                       seed = int64(binary.LittleEndian.Uint64(buf[:]))
+               } else {
+                       seed = rand.Int63()
+               }
+
+               idRand = rand.New(rand.NewSource(seed))
+       }
+
+       // The call to idRand.Uint32 must be within the
+       // mutex lock because *rand.Rand is not safe for
+       // concurrent use.
+       //
+       // There is no added performance overhead to calling
+       // idRand.Uint32 inside a mutex lock over just
+       // calling rand.Uint32 as the global math/rand rng
+       // is internally protected by a sync.Mutex.
+       id := uint16(idRand.Uint32())
+
+       idLock.Unlock()
+       return id
 }
 
 // MsgHdr is a a manually-unpacked version of (id, bits).
@@ -203,12 +230,6 @@ func packDomainName(s string, msg []byte, off int, compression map[string]int, c
                                        bs[j] = bs[j+2]
                                }
                                ls -= 2
-                       } else if bs[i] == 't' {
-                               bs[i] = '\t'
-                       } else if bs[i] == 'r' {
-                               bs[i] = '\r'
-                       } else if bs[i] == 'n' {
-                               bs[i] = '\n'
                        }
                        escapedDot = bs[i] == '.'
                        bsFresh = false
@@ -247,7 +268,9 @@ func packDomainName(s string, msg []byte, off int, compression map[string]int, c
                                bsFresh = true
                        }
                        // Don't try to compress '.'
-                       if compress && roBs[begin:] != "." {
+                       // We should only compress when compress it true, but we should also still pick
+                       // up names that can be used for *future* compression(s).
+                       if compression != nil && roBs[begin:] != "." {
                                if p, ok := compression[roBs[begin:]]; !ok {
                                        // Only offsets smaller than this can be used.
                                        if offset < maxCompressionOffset {
@@ -311,6 +334,7 @@ func UnpackDomainName(msg []byte, off int) (string, int, error) {
        s := make([]byte, 0, 64)
        off1 := 0
        lenmsg := len(msg)
+       maxLen := maxDomainNameWireOctets
        ptr := 0 // number of pointers followed
 Loop:
        for {
@@ -335,12 +359,10 @@ Loop:
                                        fallthrough
                                case '"', '\\':
                                        s = append(s, '\\', b)
-                               case '\t':
-                                       s = append(s, '\\', 't')
-                               case '\r':
-                                       s = append(s, '\\', 'r')
+                                       // presentation-format \X escapes add an extra byte
+                                       maxLen += 1
                                default:
-                                       if b < 32 || b >= 127 { // unprintable use \DDD
+                                       if b < 32 || b >= 127 { // unprintable, use \DDD
                                                var buf [3]byte
                                                bufs := strconv.AppendInt(buf[:0], int64(b), 10)
                                                s = append(s, '\\')
@@ -350,6 +372,8 @@ Loop:
                                                for _, r := range bufs {
                                                        s = append(s, r)
                                                }
+                                               // presentation-format \DDD escapes add 3 extra bytes
+                                               maxLen += 3
                                        } else {
                                                s = append(s, b)
                                        }
@@ -374,6 +398,9 @@ Loop:
                        if ptr++; ptr > 10 {
                                return "", lenmsg, &Error{err: "too many compression pointers"}
                        }
+                       // pointer should guarantee that it advances and points forwards at least
+                       // but the condition on previous three lines guarantees that it's
+                       // at least loop-free
                        off = (c^0xC0)<<8 | int(c1)
                default:
                        // 0x80 and 0x40 are reserved
@@ -385,6 +412,9 @@ Loop:
        }
        if len(s) == 0 {
                s = []byte(".")
+       } else if len(s) >= maxLen {
+               // error if the name is too long, but don't throw it away
+               return string(s), lenmsg, ErrLongDomain
        }
        return string(s), off1, nil
 }
@@ -431,12 +461,6 @@ func packTxtString(s string, msg []byte, offset int, tmp []byte) (int, error) {
                        if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
                                msg[offset] = dddToByte(bs[i:])
                                i += 2
-                       } else if bs[i] == 't' {
-                               msg[offset] = '\t'
-                       } else if bs[i] == 'r' {
-                               msg[offset] = '\r'
-                       } else if bs[i] == 'n' {
-                               msg[offset] = '\n'
                        } else {
                                msg[offset] = bs[i]
                        }
@@ -508,12 +532,6 @@ func unpackTxtString(msg []byte, offset int) (string, int, error) {
                switch b {
                case '"', '\\':
                        s = append(s, '\\', b)
-               case '\t':
-                       s = append(s, `\t`...)
-               case '\r':
-                       s = append(s, `\r`...)
-               case '\n':
-                       s = append(s, `\n`...)
                default:
                        if b < 32 || b > 127 { // unprintable
                                var buf [3]byte
@@ -732,12 +750,10 @@ func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
 
        // We need the uncompressed length here, because we first pack it and then compress it.
        msg = buf
-       compress := dns.Compress
-       dns.Compress = false
-       if packLen := dns.Len() + 1; len(msg) < packLen {
+       uncompressedLen := compressedLen(dns, false)
+       if packLen := uncompressedLen + 1; len(msg) < packLen {
                msg = make([]byte, packLen)
        }
-       dns.Compress = compress
 
        // Pack it in: header and then the pieces.
        off := 0
@@ -781,9 +797,6 @@ func (dns *Msg) Unpack(msg []byte) (err error) {
        if dh, off, err = unpackMsgHdr(msg, off); err != nil {
                return err
        }
-       if off == len(msg) {
-               return ErrTruncated
-       }
 
        dns.Id = dh.Id
        dns.Response = (dh.Bits & _QR) != 0
@@ -797,6 +810,10 @@ func (dns *Msg) Unpack(msg []byte) (err error) {
        dns.CheckingDisabled = (dh.Bits & _CD) != 0
        dns.Rcode = int(dh.Bits & 0xF)
 
+       if off == len(msg) {
+               return ErrTruncated
+       }
+
        // Optimistically use the count given to us in the header
        dns.Question = make([]Question, 0, int(dh.Qdcount))
 
@@ -889,16 +906,18 @@ func (dns *Msg) String() string {
 // If dns.Compress is true compression it is taken into account. Len()
 // is provided to be a faster way to get the size of the resulting packet,
 // than packing it, measuring the size and discarding the buffer.
-func (dns *Msg) Len() int {
+func (dns *Msg) Len() int { return compressedLen(dns, dns.Compress) }
+
+// compressedLen returns the message length when in compressed wire format
+// when compress is true, otherwise the uncompressed length is returned.
+func compressedLen(dns *Msg, compress bool) int {
        // We always return one more than needed.
        l := 12 // Message header is always 12 bytes
-       var compression map[string]int
-       if dns.Compress {
-               compression = make(map[string]int)
-       }
+       compression := map[string]int{}
+
        for i := 0; i < len(dns.Question); i++ {
                l += dns.Question[i].len()
-               if dns.Compress {
+               if compress {
                        compressionLenHelper(compression, dns.Question[i].Name)
                }
        }
@@ -907,7 +926,7 @@ func (dns *Msg) Len() int {
                        continue
                }
                l += dns.Answer[i].len()
-               if dns.Compress {
+               if compress {
                        k, ok := compressionLenSearch(compression, dns.Answer[i].Header().Name)
                        if ok {
                                l += 1 - k
@@ -925,7 +944,7 @@ func (dns *Msg) Len() int {
                        continue
                }
                l += dns.Ns[i].len()
-               if dns.Compress {
+               if compress {
                        k, ok := compressionLenSearch(compression, dns.Ns[i].Header().Name)
                        if ok {
                                l += 1 - k
@@ -943,7 +962,7 @@ func (dns *Msg) Len() int {
                        continue
                }
                l += dns.Extra[i].len()
-               if dns.Compress {
+               if compress {
                        k, ok := compressionLenSearch(compression, dns.Extra[i].Header().Name)
                        if ok {
                                l += 1 - k
@@ -991,97 +1010,6 @@ func compressionLenSearch(c map[string]int, s string) (int, bool) {
        return 0, false
 }
 
-// TODO(miek): should add all types, because the all can be *used* for compression. Autogenerate from msg_generate and put in zmsg.go
-func compressionLenHelperType(c map[string]int, r RR) {
-       switch x := r.(type) {
-       case *NS:
-               compressionLenHelper(c, x.Ns)
-       case *MX:
-               compressionLenHelper(c, x.Mx)
-       case *CNAME:
-               compressionLenHelper(c, x.Target)
-       case *PTR:
-               compressionLenHelper(c, x.Ptr)
-       case *SOA:
-               compressionLenHelper(c, x.Ns)
-               compressionLenHelper(c, x.Mbox)
-       case *MB:
-               compressionLenHelper(c, x.Mb)
-       case *MG:
-               compressionLenHelper(c, x.Mg)
-       case *MR:
-               compressionLenHelper(c, x.Mr)
-       case *MF:
-               compressionLenHelper(c, x.Mf)
-       case *MD:
-               compressionLenHelper(c, x.Md)
-       case *RT:
-               compressionLenHelper(c, x.Host)
-       case *RP:
-               compressionLenHelper(c, x.Mbox)
-               compressionLenHelper(c, x.Txt)
-       case *MINFO:
-               compressionLenHelper(c, x.Rmail)
-               compressionLenHelper(c, x.Email)
-       case *AFSDB:
-               compressionLenHelper(c, x.Hostname)
-       case *SRV:
-               compressionLenHelper(c, x.Target)
-       case *NAPTR:
-               compressionLenHelper(c, x.Replacement)
-       case *RRSIG:
-               compressionLenHelper(c, x.SignerName)
-       case *NSEC:
-               compressionLenHelper(c, x.NextDomain)
-               // HIP?
-       }
-}
-
-// Only search on compressing these types.
-func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
-       switch x := r.(type) {
-       case *NS:
-               return compressionLenSearch(c, x.Ns)
-       case *MX:
-               return compressionLenSearch(c, x.Mx)
-       case *CNAME:
-               return compressionLenSearch(c, x.Target)
-       case *DNAME:
-               return compressionLenSearch(c, x.Target)
-       case *PTR:
-               return compressionLenSearch(c, x.Ptr)
-       case *SOA:
-               k, ok := compressionLenSearch(c, x.Ns)
-               k1, ok1 := compressionLenSearch(c, x.Mbox)
-               if !ok && !ok1 {
-                       return 0, false
-               }
-               return k + k1, true
-       case *MB:
-               return compressionLenSearch(c, x.Mb)
-       case *MG:
-               return compressionLenSearch(c, x.Mg)
-       case *MR:
-               return compressionLenSearch(c, x.Mr)
-       case *MF:
-               return compressionLenSearch(c, x.Mf)
-       case *MD:
-               return compressionLenSearch(c, x.Md)
-       case *RT:
-               return compressionLenSearch(c, x.Host)
-       case *MINFO:
-               k, ok := compressionLenSearch(c, x.Rmail)
-               k1, ok1 := compressionLenSearch(c, x.Email)
-               if !ok && !ok1 {
-                       return 0, false
-               }
-               return k + k1, true
-       case *AFSDB:
-               return compressionLenSearch(c, x.Hostname)
-       }
-       return 0, false
-}
-
 // Copy returns a new RR which is a deep-copy of r.
 func Copy(r RR) RR { r1 := r.copy(); return r1 }
 
index 166b3af00c830e26f9eb16eb048bcc98d6891151..4d9f81d4329a3b68d9ca32fa24e8da0047bf900a 100644 (file)
@@ -117,9 +117,9 @@ return off, err
                        switch {
                        case st.Tag(i) == `dns:"-"`: // ignored
                        case st.Tag(i) == `dns:"cdomain-name"`:
-                               fallthrough
-                       case st.Tag(i) == `dns:"domain-name"`:
                                o("off, err = PackDomainName(rr.%s, msg, off, compression, compress)\n")
+                       case st.Tag(i) == `dns:"domain-name"`:
+                               o("off, err = PackDomainName(rr.%s, msg, off, compression, false)\n")
                        case st.Tag(i) == `dns:"a"`:
                                o("off, err = packDataA(rr.%s, msg, off)\n")
                        case st.Tag(i) == `dns:"aaaa"`:
@@ -139,6 +139,18 @@ return off, err
                        case st.Tag(i) == `dns:"base64"`:
                                o("off, err = packStringBase64(rr.%s, msg, off)\n")
 
+                       case strings.HasPrefix(st.Tag(i), `dns:"size-hex:SaltLength`):
+                               // directly write instead of using o() so we get the error check in the correct place
+                               field := st.Field(i).Name()
+                               fmt.Fprintf(b, `// Only pack salt if value is not "-", i.e. empty
+if rr.%s != "-" {
+  off, err = packStringHex(rr.%s, msg, off)
+  if err != nil {
+    return off, err
+  }
+}
+`, field, field)
+                               continue
                        case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex
                                fallthrough
                        case st.Tag(i) == `dns:"hex"`:
@@ -166,7 +178,7 @@ return off, err
                        }
                }
                // We have packed everything, only now we know the rdlength of this RR
-               fmt.Fprintln(b, "rr.Header().Rdlength = uint16(off- headerEnd)")
+               fmt.Fprintln(b, "rr.Header().Rdlength = uint16(off-headerEnd)")
                fmt.Fprintln(b, "return off, nil }\n")
        }
 
index e7a9500cc074afaae6d6554be0630fbf340283f4..8d415c92a376f9edf9a14e0f44f2c5f178b5e95c 100644 (file)
@@ -96,7 +96,7 @@ func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte,
                return hdr, len(msg), msg, err
        }
        msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength)
-       return hdr, off, msg, nil
+       return hdr, off, msg, err
 }
 
 // pack packs an RR header, returning the offset to the end of the header.
@@ -142,6 +142,11 @@ func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []b
 }
 
 func fromBase32(s []byte) (buf []byte, err error) {
+       for i, b := range s {
+               if b >= 'a' && b <= 'z' {
+                       s[i] = b - 32
+               }
+       }
        buflen := base32.HexEncoding.DecodedLen(len(s))
        buf = make([]byte, buflen)
        n, err := base32.HexEncoding.Decode(buf, s)
@@ -263,8 +268,6 @@ func unpackString(msg []byte, off int) (string, int, error) {
                switch b {
                case '"', '\\':
                        s = append(s, '\\', b)
-               case '\t', '\r', '\n':
-                       s = append(s, b)
                default:
                        if b < 32 || b > 127 { // unprintable
                                var buf [3]byte
index 6f10f3e65bcc6f2d4fb2b5b1b77317e8d6cd2938..9b908c447863639c327bfe9ae413267cf6a11179 100644 (file)
@@ -3,7 +3,6 @@ package dns
 import (
        "crypto/sha1"
        "hash"
-       "io"
        "strings"
 )
 
@@ -36,75 +35,63 @@ func HashName(label string, ha uint8, iter uint16, salt string) string {
        }
 
        // k = 0
-       name = append(name, wire...)
-       io.WriteString(s, string(name))
+       s.Write(name)
+       s.Write(wire)
        nsec3 := s.Sum(nil)
        // k > 0
        for k := uint16(0); k < iter; k++ {
                s.Reset()
-               nsec3 = append(nsec3, wire...)
-               io.WriteString(s, string(nsec3))
-               nsec3 = s.Sum(nil)
+               s.Write(nsec3)
+               s.Write(wire)
+               nsec3 = s.Sum(nsec3[:0])
        }
        return toBase32(nsec3)
 }
 
-// Denialer is an interface that should be implemented by types that are used to denial
-// answers in DNSSEC.
-type Denialer interface {
-       // Cover will check if the (unhashed) name is being covered by this NSEC or NSEC3.
-       Cover(name string) bool
-       // Match will check if the ownername matches the (unhashed) name for this NSEC3 or NSEC3.
-       Match(name string) bool
-}
-
-// Cover implements the Denialer interface.
-func (rr *NSEC) Cover(name string) bool {
-       return true
-}
-
-// Match implements the Denialer interface.
-func (rr *NSEC) Match(name string) bool {
-       return true
-}
-
-// Cover implements the Denialer interface.
+// Cover returns true if a name is covered by the NSEC3 record
 func (rr *NSEC3) Cover(name string) bool {
-       // FIXME(miek): check if the zones match
-       // FIXME(miek): check if we're not dealing with parent nsec3
-       hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
-       labels := Split(rr.Hdr.Name)
-       if len(labels) < 2 {
+       nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
+       owner := strings.ToUpper(rr.Hdr.Name)
+       labelIndices := Split(owner)
+       if len(labelIndices) < 2 {
                return false
        }
-       hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the dot
-       if hash == rr.NextDomain {
-               return false // empty interval
-       }
-       if hash > rr.NextDomain { // last name, points to apex
-               // hname > hash
-               // hname > rr.NextDomain
-               // TODO(miek)
+       ownerHash := owner[:labelIndices[1]-1]
+       ownerZone := owner[labelIndices[1]:]
+       if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
+               return false
        }
-       if hname <= hash {
+
+       nextHash := rr.NextDomain
+       if ownerHash == nextHash { // empty interval
                return false
        }
-       if hname >= rr.NextDomain {
+       if ownerHash > nextHash { // end of zone
+               if nameHash > ownerHash { // covered since there is nothing after ownerHash
+                       return true
+               }
+               return nameHash < nextHash // if nameHash is before beginning of zone it is covered
+       }
+       if nameHash < ownerHash { // nameHash is before ownerHash, not covered
                return false
        }
-       return true
+       return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash)
 }
 
-// Match implements the Denialer interface.
+// Match returns true if a name matches the NSEC3 record
 func (rr *NSEC3) Match(name string) bool {
-       // FIXME(miek): Check if we are in the same zone
-       hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
-       labels := Split(rr.Hdr.Name)
-       if len(labels) < 2 {
+       nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
+       owner := strings.ToUpper(rr.Hdr.Name)
+       labelIndices := Split(owner)
+       if len(labelIndices) < 2 {
+               return false
+       }
+       ownerHash := owner[:labelIndices[1]-1]
+       ownerZone := owner[labelIndices[1]:]
+       if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
                return false
        }
-       hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the .
-       if hash == hname {
+       if ownerHash == nameHash {
                return true
        }
        return false
index 099dac9486d5844ce432de80ec7ec464d6ff8bc2..f6e7a47a6e8abbdaf52967cb367bbe6c8531bc93 100644 (file)
@@ -6,10 +6,10 @@ var StringToType = reverseInt16(TypeToString)
 // StringToClass is the reverse of ClassToString, needed for string parsing.
 var StringToClass = reverseInt16(ClassToString)
 
-// Map of opcodes strings.
+// StringToOpcode is a map of opcodes to strings.
 var StringToOpcode = reverseInt(OpcodeToString)
 
-// Map of rcodes strings.
+// StringToRcode is a map of rcodes to strings.
 var StringToRcode = reverseInt(RcodeToString)
 
 // Reverse a map
index 0e83797fb5979c7cea456bb80b769fc980a87f1d..a76f1d83fc0a3049432104216c891b83f22f6cb0 100644 (file)
@@ -278,8 +278,7 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
                                return
                        }
                        neworigin := origin // There may be optionally a new origin set after the filename, if not use current one
-                       l := <-c
-                       switch l.value {
+                       switch l := <-c; l.value {
                        case zBlank:
                                l := <-c
                                if l.value == zString {
@@ -314,7 +313,7 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
                                t <- &Token{Error: &ParseError{f, "too deeply nested $INCLUDE", l}}
                                return
                        }
-                       parseZone(r1, l.token, neworigin, t, include+1)
+                       parseZone(r1, neworigin, l.token, t, include+1)
                        st = zExpectOwnerDir
                case zExpectDirTtlBl:
                        if l.value != zBlank {
@@ -627,6 +626,7 @@ func zlexer(s *scan, c chan lex) {
                        if stri > 0 {
                                l.value = zString
                                l.token = string(str[:stri])
+                               l.tokenUpper = strings.ToUpper(l.token)
                                l.length = stri
                                debug.Printf("[4 %+v]", l.token)
                                c <- l
@@ -663,6 +663,7 @@ func zlexer(s *scan, c chan lex) {
                                        owner = true
                                        l.value = zNewline
                                        l.token = "\n"
+                                       l.tokenUpper = l.token
                                        l.length = 1
                                        l.comment = string(com[:comi])
                                        debug.Printf("[3 %+v %+v]", l.token, l.comment)
@@ -696,6 +697,7 @@ func zlexer(s *scan, c chan lex) {
                                }
                                l.value = zNewline
                                l.token = "\n"
+                               l.tokenUpper = l.token
                                l.length = 1
                                debug.Printf("[1 %+v]", l.token)
                                c <- l
@@ -740,6 +742,7 @@ func zlexer(s *scan, c chan lex) {
                        if stri != 0 {
                                l.value = zString
                                l.token = string(str[:stri])
+                               l.tokenUpper = strings.ToUpper(l.token)
                                l.length = stri
 
                                debug.Printf("[%+v]", l.token)
@@ -750,6 +753,7 @@ func zlexer(s *scan, c chan lex) {
                        // send quote itself as separate token
                        l.value = zQuote
                        l.token = "\""
+                       l.tokenUpper = l.token
                        l.length = 1
                        c <- l
                        quote = !quote
@@ -775,6 +779,7 @@ func zlexer(s *scan, c chan lex) {
                                brace--
                                if brace < 0 {
                                        l.token = "extra closing brace"
+                                       l.tokenUpper = l.token
                                        l.err = true
                                        debug.Printf("[%+v]", l.token)
                                        c <- l
@@ -799,11 +804,18 @@ func zlexer(s *scan, c chan lex) {
        if stri > 0 {
                // Send remainder
                l.token = string(str[:stri])
+               l.tokenUpper = strings.ToUpper(l.token)
                l.length = stri
                l.value = zString
                debug.Printf("[%+v]", l.token)
                c <- l
        }
+       if brace != 0 {
+               l.token = "unbalanced brace"
+               l.tokenUpper = l.token
+               l.err = true
+               c <- l
+       }
 }
 
 // Extract the class number from CLASSxx
@@ -812,8 +824,8 @@ func classToInt(token string) (uint16, bool) {
        if len(token) < offset+1 {
                return 0, false
        }
-       class, ok := strconv.Atoi(token[offset:])
-       if ok != nil || class > maxUint16 {
+       class, err := strconv.ParseUint(token[offset:], 10, 16)
+       if err != nil {
                return 0, false
        }
        return uint16(class), true
@@ -825,8 +837,8 @@ func typeToInt(token string) (uint16, bool) {
        if len(token) < offset+1 {
                return 0, false
        }
-       typ, ok := strconv.Atoi(token[offset:])
-       if ok != nil || typ > maxUint16 {
+       typ, err := strconv.ParseUint(token[offset:], 10, 16)
+       if err != nil {
                return 0, false
        }
        return uint16(typ), true
index e521dc063e95af6f89d2b3d28fae116bb10c4803..b8b18fd776dd0a4d651353d820dba68fef48818e 100644 (file)
@@ -64,74 +64,63 @@ func endingToString(c chan lex, errstr, f string) (string, *ParseError, string)
        return s, nil, l.comment
 }
 
-// A remainder of the rdata with embedded spaces, return the parsed string slice (sans the spaces)
-// or an error
+// A remainder of the rdata with embedded spaces, split on unquoted whitespace
+// and return the parsed string slice or an error
 func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) {
        // Get the remaining data until we see a zNewline
-       quote := false
        l := <-c
-       var s []string
        if l.err {
-               return s, &ParseError{f, errstr, l}, ""
-       }
-       switch l.value == zQuote {
-       case true: // A number of quoted string
-               s = make([]string, 0)
-               empty := true
-               for l.value != zNewline && l.value != zEOF {
-                       if l.err {
-                               return nil, &ParseError{f, errstr, l}, ""
-                       }
-                       switch l.value {
-                       case zString:
-                               empty = false
-                               if len(l.token) > 255 {
-                                       // split up tokens that are larger than 255 into 255-chunks
-                                       sx := []string{}
-                                       p, i := 0, 255
-                                       for {
-                                               if i <= len(l.token) {
-                                                       sx = append(sx, l.token[p:i])
-                                               } else {
-                                                       sx = append(sx, l.token[p:])
-                                                       break
-
-                                               }
-                                               p, i = p+255, i+255
+               return nil, &ParseError{f, errstr, l}, ""
+       }
+
+       // Build the slice
+       s := make([]string, 0)
+       quote := false
+       empty := false
+       for l.value != zNewline && l.value != zEOF {
+               if l.err {
+                       return nil, &ParseError{f, errstr, l}, ""
+               }
+               switch l.value {
+               case zString:
+                       empty = false
+                       if len(l.token) > 255 {
+                               // split up tokens that are larger than 255 into 255-chunks
+                               sx := []string{}
+                               p, i := 0, 255
+                               for {
+                                       if i <= len(l.token) {
+                                               sx = append(sx, l.token[p:i])
+                                       } else {
+                                               sx = append(sx, l.token[p:])
+                                               break
+
                                        }
-                                       s = append(s, sx...)
-                                       break
+                                       p, i = p+255, i+255
                                }
+                               s = append(s, sx...)
+                               break
+                       }
 
-                               s = append(s, l.token)
-                       case zBlank:
-                               if quote {
-                                       // zBlank can only be seen in between txt parts.
-                                       return nil, &ParseError{f, errstr, l}, ""
-                               }
-                       case zQuote:
-                               if empty && quote {
-                                       s = append(s, "")
-                               }
-                               quote = !quote
-                               empty = true
-                       default:
+                       s = append(s, l.token)
+               case zBlank:
+                       if quote {
+                               // zBlank can only be seen in between txt parts.
                                return nil, &ParseError{f, errstr, l}, ""
                        }
-                       l = <-c
-               }
-               if quote {
-                       return nil, &ParseError{f, errstr, l}, ""
-               }
-       case false: // Unquoted text record
-               s = make([]string, 1)
-               for l.value != zNewline && l.value != zEOF {
-                       if l.err {
-                               return s, &ParseError{f, errstr, l}, ""
+               case zQuote:
+                       if empty && quote {
+                               s = append(s, "")
                        }
-                       s[0] += l.token
-                       l = <-c
+                       quote = !quote
+                       empty = true
+               default:
+                       return nil, &ParseError{f, errstr, l}, ""
                }
+               l = <-c
+       }
+       if quote {
+               return nil, &ParseError{f, errstr, l}, ""
        }
        return s, nil, l.comment
 }
@@ -458,7 +447,7 @@ func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad MX Pref", l}, ""
        }
@@ -487,7 +476,7 @@ func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil {
                return nil, &ParseError{f, "bad RT Preference", l}, ""
        }
@@ -517,7 +506,7 @@ func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad AFSDB Subtype", l}, ""
        }
@@ -562,7 +551,7 @@ func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad KX Pref", l}, ""
        }
@@ -676,7 +665,7 @@ func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
                if l.err {
                        return nil, &ParseError{f, "bad SOA zone parameter", l}, ""
                }
-               if j, e := strconv.Atoi(l.token); e != nil {
+               if j, e := strconv.ParseUint(l.token, 10, 32); e != nil {
                        if i == 0 {
                                // Serial should be a number
                                return nil, &ParseError{f, "bad SOA zone parameter", l}, ""
@@ -716,21 +705,21 @@ func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad SRV Priority", l}, ""
        }
        rr.Priority = uint16(i)
        <-c     // zBlank
        l = <-c // zString
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad SRV Weight", l}, ""
        }
        rr.Weight = uint16(i)
        <-c     // zBlank
        l = <-c // zString
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad SRV Port", l}, ""
        }
@@ -760,14 +749,14 @@ func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad NAPTR Order", l}, ""
        }
        rr.Order = uint16(i)
        <-c     // zBlank
        l = <-c // zString
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad NAPTR Preference", l}, ""
        }
@@ -896,7 +885,7 @@ func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 32)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad LOC Latitude", l}, ""
        }
@@ -908,7 +897,7 @@ func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
                goto East
        }
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 32)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad LOC Latitude minutes", l}, ""
        }
@@ -934,7 +923,7 @@ East:
        // East
        <-c // zBlank
        l = <-c
-       if i, e := strconv.Atoi(l.token); e != nil || l.err {
+       if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err {
                return nil, &ParseError{f, "bad LOC Longitude", l}, ""
        } else {
                rr.Longitude = 1000 * 60 * 60 * uint32(i)
@@ -945,7 +934,7 @@ East:
        if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
                goto Altitude
        }
-       if i, e := strconv.Atoi(l.token); e != nil || l.err {
+       if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err {
                return nil, &ParseError{f, "bad LOC Longitude minutes", l}, ""
        } else {
                rr.Longitude += 1000 * 60 * uint32(i)
@@ -1027,7 +1016,7 @@ func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, l.comment
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad HIP PublicKeyAlgorithm", l}, ""
        }
@@ -1088,14 +1077,14 @@ func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        }
        if v, ok := StringToCertType[l.token]; ok {
                rr.Type = v
-       } else if i, e := strconv.Atoi(l.token); e != nil {
+       } else if i, e := strconv.ParseUint(l.token, 10, 16); e != nil {
                return nil, &ParseError{f, "bad CERT Type", l}, ""
        } else {
                rr.Type = uint16(i)
        }
        <-c     // zBlank
        l = <-c // zString
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad CERT KeyTag", l}, ""
        }
@@ -1104,7 +1093,7 @@ func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        l = <-c // zString
        if v, ok := StringToAlgorithm[l.token]; ok {
                rr.Algorithm = v
-       } else if i, e := strconv.Atoi(l.token); e != nil {
+       } else if i, e := strconv.ParseUint(l.token, 10, 8); e != nil {
                return nil, &ParseError{f, "bad CERT Algorithm", l}, ""
        } else {
                rr.Algorithm = uint8(i)
@@ -1159,21 +1148,21 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        }
        <-c // zBlank
        l = <-c
-       i, err := strconv.Atoi(l.token)
+       i, err := strconv.ParseUint(l.token, 10, 8)
        if err != nil || l.err {
                return nil, &ParseError{f, "bad RRSIG Algorithm", l}, ""
        }
        rr.Algorithm = uint8(i)
        <-c // zBlank
        l = <-c
-       i, err = strconv.Atoi(l.token)
+       i, err = strconv.ParseUint(l.token, 10, 8)
        if err != nil || l.err {
                return nil, &ParseError{f, "bad RRSIG Labels", l}, ""
        }
        rr.Labels = uint8(i)
        <-c // zBlank
        l = <-c
-       i, err = strconv.Atoi(l.token)
+       i, err = strconv.ParseUint(l.token, 10, 32)
        if err != nil || l.err {
                return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, ""
        }
@@ -1204,7 +1193,7 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        }
        <-c // zBlank
        l = <-c
-       i, err = strconv.Atoi(l.token)
+       i, err = strconv.ParseUint(l.token, 10, 16)
        if err != nil || l.err {
                return nil, &ParseError{f, "bad RRSIG KeyTag", l}, ""
        }
@@ -1285,21 +1274,21 @@ func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, l.comment
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad NSEC3 Hash", l}, ""
        }
        rr.Hash = uint8(i)
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad NSEC3 Flags", l}, ""
        }
        rr.Flags = uint8(i)
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad NSEC3 Iterations", l}, ""
        }
@@ -1353,21 +1342,21 @@ func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, strin
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, ""
        }
        rr.Hash = uint8(i)
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, ""
        }
        rr.Flags = uint8(i)
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, ""
        }
@@ -1451,14 +1440,14 @@ func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad SSHFP Algorithm", l}, ""
        }
        rr.Algorithm = uint8(i)
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad SSHFP Type", l}, ""
        }
@@ -1480,21 +1469,21 @@ func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, str
        if l.length == 0 {
                return rr, nil, l.comment
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad " + typ + " Flags", l}, ""
        }
        rr.Flags = uint16(i)
        <-c     // zBlank
        l = <-c // zString
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad " + typ + " Protocol", l}, ""
        }
        rr.Protocol = uint8(i)
        <-c     // zBlank
        l = <-c // zString
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
        }
@@ -1536,21 +1525,21 @@ func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, l.comment
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad RKEY Flags", l}, ""
        }
        rr.Flags = uint16(i)
        <-c     // zBlank
        l = <-c // zString
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad RKEY Protocol", l}, ""
        }
        rr.Protocol = uint8(i)
        <-c     // zBlank
        l = <-c // zString
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad RKEY Algorithm", l}, ""
        }
@@ -1621,14 +1610,14 @@ func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string)
        if l.length == 0 {
                return rr, nil, l.comment
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, ""
        }
        rr.KeyTag = uint16(i)
        <-c // zBlank
        l = <-c
-       if i, e := strconv.Atoi(l.token); e != nil {
+       if i, e = strconv.ParseUint(l.token, 10, 8); e != nil {
                i, ok := StringToAlgorithm[l.tokenUpper]
                if !ok || l.err {
                        return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
@@ -1639,7 +1628,7 @@ func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string)
        }
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad " + typ + " DigestType", l}, ""
        }
@@ -1680,14 +1669,14 @@ func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, l.comment
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad TA KeyTag", l}, ""
        }
        rr.KeyTag = uint16(i)
        <-c // zBlank
        l = <-c
-       if i, e := strconv.Atoi(l.token); e != nil {
+       if i, e := strconv.ParseUint(l.token, 10, 8); e != nil {
                i, ok := StringToAlgorithm[l.tokenUpper]
                if !ok || l.err {
                        return nil, &ParseError{f, "bad TA Algorithm", l}, ""
@@ -1698,7 +1687,7 @@ func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        }
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad TA DigestType", l}, ""
        }
@@ -1718,21 +1707,21 @@ func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, l.comment
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad TLSA Usage", l}, ""
        }
        rr.Usage = uint8(i)
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad TLSA Selector", l}, ""
        }
        rr.Selector = uint8(i)
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 8)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad TLSA MatchingType", l}, ""
        }
@@ -1746,6 +1735,41 @@ func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        return rr, nil, c1
 }
 
+func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+       rr := new(SMIMEA)
+       rr.Hdr = h
+       l := <-c
+       if l.length == 0 {
+               return rr, nil, l.comment
+       }
+       i, e := strconv.ParseUint(l.token, 10, 8)
+       if e != nil || l.err {
+               return nil, &ParseError{f, "bad SMIMEA Usage", l}, ""
+       }
+       rr.Usage = uint8(i)
+       <-c // zBlank
+       l = <-c
+       i, e = strconv.ParseUint(l.token, 10, 8)
+       if e != nil || l.err {
+               return nil, &ParseError{f, "bad SMIMEA Selector", l}, ""
+       }
+       rr.Selector = uint8(i)
+       <-c // zBlank
+       l = <-c
+       i, e = strconv.ParseUint(l.token, 10, 8)
+       if e != nil || l.err {
+               return nil, &ParseError{f, "bad SMIMEA MatchingType", l}, ""
+       }
+       rr.MatchingType = uint8(i)
+       // So this needs be e2 (i.e. different than e), because...??t
+       s, e2, c1 := endingToString(c, "bad SMIMEA Certificate", f)
+       if e2 != nil {
+               return nil, e2, c1
+       }
+       rr.Certificate = s
+       return rr, nil, c1
+}
+
 func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        rr := new(RFC3597)
        rr.Hdr = h
@@ -1783,6 +1807,18 @@ func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        return rr, nil, c1
 }
 
+func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
+       rr := new(AVC)
+       rr.Hdr = h
+
+       s, e, c1 := endingToTxtSlice(c, "bad AVC Txt", f)
+       if e != nil {
+               return nil, e, ""
+       }
+       rr.Txt = s
+       return rr, nil, c1
+}
+
 func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        rr := new(TXT)
        rr.Hdr = h
@@ -1818,14 +1854,14 @@ func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
                return rr, nil, ""
        }
 
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad URI Priority", l}, ""
        }
        rr.Priority = uint16(i)
        <-c // zBlank
        l = <-c
-       i, e = strconv.Atoi(l.token)
+       i, e = strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad URI Weight", l}, ""
        }
@@ -1864,7 +1900,7 @@ func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad NID Preference", l}, ""
        }
@@ -1887,7 +1923,7 @@ func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad L32 Preference", l}, ""
        }
@@ -1909,7 +1945,7 @@ func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad LP Preference", l}, ""
        }
@@ -1942,7 +1978,7 @@ func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad L64 Preference", l}, ""
        }
@@ -1964,7 +2000,7 @@ func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 32)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad UID Uid", l}, ""
        }
@@ -1979,7 +2015,7 @@ func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 32)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad GID Gid", l}, ""
        }
@@ -1992,9 +2028,12 @@ func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        rr.Hdr = h
        s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f)
        if e != nil {
-               return nil, e, ""
+               return nil, e, c1
+       }
+       if ln := len(s); ln == 0 {
+               return rr, nil, c1
        }
-       rr.Uinfo = s[0] // silently discard anything above
+       rr.Uinfo = s[0] // silently discard anything after the first character-string
        return rr, nil, c1
 }
 
@@ -2006,7 +2045,7 @@ func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, ""
        }
-       i, e := strconv.Atoi(l.token)
+       i, e := strconv.ParseUint(l.token, 10, 16)
        if e != nil || l.err {
                return nil, &ParseError{f, "bad PX Preference", l}, ""
        }
@@ -2052,7 +2091,7 @@ func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
        if l.length == 0 {
                return rr, nil, l.comment
        }
-       i, err := strconv.Atoi(l.token)
+       i, err := strconv.ParseUint(l.token, 10, 8)
        if err != nil || l.err {
                return nil, &ParseError{f, "bad CAA Flag", l}, ""
        }
@@ -2128,8 +2167,10 @@ var typeToparserFunc = map[uint16]parserFunc{
        TypeRP:         {setRP, false},
        TypeRRSIG:      {setRRSIG, true},
        TypeRT:         {setRT, false},
+       TypeSMIMEA:     {setSMIMEA, true},
        TypeSOA:        {setSOA, false},
        TypeSPF:        {setSPF, true},
+       TypeAVC:        {setAVC, true},
        TypeSRV:        {setSRV, false},
        TypeSSHFP:      {setSSHFP, true},
        TypeTALINK:     {setTALINK, false},
index 2b4bff49f27b60ce34527950cb7e16ed31639240..0ca6e008c08b955dce103d7c616ccaeb787cffc7 100644 (file)
@@ -147,7 +147,7 @@ func (mux *ServeMux) match(q string, t uint16) Handler {
                                b[i] |= ('a' - 'A')
                        }
                }
-               if h, ok := mux.z[string(b[:l])]; ok { // 'causes garbage, might want to change the map key
+               if h, ok := mux.z[string(b[:l])]; ok { // causes garbage, might want to change the map key
                        if t != TypeDS {
                                return h
                        }
@@ -339,7 +339,7 @@ func (srv *Server) ListenAndServe() error {
                network := "tcp"
                if srv.Net == "tcp4-tls" {
                        network = "tcp4"
-               } else if srv.Net == "tcp6" {
+               } else if srv.Net == "tcp6-tls" {
                        network = "tcp6"
                }
 
@@ -389,7 +389,9 @@ func (srv *Server) ActivateAndServe() error {
                if srv.UDPSize == 0 {
                        srv.UDPSize = MinMsgSize
                }
-               if t, ok := pConn.(*net.UDPConn); ok {
+               // Check PacketConn interface's type is valid and value
+               // is not nil
+               if t, ok := pConn.(*net.UDPConn); ok && t != nil {
                        if e := setUDPSocketOptions(t); e != nil {
                                return e
                        }
index 2dce06af82f6081d539295a1e98cc9ebb305fe76..f31e9e6843dd2ebd5f568c8473dc9ea9732759b1 100644 (file)
@@ -60,16 +60,15 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
        }
 
        rr.Signature = toBase64(signature)
-       sig := string(signature)
 
-       buf = append(buf, sig...)
+       buf = append(buf, signature...)
        if len(buf) > int(^uint16(0)) {
                return nil, ErrBuf
        }
        // Adjust sig data length
        rdoff := len(mbuf) + 1 + 2 + 2 + 4
        rdlen := binary.BigEndian.Uint16(buf[rdoff:])
-       rdlen += uint16(len(sig))
+       rdlen += uint16(len(signature))
        binary.BigEndian.PutUint16(buf[rdoff:], rdlen)
        // Adjust additional count
        adc := binary.BigEndian.Uint16(buf[10:])
index 34fe6615aa2fb4df741874b378fdff3845690b0c..431e2fb5afca863e6fbc5b5064c7d27de91fee49 100644 (file)
@@ -1,50 +1,11 @@
 package dns
 
 import (
-       "crypto/sha256"
-       "crypto/sha512"
        "crypto/x509"
-       "encoding/hex"
-       "errors"
-       "io"
        "net"
        "strconv"
 )
 
-// CertificateToDANE converts a certificate to a hex string as used in the TLSA record.
-func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) {
-       switch matchingType {
-       case 0:
-               switch selector {
-               case 0:
-                       return hex.EncodeToString(cert.Raw), nil
-               case 1:
-                       return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil
-               }
-       case 1:
-               h := sha256.New()
-               switch selector {
-               case 0:
-                       io.WriteString(h, string(cert.Raw))
-                       return hex.EncodeToString(h.Sum(nil)), nil
-               case 1:
-                       io.WriteString(h, string(cert.RawSubjectPublicKeyInfo))
-                       return hex.EncodeToString(h.Sum(nil)), nil
-               }
-       case 2:
-               h := sha512.New()
-               switch selector {
-               case 0:
-                       io.WriteString(h, string(cert.Raw))
-                       return hex.EncodeToString(h.Sum(nil)), nil
-               case 1:
-                       io.WriteString(h, string(cert.RawSubjectPublicKeyInfo))
-                       return hex.EncodeToString(h.Sum(nil)), nil
-               }
-       }
-       return "", errors.New("dns: bad TLSA MatchingType or TLSA Selector")
-}
-
 // Sign creates a TLSA record from an SSL certificate.
 func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
        r.Hdr.Rrtype = TypeTLSA
index 78365e1c5bac74aef634d522a77ba70d31d373ce..4837b4ab1fd81a3a2df8e682c7717525a1989977 100644 (file)
@@ -9,7 +9,6 @@ import (
        "encoding/binary"
        "encoding/hex"
        "hash"
-       "io"
        "strconv"
        "strings"
        "time"
@@ -124,7 +123,7 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
        default:
                return nil, "", ErrKeyAlg
        }
-       io.WriteString(h, string(buf))
+       h.Write(buf)
        t.MAC = hex.EncodeToString(h.Sum(nil))
        t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
 
@@ -209,6 +208,9 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
                rr.Fudge = 300 // Standard (RFC) default.
        }
 
+       // Replace message ID in header with original ID from TSIG
+       binary.BigEndian.PutUint16(msgbuf[0:2], rr.OrigId)
+
        if requestMAC != "" {
                m := new(macWireFmt)
                m.MACSize = uint16(len(requestMAC) / 2)
index e7370647900acb19ce2486b32bcbeafb2636c281..57f065bc81750ac3941d16b80185c7be2b131704 100644 (file)
@@ -70,6 +70,7 @@ const (
        TypeNSEC3      uint16 = 50
        TypeNSEC3PARAM uint16 = 51
        TypeTLSA       uint16 = 52
+       TypeSMIMEA     uint16 = 53
        TypeHIP        uint16 = 55
        TypeNINFO      uint16 = 56
        TypeRKEY       uint16 = 57
@@ -90,6 +91,7 @@ const (
        TypeEUI64      uint16 = 109
        TypeURI        uint16 = 256
        TypeCAA        uint16 = 257
+       TypeAVC        uint16 = 258
 
        TypeTKEY uint16 = 249
        TypeTSIG uint16 = 250
@@ -113,27 +115,27 @@ const (
        ClassNONE   = 254
        ClassANY    = 255
 
-       // Message Response Codes.
-       RcodeSuccess        = 0
-       RcodeFormatError    = 1
-       RcodeServerFailure  = 2
-       RcodeNameError      = 3
-       RcodeNotImplemented = 4
-       RcodeRefused        = 5
-       RcodeYXDomain       = 6
-       RcodeYXRrset        = 7
-       RcodeNXRrset        = 8
-       RcodeNotAuth        = 9
-       RcodeNotZone        = 10
-       RcodeBadSig         = 16 // TSIG
-       RcodeBadVers        = 16 // EDNS0
-       RcodeBadKey         = 17
-       RcodeBadTime        = 18
-       RcodeBadMode        = 19 // TKEY
-       RcodeBadName        = 20
-       RcodeBadAlg         = 21
-       RcodeBadTrunc       = 22 // TSIG
-       RcodeBadCookie      = 23 // DNS Cookies
+       // Message Response Codes, see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
+       RcodeSuccess        = 0  // NoError   - No Error                          [DNS]
+       RcodeFormatError    = 1  // FormErr   - Format Error                      [DNS]
+       RcodeServerFailure  = 2  // ServFail  - Server Failure                    [DNS]
+       RcodeNameError      = 3  // NXDomain  - Non-Existent Domain               [DNS]
+       RcodeNotImplemented = 4  // NotImp    - Not Implemented                   [DNS]
+       RcodeRefused        = 5  // Refused   - Query Refused                     [DNS]
+       RcodeYXDomain       = 6  // YXDomain  - Name Exists when it should not    [DNS Update]
+       RcodeYXRrset        = 7  // YXRRSet   - RR Set Exists when it should not  [DNS Update]
+       RcodeNXRrset        = 8  // NXRRSet   - RR Set that should exist does not [DNS Update]
+       RcodeNotAuth        = 9  // NotAuth   - Server Not Authoritative for zone [DNS Update]
+       RcodeNotZone        = 10 // NotZone   - Name not contained in zone        [DNS Update/TSIG]
+       RcodeBadSig         = 16 // BADSIG    - TSIG Signature Failure            [TSIG]
+       RcodeBadVers        = 16 // BADVERS   - Bad OPT Version                   [EDNS0]
+       RcodeBadKey         = 17 // BADKEY    - Key not recognized                [TSIG]
+       RcodeBadTime        = 18 // BADTIME   - Signature out of time window      [TSIG]
+       RcodeBadMode        = 19 // BADMODE   - Bad TKEY Mode                     [TKEY]
+       RcodeBadName        = 20 // BADNAME   - Duplicate key name                [TKEY]
+       RcodeBadAlg         = 21 // BADALG    - Algorithm not supported           [TKEY]
+       RcodeBadTrunc       = 22 // BADTRUNC  - Bad Truncation                    [TSIG]
+       RcodeBadCookie      = 23 // BADCOOKIE - Bad/missing Server Cookie         [DNS Cookies]
 
        // Message Opcodes. There is no 3.
        OpcodeQuery  = 0
@@ -143,7 +145,7 @@ const (
        OpcodeUpdate = 5
 )
 
-// Headers is the wire format for the DNS packet header.
+// Header is the wire format for the DNS packet header.
 type Header struct {
        Id                                 uint16
        Bits                               uint16
@@ -479,12 +481,6 @@ func appendDomainNameByte(s []byte, b byte) []byte {
 
 func appendTXTStringByte(s []byte, b byte) []byte {
        switch b {
-       case '\t':
-               return append(s, '\\', 't')
-       case '\r':
-               return append(s, '\\', 'r')
-       case '\n':
-               return append(s, '\\', 'n')
        case '"', '\\':
                return append(s, '\\', b)
        }
@@ -524,17 +520,8 @@ func nextByte(b []byte, offset int) (byte, int) {
                        return dddToByte(b[offset+1:]), 4
                }
        }
-       // not \ddd, maybe a control char
-       switch b[offset+1] {
-       case 't':
-               return '\t', 2
-       case 'r':
-               return '\r', 2
-       case 'n':
-               return '\n', 2
-       default:
-               return b[offset+1], 2
-       }
+       // not \ddd, just an RFC 1035 "quoted" character
+       return b[offset+1], 2
 }
 
 type SPF struct {
@@ -544,6 +531,13 @@ type SPF struct {
 
 func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
 
+type AVC struct {
+       Hdr RR_Header
+       Txt []string `dns:"txt"`
+}
+
+func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
+
 type SRV struct {
        Hdr      RR_Header
        Priority uint16
@@ -958,7 +952,7 @@ type NSEC3PARAM struct {
        Flags      uint8
        Iterations uint16
        SaltLength uint8
-       Salt       string `dns:"hex"`
+       Salt       string `dns:"size-hex:SaltLength"`
 }
 
 func (rr *NSEC3PARAM) String() string {
@@ -1047,6 +1041,28 @@ func (rr *TLSA) String() string {
                " " + rr.Certificate
 }
 
+type SMIMEA struct {
+       Hdr          RR_Header
+       Usage        uint8
+       Selector     uint8
+       MatchingType uint8
+       Certificate  string `dns:"hex"`
+}
+
+func (rr *SMIMEA) String() string {
+       s := rr.Hdr.String() +
+               strconv.Itoa(int(rr.Usage)) +
+               " " + strconv.Itoa(int(rr.Selector)) +
+               " " + strconv.Itoa(int(rr.MatchingType))
+
+       // Every Nth char needs a space on this output. If we output
+       // this as one giant line, we can't read it can in because in some cases
+       // the cert length overflows scan.maxTok (2048).
+       sx := splitN(rr.Certificate, 1024) // conservative value here
+       s += " " + strings.Join(sx, " ")
+       return s
+}
+
 type HIP struct {
        Hdr                RR_Header
        HitLength          uint8
@@ -1219,8 +1235,7 @@ func StringToTime(s string) (uint32, error) {
        return uint32(t.Unix() - (mod * year68)), nil
 }
 
-// saltToString converts a NSECX salt to uppercase and
-// returns "-" when it is empty
+// saltToString converts a NSECX salt to uppercase and returns "-" when it is empty.
 func saltToString(s string) string {
        if len(s) == 0 {
                return "-"
@@ -1248,3 +1263,25 @@ func copyIP(ip net.IP) net.IP {
        copy(p, ip)
        return p
 }
+
+// SplitN splits a string into N sized string chunks.
+// This might become an exported function once.
+func splitN(s string, n int) []string {
+       if len(s) < n {
+               return []string{s}
+       }
+       sx := []string{}
+       p, i := 0, n
+       for {
+               if i <= len(s) {
+                       sx = append(sx, s[p:i])
+               } else {
+                       sx = append(sx, s[p:])
+                       break
+
+               }
+               p, i = p+n, i+n
+       }
+
+       return sx
+}
index bf80da329c31adaccbfe9481e946ece994f7c687..dd1310942ba483a93027421e120a2dbe8295620c 100644 (file)
@@ -197,7 +197,7 @@ func main() {
                        case st.Tag(i) == "":
                                switch st.Field(i).Type().(*types.Basic).Kind() {
                                case types.Uint8:
-                                       o("l += 1 // %s\n")
+                                       o("l++ // %s\n")
                                case types.Uint16:
                                        o("l += 2 // %s\n")
                                case types.Uint32:
index c79c6c88371be51189fe981537a5ca7a713a05b5..af111b9a89460ea7d84d0b7102007e4d371af0b3 100644 (file)
@@ -1,10 +1,9 @@
-// +build !windows,!plan9
+// +build !windows
 
 package dns
 
 import (
        "net"
-       "syscall"
 )
 
 // SessionUDP holds the remote address and the associated
@@ -17,29 +16,6 @@ type SessionUDP struct {
 // RemoteAddr returns the remote network address.
 func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
 
-// setUDPSocketOptions sets the UDP socket options.
-// This function is implemented on a per platform basis. See udp_*.go for more details
-func setUDPSocketOptions(conn *net.UDPConn) error {
-       sa, err := getUDPSocketName(conn)
-       if err != nil {
-               return err
-       }
-       switch sa.(type) {
-       case *syscall.SockaddrInet6:
-               v6only, err := getUDPSocketOptions6Only(conn)
-               if err != nil {
-                       return err
-               }
-               setUDPSocketOptions6(conn)
-               if !v6only {
-                       setUDPSocketOptions4(conn)
-               }
-       case *syscall.SockaddrInet4:
-               setUDPSocketOptions4(conn)
-       }
-       return nil
-}
-
 // ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
 // net.UDPAddr.
 func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
index c62d21881b63475ed793998529f712fc7787d637..033df4239986ddda3216cef1c3f162c25a9eb887 100644 (file)
@@ -1,4 +1,4 @@
-// +build linux
+// +build linux,!appengine
 
 package dns
 
@@ -15,6 +15,29 @@ import (
        "syscall"
 )
 
+// setUDPSocketOptions sets the UDP socket options.
+// This function is implemented on a per platform basis. See udp_*.go for more details
+func setUDPSocketOptions(conn *net.UDPConn) error {
+       sa, err := getUDPSocketName(conn)
+       if err != nil {
+               return err
+       }
+       switch sa.(type) {
+       case *syscall.SockaddrInet6:
+               v6only, err := getUDPSocketOptions6Only(conn)
+               if err != nil {
+                       return err
+               }
+               setUDPSocketOptions6(conn)
+               if !v6only {
+                       setUDPSocketOptions4(conn)
+               }
+       case *syscall.SockaddrInet4:
+               setUDPSocketOptions4(conn)
+       }
+       return nil
+}
+
 // setUDPSocketOptions4 prepares the v4 socket for sessions.
 func setUDPSocketOptions4(conn *net.UDPConn) error {
        file, err := conn.File()
@@ -22,14 +45,17 @@ func setUDPSocketOptions4(conn *net.UDPConn) error {
                return err
        }
        if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IP, syscall.IP_PKTINFO, 1); err != nil {
+               file.Close()
                return err
        }
        // Calling File() above results in the connection becoming blocking, we must fix that.
        // See https://github.com/miekg/dns/issues/279
        err = syscall.SetNonblock(int(file.Fd()), true)
        if err != nil {
+               file.Close()
                return err
        }
+       file.Close()
        return nil
 }
 
@@ -40,12 +66,15 @@ func setUDPSocketOptions6(conn *net.UDPConn) error {
                return err
        }
        if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1); err != nil {
+               file.Close()
                return err
        }
        err = syscall.SetNonblock(int(file.Fd()), true)
        if err != nil {
+               file.Close()
                return err
        }
+       file.Close()
        return nil
 }
 
@@ -59,8 +88,10 @@ func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) {
        // dual stack. See http://stackoverflow.com/questions/1618240/how-to-support-both-ipv4-and-ipv6-connections
        v6only, err := syscall.GetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY)
        if err != nil {
+               file.Close()
                return false, err
        }
+       file.Close()
        return v6only == 1, nil
 }
 
@@ -69,5 +100,6 @@ func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) {
        if err != nil {
                return nil, err
        }
+       defer file.Close()
        return syscall.Getsockname(int(file.Fd()))
 }
index d40732441b0f54a46c79e4bb58af043b58492f68..488a282b26af835514f3213d5745b84a0bb42fc6 100644 (file)
@@ -1,17 +1,15 @@
-// +build !linux,!plan9
+// +build !linux appengine
 
 package dns
 
 import (
        "net"
-       "syscall"
 )
 
 // These do nothing. See udp_linux.go for an example of how to implement this.
 
 // We tried to adhire to some kind of naming scheme.
-
+func setUDPSocketOptions(conn *net.UDPConn) error                  { return nil }
 func setUDPSocketOptions4(conn *net.UDPConn) error                 { return nil }
 func setUDPSocketOptions6(conn *net.UDPConn) error                 { return nil }
 func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error)     { return false, nil }
-func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) { return nil, nil }
diff --git a/vendor/github.com/miekg/dns/udp_plan9.go b/vendor/github.com/miekg/dns/udp_plan9.go
deleted file mode 100644 (file)
index b794dee..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-package dns
-
-import (
-       "net"
-)
-
-func setUDPSocketOptions(conn *net.UDPConn) error { return nil }
-
-// SessionUDP holds the remote address and the associated
-// out-of-band data.
-type SessionUDP struct {
-       raddr   *net.UDPAddr
-       context []byte
-}
-
-// RemoteAddr returns the remote network address.
-func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
-
-// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
-// net.UDPAddr.
-func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
-       oob := make([]byte, 40)
-       n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob)
-       if err != nil {
-               return n, nil, err
-       }
-       return n, &SessionUDP{raddr, oob[:oobn]}, err
-}
-
-// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
-func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
-       n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr)
-       return n, err
-}
index 2ce4b3300287bd11de3873d55c09b05c6d3f0be1..51e532ac2a8687e211bae7e6af28526e919c4ff2 100644 (file)
@@ -8,6 +8,8 @@ type SessionUDP struct {
        raddr *net.UDPAddr
 }
 
+func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
+
 // ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
 // net.UDPAddr.
 func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
@@ -25,10 +27,3 @@ func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, e
        return n, err
 }
 
-func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
-
-// setUDPSocketOptions sets the UDP socket options.
-// This function is implemented on a per platform basis. See udp_*.go for more details
-func setUDPSocketOptions(conn *net.UDPConn) error {
-       return nil
-}
index 7346deffbb736520d1ab794dff27178b89bafd52..576c5590afd54df964ac6dd45b63631786c464ca 100644 (file)
@@ -1,6 +1,7 @@
 package dns
 
 import (
+       "fmt"
        "time"
 )
 
@@ -81,6 +82,10 @@ func (t *Transfer) inAxfr(id uint16, c chan *Envelope) {
                        return
                }
                if first {
+                       if in.Rcode != RcodeSuccess {
+                               c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
+                               return
+                       }
                        if !isSOAFirst(in) {
                                c <- &Envelope{in.Answer, ErrSoa}
                                return
@@ -126,6 +131,10 @@ func (t *Transfer) inIxfr(id uint16, c chan *Envelope) {
                        return
                }
                if first {
+                       if in.Rcode != RcodeSuccess {
+                               c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
+                               return
+                       }
                        // A single SOA RR signals "no changes"
                        if len(in.Answer) == 1 && isSOAFirst(in) {
                                c <- &Envelope{in.Answer, nil}
@@ -242,3 +251,5 @@ func isSOALast(in *Msg) bool {
        }
        return false
 }
+
+const errXFR = "bad xfr rcode: %d"
index e5f3cf2974c4d87ebbdcd38120a6452eca664a52..418fb1fe3e27a98971e927096264b6bd7941bb64 100644 (file)
@@ -61,6 +61,20 @@ func (rr *ANY) pack(msg []byte, off int, compression map[string]int, compress bo
        return off, nil
 }
 
+func (rr *AVC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
+       off, err := rr.Hdr.pack(msg, off, compression, compress)
+       if err != nil {
+               return off, err
+       }
+       headerEnd := off
+       off, err = packStringTxt(rr.Txt, msg, off)
+       if err != nil {
+               return off, err
+       }
+       rr.Header().Rdlength = uint16(off - headerEnd)
+       return off, nil
+}
+
 func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
        off, err := rr.Hdr.pack(msg, off, compression, compress)
        if err != nil {
@@ -221,7 +235,7 @@ func (rr *DNAME) pack(msg []byte, off int, compression map[string]int, compress
                return off, err
        }
        headerEnd := off
-       off, err = PackDomainName(rr.Target, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Target, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -447,7 +461,7 @@ func (rr *KX) pack(msg []byte, off int, compression map[string]int, compress boo
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.Exchanger, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Exchanger, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -539,7 +553,7 @@ func (rr *LP) pack(msg []byte, off int, compression map[string]int, compress boo
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.Fqdn, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Fqdn, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -679,7 +693,7 @@ func (rr *NAPTR) pack(msg []byte, off int, compression map[string]int, compress
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.Replacement, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Replacement, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -753,7 +767,7 @@ func (rr *NSAPPTR) pack(msg []byte, off int, compression map[string]int, compres
                return off, err
        }
        headerEnd := off
-       off, err = PackDomainName(rr.Ptr, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Ptr, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -767,7 +781,7 @@ func (rr *NSEC) pack(msg []byte, off int, compression map[string]int, compress b
                return off, err
        }
        headerEnd := off
-       off, err = PackDomainName(rr.NextDomain, msg, off, compression, compress)
+       off, err = PackDomainName(rr.NextDomain, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -801,9 +815,12 @@ func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress
        if err != nil {
                return off, err
        }
-       off, err = packStringHex(rr.Salt, msg, off)
-       if err != nil {
-               return off, err
+       // Only pack salt if value is not "-", i.e. empty
+       if rr.Salt != "-" {
+               off, err = packStringHex(rr.Salt, msg, off)
+               if err != nil {
+                       return off, err
+               }
        }
        off, err = packUint8(rr.HashLength, msg, off)
        if err != nil {
@@ -843,9 +860,12 @@ func (rr *NSEC3PARAM) pack(msg []byte, off int, compression map[string]int, comp
        if err != nil {
                return off, err
        }
-       off, err = packStringHex(rr.Salt, msg, off)
-       if err != nil {
-               return off, err
+       // Only pack salt if value is not "-", i.e. empty
+       if rr.Salt != "-" {
+               off, err = packStringHex(rr.Salt, msg, off)
+               if err != nil {
+                       return off, err
+               }
        }
        rr.Header().Rdlength = uint16(off - headerEnd)
        return off, nil
@@ -903,11 +923,11 @@ func (rr *PX) pack(msg []byte, off int, compression map[string]int, compress boo
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.Map822, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Map822, msg, off, compression, false)
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.Mapx400, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Mapx400, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -961,11 +981,11 @@ func (rr *RP) pack(msg []byte, off int, compression map[string]int, compress boo
                return off, err
        }
        headerEnd := off
-       off, err = PackDomainName(rr.Mbox, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Mbox, msg, off, compression, false)
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.Txt, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Txt, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -1007,7 +1027,7 @@ func (rr *RRSIG) pack(msg []byte, off int, compression map[string]int, compress
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.SignerName, msg, off, compression, compress)
+       off, err = PackDomainName(rr.SignerName, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -1071,7 +1091,7 @@ func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bo
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.SignerName, msg, off, compression, compress)
+       off, err = PackDomainName(rr.SignerName, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -1083,6 +1103,32 @@ func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bo
        return off, nil
 }
 
+func (rr *SMIMEA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
+       off, err := rr.Hdr.pack(msg, off, compression, compress)
+       if err != nil {
+               return off, err
+       }
+       headerEnd := off
+       off, err = packUint8(rr.Usage, msg, off)
+       if err != nil {
+               return off, err
+       }
+       off, err = packUint8(rr.Selector, msg, off)
+       if err != nil {
+               return off, err
+       }
+       off, err = packUint8(rr.MatchingType, msg, off)
+       if err != nil {
+               return off, err
+       }
+       off, err = packStringHex(rr.Certificate, msg, off)
+       if err != nil {
+               return off, err
+       }
+       rr.Header().Rdlength = uint16(off - headerEnd)
+       return off, nil
+}
+
 func (rr *SOA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
        off, err := rr.Hdr.pack(msg, off, compression, compress)
        if err != nil {
@@ -1153,7 +1199,7 @@ func (rr *SRV) pack(msg []byte, off int, compression map[string]int, compress bo
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.Target, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Target, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -1215,11 +1261,11 @@ func (rr *TALINK) pack(msg []byte, off int, compression map[string]int, compress
                return off, err
        }
        headerEnd := off
-       off, err = PackDomainName(rr.PreviousName, msg, off, compression, compress)
+       off, err = PackDomainName(rr.PreviousName, msg, off, compression, false)
        if err != nil {
                return off, err
        }
-       off, err = PackDomainName(rr.NextName, msg, off, compression, compress)
+       off, err = PackDomainName(rr.NextName, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -1233,7 +1279,7 @@ func (rr *TKEY) pack(msg []byte, off int, compression map[string]int, compress b
                return off, err
        }
        headerEnd := off
-       off, err = PackDomainName(rr.Algorithm, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Algorithm, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -1305,7 +1351,7 @@ func (rr *TSIG) pack(msg []byte, off int, compression map[string]int, compress b
                return off, err
        }
        headerEnd := off
-       off, err = PackDomainName(rr.Algorithm, msg, off, compression, compress)
+       off, err = PackDomainName(rr.Algorithm, msg, off, compression, false)
        if err != nil {
                return off, err
        }
@@ -1496,6 +1542,23 @@ func unpackANY(h RR_Header, msg []byte, off int) (RR, int, error) {
        return rr, off, err
 }
 
+func unpackAVC(h RR_Header, msg []byte, off int) (RR, int, error) {
+       rr := new(AVC)
+       rr.Hdr = h
+       if noRdata(h) {
+               return rr, off, nil
+       }
+       var err error
+       rdStart := off
+       _ = rdStart
+
+       rr.Txt, off, err = unpackStringTxt(msg, off)
+       if err != nil {
+               return rr, off, err
+       }
+       return rr, off, err
+}
+
 func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) {
        rr := new(CAA)
        rr.Hdr = h
@@ -2567,7 +2630,7 @@ func unpackNSEC3PARAM(h RR_Header, msg []byte, off int) (RR, int, error) {
        if off == len(msg) {
                return rr, off, nil
        }
-       rr.Salt, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+       rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength))
        if err != nil {
                return rr, off, err
        }
@@ -2905,6 +2968,44 @@ func unpackSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
        return rr, off, err
 }
 
+func unpackSMIMEA(h RR_Header, msg []byte, off int) (RR, int, error) {
+       rr := new(SMIMEA)
+       rr.Hdr = h
+       if noRdata(h) {
+               return rr, off, nil
+       }
+       var err error
+       rdStart := off
+       _ = rdStart
+
+       rr.Usage, off, err = unpackUint8(msg, off)
+       if err != nil {
+               return rr, off, err
+       }
+       if off == len(msg) {
+               return rr, off, nil
+       }
+       rr.Selector, off, err = unpackUint8(msg, off)
+       if err != nil {
+               return rr, off, err
+       }
+       if off == len(msg) {
+               return rr, off, nil
+       }
+       rr.MatchingType, off, err = unpackUint8(msg, off)
+       if err != nil {
+               return rr, off, err
+       }
+       if off == len(msg) {
+               return rr, off, nil
+       }
+       rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
+       if err != nil {
+               return rr, off, err
+       }
+       return rr, off, err
+}
+
 func unpackSOA(h RR_Header, msg []byte, off int) (RR, int, error) {
        rr := new(SOA)
        rr.Hdr = h
@@ -3397,6 +3498,7 @@ var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
        TypeAAAA:       unpackAAAA,
        TypeAFSDB:      unpackAFSDB,
        TypeANY:        unpackANY,
+       TypeAVC:        unpackAVC,
        TypeCAA:        unpackCAA,
        TypeCDNSKEY:    unpackCDNSKEY,
        TypeCDS:        unpackCDS,
@@ -3445,6 +3547,7 @@ var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
        TypeRRSIG:      unpackRRSIG,
        TypeRT:         unpackRT,
        TypeSIG:        unpackSIG,
+       TypeSMIMEA:     unpackSMIMEA,
        TypeSOA:        unpackSOA,
        TypeSPF:        unpackSPF,
        TypeSRV:        unpackSRV,
index a4ecbb0cc0fa915edd1c82f2808bae36e9742a94..3e534f12e0191248c1a8603f7b0cc553470a465c 100644 (file)
@@ -14,6 +14,7 @@ var TypeToRR = map[uint16]func() RR{
        TypeAAAA:       func() RR { return new(AAAA) },
        TypeAFSDB:      func() RR { return new(AFSDB) },
        TypeANY:        func() RR { return new(ANY) },
+       TypeAVC:        func() RR { return new(AVC) },
        TypeCAA:        func() RR { return new(CAA) },
        TypeCDNSKEY:    func() RR { return new(CDNSKEY) },
        TypeCDS:        func() RR { return new(CDS) },
@@ -62,6 +63,7 @@ var TypeToRR = map[uint16]func() RR{
        TypeRRSIG:      func() RR { return new(RRSIG) },
        TypeRT:         func() RR { return new(RT) },
        TypeSIG:        func() RR { return new(SIG) },
+       TypeSMIMEA:     func() RR { return new(SMIMEA) },
        TypeSOA:        func() RR { return new(SOA) },
        TypeSPF:        func() RR { return new(SPF) },
        TypeSRV:        func() RR { return new(SRV) },
@@ -85,6 +87,7 @@ var TypeToString = map[uint16]string{
        TypeAFSDB:      "AFSDB",
        TypeANY:        "ANY",
        TypeATMA:       "ATMA",
+       TypeAVC:        "AVC",
        TypeAXFR:       "AXFR",
        TypeCAA:        "CAA",
        TypeCDNSKEY:    "CDNSKEY",
@@ -141,6 +144,7 @@ var TypeToString = map[uint16]string{
        TypeRT:         "RT",
        TypeReserved:   "Reserved",
        TypeSIG:        "SIG",
+       TypeSMIMEA:     "SMIMEA",
        TypeSOA:        "SOA",
        TypeSPF:        "SPF",
        TypeSRV:        "SRV",
@@ -164,6 +168,7 @@ func (rr *A) Header() *RR_Header          { return &rr.Hdr }
 func (rr *AAAA) Header() *RR_Header       { return &rr.Hdr }
 func (rr *AFSDB) Header() *RR_Header      { return &rr.Hdr }
 func (rr *ANY) Header() *RR_Header        { return &rr.Hdr }
+func (rr *AVC) Header() *RR_Header        { return &rr.Hdr }
 func (rr *CAA) Header() *RR_Header        { return &rr.Hdr }
 func (rr *CDNSKEY) Header() *RR_Header    { return &rr.Hdr }
 func (rr *CDS) Header() *RR_Header        { return &rr.Hdr }
@@ -213,6 +218,7 @@ func (rr *RP) Header() *RR_Header         { return &rr.Hdr }
 func (rr *RRSIG) Header() *RR_Header      { return &rr.Hdr }
 func (rr *RT) Header() *RR_Header         { return &rr.Hdr }
 func (rr *SIG) Header() *RR_Header        { return &rr.Hdr }
+func (rr *SMIMEA) Header() *RR_Header     { return &rr.Hdr }
 func (rr *SOA) Header() *RR_Header        { return &rr.Hdr }
 func (rr *SPF) Header() *RR_Header        { return &rr.Hdr }
 func (rr *SRV) Header() *RR_Header        { return &rr.Hdr }
@@ -249,9 +255,16 @@ func (rr *ANY) len() int {
        l := rr.Hdr.len()
        return l
 }
+func (rr *AVC) len() int {
+       l := rr.Hdr.len()
+       for _, x := range rr.Txt {
+               l += len(x) + 1
+       }
+       return l
+}
 func (rr *CAA) len() int {
        l := rr.Hdr.len()
-       l += 1 // Flag
+       l++ // Flag
        l += len(rr.Tag) + 1
        l += len(rr.Value)
        return l
@@ -260,7 +273,7 @@ func (rr *CERT) len() int {
        l := rr.Hdr.len()
        l += 2 // Type
        l += 2 // KeyTag
-       l += 1 // Algorithm
+       l++    // Algorithm
        l += base64.StdEncoding.DecodedLen(len(rr.Certificate))
        return l
 }
@@ -282,16 +295,16 @@ func (rr *DNAME) len() int {
 func (rr *DNSKEY) len() int {
        l := rr.Hdr.len()
        l += 2 // Flags
-       l += 1 // Protocol
-       l += 1 // Algorithm
+       l++    // Protocol
+       l++    // Algorithm
        l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
        return l
 }
 func (rr *DS) len() int {
        l := rr.Hdr.len()
        l += 2 // KeyTag
-       l += 1 // Algorithm
-       l += 1 // DigestType
+       l++    // Algorithm
+       l++    // DigestType
        l += len(rr.Digest)/2 + 1
        return l
 }
@@ -330,8 +343,8 @@ func (rr *HINFO) len() int {
 }
 func (rr *HIP) len() int {
        l := rr.Hdr.len()
-       l += 1 // HitLength
-       l += 1 // PublicKeyAlgorithm
+       l++    // HitLength
+       l++    // PublicKeyAlgorithm
        l += 2 // PublicKeyLength
        l += len(rr.Hit)/2 + 1
        l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
@@ -360,10 +373,10 @@ func (rr *L64) len() int {
 }
 func (rr *LOC) len() int {
        l := rr.Hdr.len()
-       l += 1 // Version
-       l += 1 // Size
-       l += 1 // HorizPre
-       l += 1 // VertPre
+       l++    // Version
+       l++    // Size
+       l++    // HorizPre
+       l++    // VertPre
        l += 4 // Latitude
        l += 4 // Longitude
        l += 4 // Altitude
@@ -452,10 +465,10 @@ func (rr *NSAPPTR) len() int {
 }
 func (rr *NSEC3PARAM) len() int {
        l := rr.Hdr.len()
-       l += 1 // Hash
-       l += 1 // Flags
+       l++    // Hash
+       l++    // Flags
        l += 2 // Iterations
-       l += 1 // SaltLength
+       l++    // SaltLength
        l += len(rr.Salt)/2 + 1
        return l
 }
@@ -484,8 +497,8 @@ func (rr *RFC3597) len() int {
 func (rr *RKEY) len() int {
        l := rr.Hdr.len()
        l += 2 // Flags
-       l += 1 // Protocol
-       l += 1 // Algorithm
+       l++    // Protocol
+       l++    // Algorithm
        l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
        return l
 }
@@ -498,8 +511,8 @@ func (rr *RP) len() int {
 func (rr *RRSIG) len() int {
        l := rr.Hdr.len()
        l += 2 // TypeCovered
-       l += 1 // Algorithm
-       l += 1 // Labels
+       l++    // Algorithm
+       l++    // Labels
        l += 4 // OrigTtl
        l += 4 // Expiration
        l += 4 // Inception
@@ -514,6 +527,14 @@ func (rr *RT) len() int {
        l += len(rr.Host) + 1
        return l
 }
+func (rr *SMIMEA) len() int {
+       l := rr.Hdr.len()
+       l++ // Usage
+       l++ // Selector
+       l++ // MatchingType
+       l += len(rr.Certificate)/2 + 1
+       return l
+}
 func (rr *SOA) len() int {
        l := rr.Hdr.len()
        l += len(rr.Ns) + 1
@@ -542,16 +563,16 @@ func (rr *SRV) len() int {
 }
 func (rr *SSHFP) len() int {
        l := rr.Hdr.len()
-       l += 1 // Algorithm
-       l += 1 // Type
+       l++ // Algorithm
+       l++ // Type
        l += len(rr.FingerPrint)/2 + 1
        return l
 }
 func (rr *TA) len() int {
        l := rr.Hdr.len()
        l += 2 // KeyTag
-       l += 1 // Algorithm
-       l += 1 // DigestType
+       l++    // Algorithm
+       l++    // DigestType
        l += len(rr.Digest)/2 + 1
        return l
 }
@@ -576,9 +597,9 @@ func (rr *TKEY) len() int {
 }
 func (rr *TLSA) len() int {
        l := rr.Hdr.len()
-       l += 1 // Usage
-       l += 1 // Selector
-       l += 1 // MatchingType
+       l++ // Usage
+       l++ // Selector
+       l++ // MatchingType
        l += len(rr.Certificate)/2 + 1
        return l
 }
@@ -638,6 +659,11 @@ func (rr *AFSDB) copy() RR {
 func (rr *ANY) copy() RR {
        return &ANY{*rr.Hdr.copyHeader()}
 }
+func (rr *AVC) copy() RR {
+       Txt := make([]string, len(rr.Txt))
+       copy(Txt, rr.Txt)
+       return &AVC{*rr.Hdr.copyHeader(), Txt}
+}
 func (rr *CAA) copy() RR {
        return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value}
 }
@@ -780,6 +806,9 @@ func (rr *RRSIG) copy() RR {
 func (rr *RT) copy() RR {
        return &RT{*rr.Hdr.copyHeader(), rr.Preference, rr.Host}
 }
+func (rr *SMIMEA) copy() RR {
+       return &SMIMEA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
+}
 func (rr *SOA) copy() RR {
        return &SOA{*rr.Hdr.copyHeader(), rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl}
 }
index 6b1f2891a5ac09218a5b7de82f3e479a16f44298..cbe3f3e387c7fedaea0b839dc04352dd203ae2f2 100644 (file)
@@ -79,6 +79,14 @@ func (f Frame) Format(s fmt.State, verb rune) {
 // StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
 type StackTrace []Frame
 
+// Format formats the stack of Frames according to the fmt.Formatter interface.
+//
+//    %s       lists source files for each Frame in the stack
+//    %v       lists the source file and line number for each Frame in the stack
+//
+// Format accepts flags that alter the printing of some verbs, as follows:
+//
+//    %+v   Prints filename, function, and line number for each Frame in the stack.
 func (st StackTrace) Format(s fmt.State, verb rune) {
        switch verb {
        case 'v':
index 72d5256a508fe8e16a867e1b4f17b379333307e8..273db5f815979285e64b2dd75d460279d99bd1c6 100644 (file)
@@ -70,16 +70,12 @@ func (c *counter) Add(v float64) {
 // if you want to count the same thing partitioned by various dimensions
 // (e.g. number of HTTP requests, partitioned by response code and
 // method). Create instances with NewCounterVec.
-//
-// CounterVec embeds MetricVec. See there for a full list of methods with
-// detailed documentation.
 type CounterVec struct {
-       *MetricVec
+       *metricVec
 }
 
 // NewCounterVec creates a new CounterVec based on the provided CounterOpts and
-// partitioned by the given label names. At least one label name must be
-// provided.
+// partitioned by the given label names.
 func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
        desc := NewDesc(
                BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
@@ -88,7 +84,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
                opts.ConstLabels,
        )
        return &CounterVec{
-               MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
+               metricVec: newMetricVec(desc, func(lvs ...string) Metric {
                        result := &counter{value: value{
                                desc:       desc,
                                valType:    CounterValue,
@@ -100,22 +96,51 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
        }
 }
 
-// GetMetricWithLabelValues replaces the method of the same name in
-// MetricVec. The difference is that this method returns a Counter and not a
-// Metric so that no type conversion is required.
+// GetMetricWithLabelValues returns the Counter for the given slice of label
+// values (same order as the VariableLabels in Desc). If that combination of
+// label values is accessed for the first time, a new Counter is created.
+//
+// It is possible to call this method without using the returned Counter to only
+// create the new Counter but leave it at its starting value 0. See also the
+// SummaryVec example.
+//
+// Keeping the Counter for later use is possible (and should be considered if
+// performance is critical), but keep in mind that Reset, DeleteLabelValues and
+// Delete can be used to delete the Counter from the CounterVec. In that case,
+// the Counter will still exist, but it will not be exported anymore, even if a
+// Counter with the same label values is created later.
+//
+// An error is returned if the number of label values is not the same as the
+// number of VariableLabels in Desc.
+//
+// Note that for more than one label value, this method is prone to mistakes
+// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
+// an alternative to avoid that type of mistake. For higher label numbers, the
+// latter has a much more readable (albeit more verbose) syntax, but it comes
+// with a performance overhead (for creating and processing the Labels map).
+// See also the GaugeVec example.
 func (m *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) {
-       metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
+       metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
        if metric != nil {
                return metric.(Counter), err
        }
        return nil, err
 }
 
-// GetMetricWith replaces the method of the same name in MetricVec. The
-// difference is that this method returns a Counter and not a Metric so that no
-// type conversion is required.
+// GetMetricWith returns the Counter for the given Labels map (the label names
+// must match those of the VariableLabels in Desc). If that label map is
+// accessed for the first time, a new Counter is created. Implications of
+// creating a Counter without using it and keeping the Counter for later use are
+// the same as for GetMetricWithLabelValues.
+//
+// An error is returned if the number and names of the Labels are inconsistent
+// with those of the VariableLabels in Desc.
+//
+// This method is used for the same purpose as
+// GetMetricWithLabelValues(...string). See there for pros and cons of the two
+// methods.
 func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
-       metric, err := m.MetricVec.GetMetricWith(labels)
+       metric, err := m.metricVec.getMetricWith(labels)
        if metric != nil {
                return metric.(Counter), err
        }
@@ -127,14 +152,14 @@ func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
 // error, WithLabelValues allows shortcuts like
 //     myVec.WithLabelValues("404", "GET").Add(42)
 func (m *CounterVec) WithLabelValues(lvs ...string) Counter {
-       return m.MetricVec.WithLabelValues(lvs...).(Counter)
+       return m.metricVec.withLabelValues(lvs...).(Counter)
 }
 
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // returned an error. By not returning an error, With allows shortcuts like
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
 func (m *CounterVec) With(labels Labels) Counter {
-       return m.MetricVec.With(labels).(Counter)
+       return m.metricVec.with(labels).(Counter)
 }
 
 // CounterFunc is a Counter whose value is determined at collect time by calling a
index 1835b16f65ca0ec99aaa63963dfca6fbc48a0595..920abc92019e535909828f7b312484a8fd5fac22 100644 (file)
@@ -25,19 +25,6 @@ import (
        dto "github.com/prometheus/client_model/go"
 )
 
-// reservedLabelPrefix is a prefix which is not legal in user-supplied
-// label names.
-const reservedLabelPrefix = "__"
-
-// Labels represents a collection of label name -> value mappings. This type is
-// commonly used with the With(Labels) and GetMetricWith(Labels) methods of
-// metric vector Collectors, e.g.:
-//     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
-//
-// The other use-case is the specification of constant label pairs in Opts or to
-// create a Desc.
-type Labels map[string]string
-
 // Desc is the descriptor used by every Prometheus Metric. It is essentially
 // the immutable meta-data of a Metric. The normal Metric implementations
 // included in this package manage their Desc under the hood. Users only have to
@@ -122,6 +109,12 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
        for _, labelName := range labelNames {
                labelValues = append(labelValues, constLabels[labelName])
        }
+       // Validate the const label values. They can't have a wrong cardinality, so
+       // use in len(labelValues) as expectedNumberOfValues.
+       if err := validateLabelValues(labelValues, len(labelValues)); err != nil {
+               d.err = err
+               return d
+       }
        // Now add the variable label names, but prefix them with something that
        // cannot be in a regular label name. That prevents matching the label
        // dimension with a different mix between preset and variable labels.
@@ -137,6 +130,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
                d.err = errors.New("duplicate label names")
                return d
        }
+
        vh := hashNew()
        for _, val := range labelValues {
                vh = hashAdd(vh, val)
@@ -193,8 +187,3 @@ func (d *Desc) String() string {
                d.variableLabels,
        )
 }
-
-func checkLabelName(l string) bool {
-       return model.LabelName(l).IsValid() &&
-               !strings.HasPrefix(l, reservedLabelPrefix)
-}
index 1fdef9edb01497598efd3ad0686981e98e3aacf1..36ef155670c1bfa0ef91030d1ce9fa97449ceefb 100644 (file)
@@ -26,6 +26,7 @@
 //    package main
 //
 //    import (
+//     "log"
 //     "net/http"
 //
 //     "github.com/prometheus/client_golang/prometheus"
@@ -59,7 +60,7 @@
 //     // The Handler function provides a default handler to expose metrics
 //     // via an HTTP server. "/metrics" is the usual endpoint for that.
 //     http.Handle("/metrics", promhttp.Handler())
-//      log.Fatal(http.ListenAndServe(":8080", nil))
+//     log.Fatal(http.ListenAndServe(":8080", nil))
 //    }
 //
 //
 // registry.
 //
 // So far, everything we did operated on the so-called default registry, as it
-// can be found in the global DefaultRegistry variable. With NewRegistry, you
+// can be found in the global DefaultRegisterer variable. With NewRegistry, you
 // can create a custom registry, or you can even implement the Registerer or
 // Gatherer interfaces yourself. The methods Register and Unregister work in the
 // same way on a custom registry as the global functions Register and Unregister
 //
 // There are a number of uses for custom registries: You can use registries with
 // special properties, see NewPedanticRegistry. You can avoid global state, as
-// it is imposed by the DefaultRegistry. You can use multiple registries at the
-// same time to expose different metrics in different ways. You can use separate
-// registries for testing purposes.
+// it is imposed by the DefaultRegisterer. You can use multiple registries at
+// the same time to expose different metrics in different ways.  You can use
+// separate registries for testing purposes.
 //
-// Also note that the DefaultRegistry comes registered with a Collector for Go
+// Also note that the DefaultRegisterer comes registered with a Collector for Go
 // runtime metrics (via NewGoCollector) and a Collector for process metrics (via
 // NewProcessCollector). With a custom registry, you are in control and decide
 // yourself about the Collectors to register.
index 9ab5a3d6218a0fe1dcf0b66b8cac3e4729f400a7..13064dab899fe2eb402054760af731e0ec788e12 100644 (file)
@@ -63,12 +63,11 @@ func NewGauge(opts GaugeOpts) Gauge {
 // (e.g. number of operations queued, partitioned by user and operation
 // type). Create instances with NewGaugeVec.
 type GaugeVec struct {
-       *MetricVec
+       *metricVec
 }
 
 // NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and
-// partitioned by the given label names. At least one label name must be
-// provided.
+// partitioned by the given label names.
 func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
        desc := NewDesc(
                BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
@@ -77,28 +76,57 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
                opts.ConstLabels,
        )
        return &GaugeVec{
-               MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
+               metricVec: newMetricVec(desc, func(lvs ...string) Metric {
                        return newValue(desc, GaugeValue, 0, lvs...)
                }),
        }
 }
 
-// GetMetricWithLabelValues replaces the method of the same name in
-// MetricVec. The difference is that this method returns a Gauge and not a
-// Metric so that no type conversion is required.
+// GetMetricWithLabelValues returns the Gauge for the given slice of label
+// values (same order as the VariableLabels in Desc). If that combination of
+// label values is accessed for the first time, a new Gauge is created.
+//
+// It is possible to call this method without using the returned Gauge to only
+// create the new Gauge but leave it at its starting value 0. See also the
+// SummaryVec example.
+//
+// Keeping the Gauge for later use is possible (and should be considered if
+// performance is critical), but keep in mind that Reset, DeleteLabelValues and
+// Delete can be used to delete the Gauge from the GaugeVec. In that case, the
+// Gauge will still exist, but it will not be exported anymore, even if a
+// Gauge with the same label values is created later. See also the CounterVec
+// example.
+//
+// An error is returned if the number of label values is not the same as the
+// number of VariableLabels in Desc.
+//
+// Note that for more than one label value, this method is prone to mistakes
+// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
+// an alternative to avoid that type of mistake. For higher label numbers, the
+// latter has a much more readable (albeit more verbose) syntax, but it comes
+// with a performance overhead (for creating and processing the Labels map).
 func (m *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) {
-       metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
+       metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
        if metric != nil {
                return metric.(Gauge), err
        }
        return nil, err
 }
 
-// GetMetricWith replaces the method of the same name in MetricVec. The
-// difference is that this method returns a Gauge and not a Metric so that no
-// type conversion is required.
+// GetMetricWith returns the Gauge for the given Labels map (the label names
+// must match those of the VariableLabels in Desc). If that label map is
+// accessed for the first time, a new Gauge is created. Implications of
+// creating a Gauge without using it and keeping the Gauge for later use are
+// the same as for GetMetricWithLabelValues.
+//
+// An error is returned if the number and names of the Labels are inconsistent
+// with those of the VariableLabels in Desc.
+//
+// This method is used for the same purpose as
+// GetMetricWithLabelValues(...string). See there for pros and cons of the two
+// methods.
 func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
-       metric, err := m.MetricVec.GetMetricWith(labels)
+       metric, err := m.metricVec.getMetricWith(labels)
        if metric != nil {
                return metric.(Gauge), err
        }
@@ -110,14 +138,14 @@ func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
 // error, WithLabelValues allows shortcuts like
 //     myVec.WithLabelValues("404", "GET").Add(42)
 func (m *GaugeVec) WithLabelValues(lvs ...string) Gauge {
-       return m.MetricVec.WithLabelValues(lvs...).(Gauge)
+       return m.metricVec.withLabelValues(lvs...).(Gauge)
 }
 
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // returned an error. By not returning an error, With allows shortcuts like
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
 func (m *GaugeVec) With(labels Labels) Gauge {
-       return m.MetricVec.With(labels).(Gauge)
+       return m.metricVec.with(labels).(Gauge)
 }
 
 // GaugeFunc is a Gauge whose value is determined at collect time by calling a
index f96764559b52b80e2d11d44527ef7aea6cf1a67f..096454af91b681a0ddfeef56e7cbff0ff63d0b55 100644 (file)
@@ -11,6 +11,7 @@ type goCollector struct {
        goroutinesDesc *Desc
        threadsDesc    *Desc
        gcDesc         *Desc
+       goInfoDesc     *Desc
 
        // metrics to describe and collect
        metrics memStatsMetrics
@@ -26,12 +27,16 @@ func NewGoCollector() Collector {
                        nil, nil),
                threadsDesc: NewDesc(
                        "go_threads",
-                       "Number of OS threads created",
+                       "Number of OS threads created.",
                        nil, nil),
                gcDesc: NewDesc(
                        "go_gc_duration_seconds",
                        "A summary of the GC invocation durations.",
                        nil, nil),
+               goInfoDesc: NewDesc(
+                       "go_info",
+                       "Information about the Go environment.",
+                       nil, Labels{"version": runtime.Version()}),
                metrics: memStatsMetrics{
                        {
                                desc: NewDesc(
@@ -239,6 +244,7 @@ func (c *goCollector) Describe(ch chan<- *Desc) {
        ch <- c.goroutinesDesc
        ch <- c.threadsDesc
        ch <- c.gcDesc
+       ch <- c.goInfoDesc
        for _, i := range c.metrics {
                ch <- i.desc
        }
@@ -261,6 +267,8 @@ func (c *goCollector) Collect(ch chan<- Metric) {
        quantiles[0.0] = stats.PauseQuantiles[0].Seconds()
        ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), float64(stats.PauseTotal.Seconds()), quantiles)
 
+       ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1)
+
        ms := &runtime.MemStats{}
        runtime.ReadMemStats(ms)
        for _, i := range c.metrics {
index f46eff6acfc59f4f0ef4aec4dc30dd2e57b37c72..6cc6e68cf48778d81cffb7b97686731957814a4d 100644 (file)
@@ -287,12 +287,11 @@ func (h *histogram) Write(out *dto.Metric) error {
 // (e.g. HTTP request latencies, partitioned by status code and method). Create
 // instances with NewHistogramVec.
 type HistogramVec struct {
-       *MetricVec
+       *metricVec
 }
 
 // NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and
-// partitioned by the given label names. At least one label name must be
-// provided.
+// partitioned by the given label names.
 func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
        desc := NewDesc(
                BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
@@ -301,28 +300,58 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
                opts.ConstLabels,
        )
        return &HistogramVec{
-               MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
+               metricVec: newMetricVec(desc, func(lvs ...string) Metric {
                        return newHistogram(desc, opts, lvs...)
                }),
        }
 }
 
-// GetMetricWithLabelValues replaces the method of the same name in
-// MetricVec. The difference is that this method returns an Observer and not a
-// Metric so that no type conversion to an Observer is required.
+// GetMetricWithLabelValues returns the Histogram for the given slice of label
+// values (same order as the VariableLabels in Desc). If that combination of
+// label values is accessed for the first time, a new Histogram is created.
+//
+// It is possible to call this method without using the returned Histogram to only
+// create the new Histogram but leave it at its starting value, a Histogram without
+// any observations.
+//
+// Keeping the Histogram for later use is possible (and should be considered if
+// performance is critical), but keep in mind that Reset, DeleteLabelValues and
+// Delete can be used to delete the Histogram from the HistogramVec. In that case, the
+// Histogram will still exist, but it will not be exported anymore, even if a
+// Histogram with the same label values is created later. See also the CounterVec
+// example.
+//
+// An error is returned if the number of label values is not the same as the
+// number of VariableLabels in Desc.
+//
+// Note that for more than one label value, this method is prone to mistakes
+// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
+// an alternative to avoid that type of mistake. For higher label numbers, the
+// latter has a much more readable (albeit more verbose) syntax, but it comes
+// with a performance overhead (for creating and processing the Labels map).
+// See also the GaugeVec example.
 func (m *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
-       metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
+       metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
        if metric != nil {
                return metric.(Observer), err
        }
        return nil, err
 }
 
-// GetMetricWith replaces the method of the same name in MetricVec. The
-// difference is that this method returns an Observer and not a Metric so that no
-// type conversion to an Observer is required.
+// GetMetricWith returns the Histogram for the given Labels map (the label names
+// must match those of the VariableLabels in Desc). If that label map is
+// accessed for the first time, a new Histogram is created. Implications of
+// creating a Histogram without using it and keeping the Histogram for later use
+// are the same as for GetMetricWithLabelValues.
+//
+// An error is returned if the number and names of the Labels are inconsistent
+// with those of the VariableLabels in Desc.
+//
+// This method is used for the same purpose as
+// GetMetricWithLabelValues(...string). See there for pros and cons of the two
+// methods.
 func (m *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {
-       metric, err := m.MetricVec.GetMetricWith(labels)
+       metric, err := m.metricVec.getMetricWith(labels)
        if metric != nil {
                return metric.(Observer), err
        }
@@ -334,14 +363,14 @@ func (m *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {
 // error, WithLabelValues allows shortcuts like
 //     myVec.WithLabelValues("404", "GET").Observe(42.21)
 func (m *HistogramVec) WithLabelValues(lvs ...string) Observer {
-       return m.MetricVec.WithLabelValues(lvs...).(Observer)
+       return m.metricVec.withLabelValues(lvs...).(Observer)
 }
 
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // returned an error. By not returning an error, With allows shortcuts like
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
 func (m *HistogramVec) With(labels Labels) Observer {
-       return m.MetricVec.With(labels).(Observer)
+       return m.metricVec.with(labels).(Observer)
 }
 
 type constHistogram struct {
@@ -401,8 +430,8 @@ func NewConstHistogram(
        buckets map[float64]uint64,
        labelValues ...string,
 ) (Metric, error) {
-       if len(desc.variableLabels) != len(labelValues) {
-               return nil, errInconsistentCardinality
+       if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
+               return nil, err
        }
        return &constHistogram{
                desc:       desc,
index d74fb4881e94d07c3b6701fd71688f5e6369a497..bfee5c6eb3756b1d2b3fab26b4daf0609270940c 100644 (file)
@@ -62,7 +62,8 @@ func giveBuf(buf *bytes.Buffer) {
 //
 // Deprecated: Please note the issues described in the doc comment of
 // InstrumentHandler. You might want to consider using promhttp.Handler instead
-// (which is not instrumented).
+// (which is not instrumented, but can be instrumented with the tooling provided
+// in package promhttp).
 func Handler() http.Handler {
        return InstrumentHandler("prometheus", UninstrumentedHandler())
 }
@@ -95,7 +96,7 @@ func UninstrumentedHandler() http.Handler {
                        closer.Close()
                }
                if lastErr != nil && buf.Len() == 0 {
-                       http.Error(w, "No metrics encoded, last error:\n\n"+err.Error(), http.StatusInternalServerError)
+                       http.Error(w, "No metrics encoded, last error:\n\n"+lastErr.Error(), http.StatusInternalServerError)
                        return
                }
                header := w.Header()
@@ -158,7 +159,8 @@ func nowSeries(t ...time.Time) nower {
 // value. http_requests_total is a metric vector partitioned by HTTP method
 // (label name "method") and HTTP status code (label name "code").
 //
-// Deprecated: InstrumentHandler has several issues:
+// Deprecated: InstrumentHandler has several issues. Use the tooling provided in
+// package promhttp instead. The issues are the following:
 //
 // - It uses Summaries rather than Histograms. Summaries are not useful if
 // aggregation across multiple instances is required.
@@ -174,10 +176,6 @@ func nowSeries(t ...time.Time) nower {
 //
 // - It has additional issues with HTTP/2, cf.
 // https://github.com/prometheus/client_golang/issues/272.
-//
-// Upcoming versions of this package will provide ways of instrumenting HTTP
-// handlers that are more flexible and have fewer issues. Please prefer direct
-// instrumentation in the meantime.
 func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc {
        return InstrumentHandlerFunc(handlerName, handler.ServeHTTP)
 }
@@ -187,7 +185,7 @@ func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFun
 // issues).
 //
 // Deprecated: InstrumentHandlerFunc is deprecated for the same reasons as
-// InstrumentHandler is.
+// InstrumentHandler is. Use the tooling provided in package promhttp instead.
 func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
        return InstrumentHandlerFuncWithOpts(
                SummaryOpts{
@@ -226,7 +224,7 @@ func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWri
 // SummaryOpts.
 //
 // Deprecated: InstrumentHandlerWithOpts is deprecated for the same reasons as
-// InstrumentHandler is.
+// InstrumentHandler is. Use the tooling provided in package promhttp instead.
 func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.HandlerFunc {
        return InstrumentHandlerFuncWithOpts(opts, handler.ServeHTTP)
 }
@@ -237,7 +235,7 @@ func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.Hand
 // SummaryOpts are used.
 //
 // Deprecated: InstrumentHandlerFuncWithOpts is deprecated for the same reasons
-// as InstrumentHandler is.
+// as InstrumentHandler is. Use the tooling provided in package promhttp instead.
 func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
        reqCnt := NewCounterVec(
                CounterOpts{
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_7.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_7.go
deleted file mode 100644 (file)
index 5e38c7c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !go1.8
-
-package promhttp
-
-import (
-       "io"
-       "net/http"
-)
-
-func newDelegator(w http.ResponseWriter) delegator {
-       d := &responseWriterDelegator{ResponseWriter: w}
-
-       _, cn := w.(http.CloseNotifier)
-       _, fl := w.(http.Flusher)
-       _, hj := w.(http.Hijacker)
-       _, rf := w.(io.ReaderFrom)
-       if cn && fl && hj && rf {
-               return &fancyDelegator{d}
-       }
-
-       return d
-}
index 98b5650961c544b8044a2d52a1eee83191ea3ae8..f4d386f7a393f61b502f6c6a08463c3805203771 100644 (file)
@@ -20,51 +20,162 @@ import (
        "net/http"
 )
 
-// newDelegator handles the four different methods of upgrading a
-// http.ResponseWriter to delegator.
-func newDelegator(w http.ResponseWriter) delegator {
-       d := &responseWriterDelegator{ResponseWriter: w}
+type pusherDelegator struct{ *responseWriterDelegator }
 
-       _, cn := w.(http.CloseNotifier)
-       _, fl := w.(http.Flusher)
-       _, hj := w.(http.Hijacker)
-       _, ps := w.(http.Pusher)
-       _, rf := w.(io.ReaderFrom)
-
-       // Check for the four most common combination of interfaces a
-       // http.ResponseWriter might implement.
-       switch {
-       case cn && fl && hj && rf && ps:
-               // All interfaces.
-               return &fancyPushDelegator{
-                       fancyDelegator: &fancyDelegator{d},
-                       p:              &pushDelegator{d},
-               }
-       case cn && fl && hj && rf:
-               // All interfaces, except http.Pusher.
-               return &fancyDelegator{d}
-       case ps:
-               // Just http.Pusher.
-               return &pushDelegator{d}
-       }
-
-       return d
+func (d *pusherDelegator) Push(target string, opts *http.PushOptions) error {
+       return d.ResponseWriter.(http.Pusher).Push(target, opts)
 }
 
-type fancyPushDelegator struct {
-       p *pushDelegator
-
-       *fancyDelegator
+func init() {
+       pickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16
+               return pusherDelegator{d}
+       }
+       pickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       http.CloseNotifier
+               }{d, &pusherDelegator{d}, &closeNotifierDelegator{d}}
+       }
+       pickDelegator[pusher+flusher] = func(d *responseWriterDelegator) delegator { // 18
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       http.Flusher
+               }{d, &pusherDelegator{d}, &flusherDelegator{d}}
+       }
+       pickDelegator[pusher+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 19
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       http.Flusher
+                       http.CloseNotifier
+               }{d, &pusherDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
+       }
+       pickDelegator[pusher+hijacker] = func(d *responseWriterDelegator) delegator { // 20
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       http.Hijacker
+               }{d, &pusherDelegator{d}, &hijackerDelegator{d}}
+       }
+       pickDelegator[pusher+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 21
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       http.Hijacker
+                       http.CloseNotifier
+               }{d, &pusherDelegator{d}, &hijackerDelegator{d}, &closeNotifierDelegator{d}}
+       }
+       pickDelegator[pusher+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 22
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       http.Hijacker
+                       http.Flusher
+               }{d, &pusherDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}}
+       }
+       pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       http.Hijacker
+                       http.Flusher
+                       http.CloseNotifier
+               }{d, &pusherDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
+       }
+       pickDelegator[pusher+readerFrom] = func(d *responseWriterDelegator) delegator { // 24
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       io.ReaderFrom
+               }{d, &pusherDelegator{d}, &readerFromDelegator{d}}
+       }
+       pickDelegator[pusher+readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 25
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       io.ReaderFrom
+                       http.CloseNotifier
+               }{d, &pusherDelegator{d}, &readerFromDelegator{d}, &closeNotifierDelegator{d}}
+       }
+       pickDelegator[pusher+readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 26
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       io.ReaderFrom
+                       http.Flusher
+               }{d, &pusherDelegator{d}, &readerFromDelegator{d}, &flusherDelegator{d}}
+       }
+       pickDelegator[pusher+readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 27
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       io.ReaderFrom
+                       http.Flusher
+                       http.CloseNotifier
+               }{d, &pusherDelegator{d}, &readerFromDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
+       }
+       pickDelegator[pusher+readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 28
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       io.ReaderFrom
+                       http.Hijacker
+               }{d, &pusherDelegator{d}, &readerFromDelegator{d}, &hijackerDelegator{d}}
+       }
+       pickDelegator[pusher+readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 29
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       io.ReaderFrom
+                       http.Hijacker
+                       http.CloseNotifier
+               }{d, &pusherDelegator{d}, &readerFromDelegator{d}, &hijackerDelegator{d}, &closeNotifierDelegator{d}}
+       }
+       pickDelegator[pusher+readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 30
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       io.ReaderFrom
+                       http.Hijacker
+                       http.Flusher
+               }{d, &pusherDelegator{d}, &readerFromDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}}
+       }
+       pickDelegator[pusher+readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 31
+               return struct {
+                       *responseWriterDelegator
+                       http.Pusher
+                       io.ReaderFrom
+                       http.Hijacker
+                       http.Flusher
+                       http.CloseNotifier
+               }{d, &pusherDelegator{d}, &readerFromDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
+       }
 }
 
-func (f *fancyPushDelegator) Push(target string, opts *http.PushOptions) error {
-       return f.p.Push(target, opts)
-}
+func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
+       d := &responseWriterDelegator{
+               ResponseWriter:     w,
+               observeWriteHeader: observeWriteHeaderFunc,
+       }
 
-type pushDelegator struct {
-       *responseWriterDelegator
-}
+       id := 0
+       if _, ok := w.(http.CloseNotifier); ok {
+               id += closeNotifier
+       }
+       if _, ok := w.(http.Flusher); ok {
+               id += flusher
+       }
+       if _, ok := w.(http.Hijacker); ok {
+               id += hijacker
+       }
+       if _, ok := w.(io.ReaderFrom); ok {
+               id += readerFrom
+       }
+       if _, ok := w.(http.Pusher); ok {
+               id += pusher
+       }
 
-func (f *pushDelegator) Push(target string, opts *http.PushOptions) error {
-       return f.ResponseWriter.(http.Pusher).Push(target, opts)
+       return pickDelegator[id](d)
 }
index 82d5656257b674daa8fa4b23ef8b40f5b2716fd2..2d67f2496293c44f5425632d3d6ece79befe4522 100644 (file)
 // via middleware. Middleware wrappers follow the naming scheme
 // InstrumentHandlerX, where X describes the intended use of the middleware.
 // See each function's doc comment for specific details.
+//
+// Finally, the package allows for an http.RoundTripper to be instrumented via
+// middleware. Middleware wrappers follow the naming scheme
+// InstrumentRoundTripperX, where X describes the intended use of the
+// middleware. See each function's doc comment for specific details.
 package promhttp
 
 import (
@@ -123,7 +128,7 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
                        closer.Close()
                }
                if lastErr != nil && buf.Len() == 0 {
-                       http.Error(w, "No metrics encoded, last error:\n\n"+err.Error(), http.StatusInternalServerError)
+                       http.Error(w, "No metrics encoded, last error:\n\n"+lastErr.Error(), http.StatusInternalServerError)
                        return
                }
                header := w.Header()
index 31e15cbae2e1e7149140b85c0980f3182858b3da..3d145adbf0963091864d110f0ef8257e06cfa3cb 100644 (file)
@@ -14,9 +14,6 @@
 package promhttp
 
 import (
-       "bufio"
-       "io"
-       "net"
        "net/http"
        "strconv"
        "strings"
@@ -27,6 +24,9 @@ import (
        "github.com/prometheus/client_golang/prometheus"
 )
 
+// magicString is used for the hacky label test in checkLabels. Remove once fixed.
+const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa"
+
 // InstrumentHandlerInFlight is a middleware that wraps the provided
 // http.Handler. It sets the provided prometheus.Gauge to the number of
 // requests currently handled by the wrapped http.Handler.
@@ -54,13 +54,16 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl
 // If the wrapped Handler does not set a status code, a status code of 200 is assumed.
 //
 // If the wrapped Handler panics, no values are reported.
+//
+// Note that this method is only guaranteed to never observe negative durations
+// if used with Go1.9+.
 func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
        code, method := checkLabels(obs)
 
        if code {
                return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                        now := time.Now()
-                       d := newDelegator(w)
+                       d := newDelegator(w, nil)
                        next.ServeHTTP(d, r)
 
                        obs.With(labels(code, method, r.Method, d.Status())).Observe(time.Since(now).Seconds())
@@ -80,7 +83,7 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) ht
 // names are "code" and "method". The function panics if any other instance
 // labels are provided. Partitioning of the CounterVec happens by HTTP status
 // code and/or HTTP method if the respective instance label names are present
-// in the CounterVec. For unpartitioned observations, use a CounterVec with
+// in the CounterVec. For unpartitioned counting, use a CounterVec with
 // zero labels.
 //
 // If the wrapped Handler does not set a status code, a status code of 200 is assumed.
@@ -93,7 +96,7 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler)
 
        if code {
                return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-                       d := newDelegator(w)
+                       d := newDelegator(w, nil)
                        next.ServeHTTP(d, r)
                        counter.With(labels(code, method, r.Method, d.Status())).Inc()
                })
@@ -105,6 +108,37 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler)
        })
 }
 
+// InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided
+// http.Handler to observe with the provided ObserverVec the request duration
+// until the response headers are written. The ObserverVec must have zero, one,
+// or two labels. The only allowed label names are "code" and "method". The
+// function panics if any other instance labels are provided. The Observe
+// method of the Observer in the ObserverVec is called with the request
+// duration in seconds. Partitioning happens by HTTP status code and/or HTTP
+// method if the respective instance label names are present in the
+// ObserverVec. For unpartitioned observations, use an ObserverVec with zero
+// labels. Note that partitioning of Histograms is expensive and should be used
+// judiciously.
+//
+// If the wrapped Handler panics before calling WriteHeader, no value is
+// reported.
+//
+// Note that this method is only guaranteed to never observe negative durations
+// if used with Go1.9+.
+//
+// See the example for InstrumentHandlerDuration for example usage.
+func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
+       code, method := checkLabels(obs)
+
+       return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+               now := time.Now()
+               d := newDelegator(w, func(status int) {
+                       obs.With(labels(code, method, r.Method, status)).Observe(time.Since(now).Seconds())
+               })
+               next.ServeHTTP(d, r)
+       })
+}
+
 // InstrumentHandlerRequestSize is a middleware that wraps the provided
 // http.Handler to observe the request size with the provided ObserverVec.
 // The ObserverVec must have zero, one, or two labels. The only allowed label
@@ -126,7 +160,7 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler)
 
        if code {
                return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-                       d := newDelegator(w)
+                       d := newDelegator(w, nil)
                        next.ServeHTTP(d, r)
                        size := computeApproximateRequestSize(r)
                        obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(size))
@@ -159,7 +193,7 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler)
 func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler) http.Handler {
        code, method := checkLabels(obs)
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-               d := newDelegator(w)
+               d := newDelegator(w, nil)
                next.ServeHTTP(d, r)
                obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(d.Written()))
        })
@@ -191,37 +225,46 @@ func checkLabels(c prometheus.Collector) (code bool, method bool) {
 
        if _, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0); err == nil {
                return
-       } else if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, ""); err == nil {
+       }
+       if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, magicString); err == nil {
                if err := m.Write(&pm); err != nil {
                        panic("error checking metric for labels")
                }
-
-               name := *pm.Label[0].Name
-               if name == "code" {
-                       code = true
-               } else if name == "method" {
-                       method = true
-               } else {
-                       panic("metric partitioned with non-supported labels")
+               for _, label := range pm.Label {
+                       name, value := label.GetName(), label.GetValue()
+                       if value != magicString {
+                               continue
+                       }
+                       switch name {
+                       case "code":
+                               code = true
+                       case "method":
+                               method = true
+                       default:
+                               panic("metric partitioned with non-supported labels")
+                       }
+                       return
                }
-               return
-       } else if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, "", ""); err == nil {
+               panic("previously set label not found â€“ this must never happen")
+       }
+       if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, magicString, magicString); err == nil {
                if err := m.Write(&pm); err != nil {
                        panic("error checking metric for labels")
                }
-
                for _, label := range pm.Label {
-                       if *label.Name == "code" || *label.Name == "method" {
+                       name, value := label.GetName(), label.GetValue()
+                       if value != magicString {
+                               continue
+                       }
+                       if name == "code" || name == "method" {
                                continue
                        }
                        panic("metric partitioned with non-supported labels")
                }
-
                code = true
                method = true
                return
        }
-
        panic("metric partitioned with non-supported labels")
 }
 
@@ -395,67 +438,3 @@ func sanitizeCode(s int) string {
                return strconv.Itoa(s)
        }
 }
-
-type delegator interface {
-       Status() int
-       Written() int64
-
-       http.ResponseWriter
-}
-
-type responseWriterDelegator struct {
-       http.ResponseWriter
-
-       handler, method string
-       status          int
-       written         int64
-       wroteHeader     bool
-}
-
-func (r *responseWriterDelegator) Status() int {
-       return r.status
-}
-
-func (r *responseWriterDelegator) Written() int64 {
-       return r.written
-}
-
-func (r *responseWriterDelegator) WriteHeader(code int) {
-       r.status = code
-       r.wroteHeader = true
-       r.ResponseWriter.WriteHeader(code)
-}
-
-func (r *responseWriterDelegator) Write(b []byte) (int, error) {
-       if !r.wroteHeader {
-               r.WriteHeader(http.StatusOK)
-       }
-       n, err := r.ResponseWriter.Write(b)
-       r.written += int64(n)
-       return n, err
-}
-
-type fancyDelegator struct {
-       *responseWriterDelegator
-}
-
-func (r *fancyDelegator) CloseNotify() <-chan bool {
-       return r.ResponseWriter.(http.CloseNotifier).CloseNotify()
-}
-
-func (r *fancyDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
-       return r.ResponseWriter.(http.Hijacker).Hijack()
-}
-
-func (r *fancyDelegator) Flush() {
-       r.ResponseWriter.(http.Flusher).Flush()
-}
-
-func (r *fancyDelegator) ReadFrom(re io.Reader) (int64, error) {
-       if !r.wroteHeader {
-               r.WriteHeader(http.StatusOK)
-       }
-       n, err := r.ResponseWriter.(io.ReaderFrom).ReadFrom(re)
-       r.written += n
-       return n, err
-}
index 8c6b5bd8ee11d97c6072756e90fd493eadfc4ba0..8f2094cce5ff31af95f64603769cf1a17d6ebfe7 100644 (file)
@@ -20,6 +20,7 @@ import (
        "os"
        "sort"
        "sync"
+       "unicode/utf8"
 
        "github.com/golang/protobuf/proto"
 
@@ -80,7 +81,7 @@ func NewPedanticRegistry() *Registry {
 
 // Registerer is the interface for the part of a registry in charge of
 // registering and unregistering. Users of custom registries should use
-// Registerer as type for registration purposes (rather then the Registry type
+// Registerer as type for registration purposes (rather than the Registry type
 // directly). In that way, they are free to use custom Registerer implementation
 // (e.g. for testing purposes).
 type Registerer interface {
@@ -679,6 +680,12 @@ func checkMetricConsistency(
                )
        }
 
+       for _, labelPair := range dtoMetric.GetLabel() {
+               if !utf8.ValidString(*labelPair.Value) {
+                       return fmt.Errorf("collected metric's label %s is not utf8: %#v", *labelPair.Name, *labelPair.Value)
+               }
+       }
+
        // Is the metric unique (i.e. no other metric with the same name and the same label values)?
        h := hashNew()
        h = hashAdd(h, metricFamily.GetName())
index 1c65e25ece6d4778efe82092adbfe622a7176f5c..21c031e4b7dca7c49988a49e1b77193b21bac893 100644 (file)
@@ -36,7 +36,10 @@ const quantileLabel = "quantile"
 //
 // A typical use-case is the observation of request latencies. By default, a
 // Summary provides the median, the 90th and the 99th percentile of the latency
-// as rank estimations.
+// as rank estimations. However, the default behavior will change in the
+// upcoming v0.10 of the library. There will be no rank estiamtions at all by
+// default. For a sane transition, it is recommended to set the desired rank
+// estimations explicitly.
 //
 // Note that the rank estimations cannot be aggregated in a meaningful way with
 // the Prometheus query language (i.e. you cannot average or add them). If you
@@ -78,8 +81,10 @@ const (
 )
 
 // SummaryOpts bundles the options for creating a Summary metric. It is
-// mandatory to set Name and Help to a non-empty string. All other fields are
-// optional and can safely be left at their zero value.
+// mandatory to set Name and Help to a non-empty string. While all other fields
+// are optional and can safely be left at their zero value, it is recommended to
+// explicitly set the Objectives field to the desired value as the default value
+// will change in the upcoming v0.10 of the library.
 type SummaryOpts struct {
        // Namespace, Subsystem, and Name are components of the fully-qualified
        // name of the Summary (created by joining these components with
@@ -399,12 +404,11 @@ func (s quantSort) Less(i, j int) bool {
 // (e.g. HTTP request latencies, partitioned by status code and method). Create
 // instances with NewSummaryVec.
 type SummaryVec struct {
-       *MetricVec
+       *metricVec
 }
 
 // NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and
-// partitioned by the given label names. At least one label name must be
-// provided.
+// partitioned by the given label names.
 func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
        desc := NewDesc(
                BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
@@ -413,28 +417,58 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
                opts.ConstLabels,
        )
        return &SummaryVec{
-               MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
+               metricVec: newMetricVec(desc, func(lvs ...string) Metric {
                        return newSummary(desc, opts, lvs...)
                }),
        }
 }
 
-// GetMetricWithLabelValues replaces the method of the same name in MetricVec.
-// The difference is that this method returns an Observer and not a Metric so
-// that no type conversion to an Observer is required.
+// GetMetricWithLabelValues returns the Summary for the given slice of label
+// values (same order as the VariableLabels in Desc). If that combination of
+// label values is accessed for the first time, a new Summary is created.
+//
+// It is possible to call this method without using the returned Summary to only
+// create the new Summary but leave it at its starting value, a Summary without
+// any observations.
+//
+// Keeping the Summary for later use is possible (and should be considered if
+// performance is critical), but keep in mind that Reset, DeleteLabelValues and
+// Delete can be used to delete the Summary from the SummaryVec. In that case, the
+// Summary will still exist, but it will not be exported anymore, even if a
+// Summary with the same label values is created later. See also the CounterVec
+// example.
+//
+// An error is returned if the number of label values is not the same as the
+// number of VariableLabels in Desc.
+//
+// Note that for more than one label value, this method is prone to mistakes
+// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
+// an alternative to avoid that type of mistake. For higher label numbers, the
+// latter has a much more readable (albeit more verbose) syntax, but it comes
+// with a performance overhead (for creating and processing the Labels map).
+// See also the GaugeVec example.
 func (m *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
-       metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
+       metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
        if metric != nil {
                return metric.(Observer), err
        }
        return nil, err
 }
 
-// GetMetricWith replaces the method of the same name in MetricVec. The
-// difference is that this method returns an Observer and not a Metric so that
-// no type conversion to an Observer is required.
+// GetMetricWith returns the Summary for the given Labels map (the label names
+// must match those of the VariableLabels in Desc). If that label map is
+// accessed for the first time, a new Summary is created. Implications of
+// creating a Summary without using it and keeping the Summary for later use are
+// the same as for GetMetricWithLabelValues.
+//
+// An error is returned if the number and names of the Labels are inconsistent
+// with those of the VariableLabels in Desc.
+//
+// This method is used for the same purpose as
+// GetMetricWithLabelValues(...string). See there for pros and cons of the two
+// methods.
 func (m *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {
-       metric, err := m.MetricVec.GetMetricWith(labels)
+       metric, err := m.metricVec.getMetricWith(labels)
        if metric != nil {
                return metric.(Observer), err
        }
@@ -446,14 +480,14 @@ func (m *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {
 // error, WithLabelValues allows shortcuts like
 //     myVec.WithLabelValues("404", "GET").Observe(42.21)
 func (m *SummaryVec) WithLabelValues(lvs ...string) Observer {
-       return m.MetricVec.WithLabelValues(lvs...).(Observer)
+       return m.metricVec.withLabelValues(lvs...).(Observer)
 }
 
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // returned an error. By not returning an error, With allows shortcuts like
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
 func (m *SummaryVec) With(labels Labels) Observer {
-       return m.MetricVec.With(labels).(Observer)
+       return m.metricVec.with(labels).(Observer)
 }
 
 type constSummary struct {
@@ -514,8 +548,8 @@ func NewConstSummary(
        quantiles map[float64]float64,
        labelValues ...string,
 ) (Metric, error) {
-       if len(desc.variableLabels) != len(labelValues) {
-               return nil, errInconsistentCardinality
+       if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
+               return nil, err
        }
        return &constSummary{
                desc:       desc,
index 12b65699b999bf920a5f6ee6ff0ad5fd0a71af7b..b8fc5f18c853a44abb7a9b925dd39f2210dcb98b 100644 (file)
@@ -41,6 +41,9 @@ func NewTimer(o Observer) *Timer {
 // NewTimer. It calls the Observe method of the Observer provided during
 // construction with the duration in seconds as an argument. ObserveDuration is
 // usually called with a defer statement.
+//
+// Note that this method is only guaranteed to never observe negative durations
+// if used with Go1.9+.
 func (t *Timer) ObserveDuration() {
        if t.observer != nil {
                t.observer.Observe(time.Since(t.begin).Seconds())
index 065501d38fb30ea7f8119fcf093cf140a232cb9a..0f9ce63f4093be007f8ed0ed19e5228a0f1dc2ce 100644 (file)
 
 package prometheus
 
-// Untyped is a Metric that represents a single numerical value that can
-// arbitrarily go up and down.
-//
-// An Untyped metric works the same as a Gauge. The only difference is that to
-// no type information is implied.
-//
-// To create Untyped instances, use NewUntyped.
-//
-// Deprecated: The Untyped type is deprecated because it doesn't make sense in
-// direct instrumentation. If you need to mirror an external metric of unknown
-// type (usually while writing exporters), Use MustNewConstMetric to create an
-// untyped metric instance on the fly.
-type Untyped interface {
-       Metric
-       Collector
-
-       // Set sets the Untyped metric to an arbitrary value.
-       Set(float64)
-       // Inc increments the Untyped metric by 1.
-       Inc()
-       // Dec decrements the Untyped metric by 1.
-       Dec()
-       // Add adds the given value to the Untyped metric. (The value can be
-       // negative, resulting in a decrease.)
-       Add(float64)
-       // Sub subtracts the given value from the Untyped metric. (The value can
-       // be negative, resulting in an increase.)
-       Sub(float64)
-}
-
 // UntypedOpts is an alias for Opts. See there for doc comments.
 type UntypedOpts Opts
 
-// NewUntyped creates a new Untyped metric from the provided UntypedOpts.
-func NewUntyped(opts UntypedOpts) Untyped {
-       return newValue(NewDesc(
-               BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-               opts.Help,
-               nil,
-               opts.ConstLabels,
-       ), UntypedValue, 0)
-}
-
-// UntypedVec is a Collector that bundles a set of Untyped metrics that all
-// share the same Desc, but have different values for their variable
-// labels. This is used if you want to count the same thing partitioned by
-// various dimensions. Create instances with NewUntypedVec.
-type UntypedVec struct {
-       *MetricVec
-}
-
-// NewUntypedVec creates a new UntypedVec based on the provided UntypedOpts and
-// partitioned by the given label names. At least one label name must be
-// provided.
-func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec {
-       desc := NewDesc(
-               BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
-               opts.Help,
-               labelNames,
-               opts.ConstLabels,
-       )
-       return &UntypedVec{
-               MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
-                       return newValue(desc, UntypedValue, 0, lvs...)
-               }),
-       }
-}
-
-// GetMetricWithLabelValues replaces the method of the same name in
-// MetricVec. The difference is that this method returns an Untyped and not a
-// Metric so that no type conversion is required.
-func (m *UntypedVec) GetMetricWithLabelValues(lvs ...string) (Untyped, error) {
-       metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
-       if metric != nil {
-               return metric.(Untyped), err
-       }
-       return nil, err
-}
-
-// GetMetricWith replaces the method of the same name in MetricVec. The
-// difference is that this method returns an Untyped and not a Metric so that no
-// type conversion is required.
-func (m *UntypedVec) GetMetricWith(labels Labels) (Untyped, error) {
-       metric, err := m.MetricVec.GetMetricWith(labels)
-       if metric != nil {
-               return metric.(Untyped), err
-       }
-       return nil, err
-}
-
-// WithLabelValues works as GetMetricWithLabelValues, but panics where
-// GetMetricWithLabelValues would have returned an error. By not returning an
-// error, WithLabelValues allows shortcuts like
-//     myVec.WithLabelValues("404", "GET").Add(42)
-func (m *UntypedVec) WithLabelValues(lvs ...string) Untyped {
-       return m.MetricVec.WithLabelValues(lvs...).(Untyped)
-}
-
-// With works as GetMetricWith, but panics where GetMetricWithLabels would have
-// returned an error. By not returning an error, With allows shortcuts like
-//     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
-func (m *UntypedVec) With(labels Labels) Untyped {
-       return m.MetricVec.With(labels).(Untyped)
-}
-
-// UntypedFunc is an Untyped whose value is determined at collect time by
-// calling a provided function.
+// UntypedFunc works like GaugeFunc but the collected metric is of type
+// "Untyped". UntypedFunc is useful to mirror an external metric of unknown
+// type.
 //
 // To create UntypedFunc instances, use NewUntypedFunc.
 type UntypedFunc interface {
index ff75ce585142766e4a16f1e1b1f837c1e595e80a..4a9cca6669baaae917b2bffbab583fbb9adf5982 100644 (file)
@@ -14,7 +14,6 @@
 package prometheus
 
 import (
-       "errors"
        "fmt"
        "math"
        "sort"
@@ -37,8 +36,6 @@ const (
        UntypedValue
 )
 
-var errInconsistentCardinality = errors.New("inconsistent label cardinality")
-
 // value is a generic metric for simple values. It implements Metric, Collector,
 // Counter, Gauge, and Untyped. Its effective type is determined by
 // ValueType. This is a low-level building block used by the library to back the
@@ -158,8 +155,8 @@ func (v *valueFunc) Write(out *dto.Metric) error {
 // the Collect method. NewConstMetric returns an error if the length of
 // labelValues is not consistent with the variable labels in Desc.
 func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {
-       if len(desc.variableLabels) != len(labelValues) {
-               return nil, errInconsistentCardinality
+       if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
+               return nil, err
        }
        return &constMetric{
                desc:       desc,
index 7f3eef9a46707813913a49bc466528ccd87a6c2f..65d13fe1ef077774ef8744acab3678acbe201c35 100644 (file)
@@ -20,12 +20,12 @@ import (
        "github.com/prometheus/common/model"
 )
 
-// MetricVec is a Collector to bundle metrics of the same name that
-// differ in their label values. MetricVec is usually not used directly but as a
-// building block for implementations of vectors of a given metric
-// type. GaugeVec, CounterVec, SummaryVec, and UntypedVec are examples already
-// provided in this package.
-type MetricVec struct {
+// metricVec is a Collector to bundle metrics of the same name that differ in
+// their label values. metricVec is not used directly (and therefore
+// unexported). It is used as a building block for implementations of vectors of
+// a given metric type, like GaugeVec, CounterVec, SummaryVec, HistogramVec, and
+// UntypedVec.
+type metricVec struct {
        mtx      sync.RWMutex // Protects the children.
        children map[uint64][]metricWithLabelValues
        desc     *Desc
@@ -35,10 +35,9 @@ type MetricVec struct {
        hashAddByte func(h uint64, b byte) uint64
 }
 
-// newMetricVec returns an initialized MetricVec. The concrete value is
-// returned for embedding into another struct.
-func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec {
-       return &MetricVec{
+// newMetricVec returns an initialized metricVec.
+func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *metricVec {
+       return &metricVec{
                children:    map[uint64][]metricWithLabelValues{},
                desc:        desc,
                newMetric:   newMetric,
@@ -56,12 +55,12 @@ type metricWithLabelValues struct {
 
 // Describe implements Collector. The length of the returned slice
 // is always one.
-func (m *MetricVec) Describe(ch chan<- *Desc) {
+func (m *metricVec) Describe(ch chan<- *Desc) {
        ch <- m.desc
 }
 
 // Collect implements Collector.
-func (m *MetricVec) Collect(ch chan<- Metric) {
+func (m *metricVec) Collect(ch chan<- Metric) {
        m.mtx.RLock()
        defer m.mtx.RUnlock()
 
@@ -72,31 +71,7 @@ func (m *MetricVec) Collect(ch chan<- Metric) {
        }
 }
 
-// GetMetricWithLabelValues returns the Metric for the given slice of label
-// values (same order as the VariableLabels in Desc). If that combination of
-// label values is accessed for the first time, a new Metric is created.
-//
-// It is possible to call this method without using the returned Metric to only
-// create the new Metric but leave it at its start value (e.g. a Summary or
-// Histogram without any observations). See also the SummaryVec example.
-//
-// Keeping the Metric for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Metric from the MetricVec. In that case, the
-// Metric will still exist, but it will not be exported anymore, even if a
-// Metric with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of VariableLabels in Desc.
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
-func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
+func (m *metricVec) getMetricWithLabelValues(lvs ...string) (Metric, error) {
        h, err := m.hashLabelValues(lvs)
        if err != nil {
                return nil, err
@@ -105,19 +80,7 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
        return m.getOrCreateMetricWithLabelValues(h, lvs), nil
 }
 
-// GetMetricWith returns the Metric for the given Labels map (the label names
-// must match those of the VariableLabels in Desc). If that label map is
-// accessed for the first time, a new Metric is created. Implications of
-// creating a Metric without using it and keeping the Metric for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc.
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
+func (m *metricVec) getMetricWith(labels Labels) (Metric, error) {
        h, err := m.hashLabels(labels)
        if err != nil {
                return nil, err
@@ -126,22 +89,16 @@ func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
        return m.getOrCreateMetricWithLabels(h, labels), nil
 }
 
-// WithLabelValues works as GetMetricWithLabelValues, but panics if an error
-// occurs. The method allows neat syntax like:
-//     httpReqs.WithLabelValues("404", "POST").Inc()
-func (m *MetricVec) WithLabelValues(lvs ...string) Metric {
-       metric, err := m.GetMetricWithLabelValues(lvs...)
+func (m *metricVec) withLabelValues(lvs ...string) Metric {
+       metric, err := m.getMetricWithLabelValues(lvs...)
        if err != nil {
                panic(err)
        }
        return metric
 }
 
-// With works as GetMetricWith, but panics if an error occurs. The method allows
-// neat syntax like:
-//     httpReqs.With(Labels{"status":"404", "method":"POST"}).Inc()
-func (m *MetricVec) With(labels Labels) Metric {
-       metric, err := m.GetMetricWith(labels)
+func (m *metricVec) with(labels Labels) Metric {
+       metric, err := m.getMetricWith(labels)
        if err != nil {
                panic(err)
        }
@@ -153,8 +110,8 @@ func (m *MetricVec) With(labels Labels) Metric {
 // returns true if a metric was deleted.
 //
 // It is not an error if the number of label values is not the same as the
-// number of VariableLabels in Desc.  However, such inconsistent label count can
-// never match an actual Metric, so the method will always return false in that
+// number of VariableLabels in Desc. However, such inconsistent label count can
+// never match an actual metric, so the method will always return false in that
 // case.
 //
 // Note that for more than one label value, this method is prone to mistakes
@@ -163,7 +120,7 @@ func (m *MetricVec) With(labels Labels) Metric {
 // latter has a much more readable (albeit more verbose) syntax, but it comes
 // with a performance overhead (for creating and processing the Labels map).
 // See also the CounterVec example.
-func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
+func (m *metricVec) DeleteLabelValues(lvs ...string) bool {
        m.mtx.Lock()
        defer m.mtx.Unlock()
 
@@ -178,13 +135,13 @@ func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
 // passed in as labels. It returns true if a metric was deleted.
 //
 // It is not an error if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in the Desc of the MetricVec. However, such
-// inconsistent Labels can never match an actual Metric, so the method will
-// always return false in that case.
+// with those of the VariableLabels in Desc. However, such inconsistent Labels
+// can never match an actual metric, so the method will always return false in
+// that case.
 //
 // This method is used for the same purpose as DeleteLabelValues(...string). See
 // there for pros and cons of the two methods.
-func (m *MetricVec) Delete(labels Labels) bool {
+func (m *metricVec) Delete(labels Labels) bool {
        m.mtx.Lock()
        defer m.mtx.Unlock()
 
@@ -199,7 +156,7 @@ func (m *MetricVec) Delete(labels Labels) bool {
 // deleteByHashWithLabelValues removes the metric from the hash bucket h. If
 // there are multiple matches in the bucket, use lvs to select a metric and
 // remove only that metric.
-func (m *MetricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool {
+func (m *metricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool {
        metrics, ok := m.children[h]
        if !ok {
                return false
@@ -221,7 +178,7 @@ func (m *MetricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool {
 // deleteByHashWithLabels removes the metric from the hash bucket h. If there
 // are multiple matches in the bucket, use lvs to select a metric and remove
 // only that metric.
-func (m *MetricVec) deleteByHashWithLabels(h uint64, labels Labels) bool {
+func (m *metricVec) deleteByHashWithLabels(h uint64, labels Labels) bool {
        metrics, ok := m.children[h]
        if !ok {
                return false
@@ -240,7 +197,7 @@ func (m *MetricVec) deleteByHashWithLabels(h uint64, labels Labels) bool {
 }
 
 // Reset deletes all metrics in this vector.
-func (m *MetricVec) Reset() {
+func (m *metricVec) Reset() {
        m.mtx.Lock()
        defer m.mtx.Unlock()
 
@@ -249,10 +206,11 @@ func (m *MetricVec) Reset() {
        }
 }
 
-func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
-       if len(vals) != len(m.desc.variableLabels) {
-               return 0, errInconsistentCardinality
+func (m *metricVec) hashLabelValues(vals []string) (uint64, error) {
+       if err := validateLabelValues(vals, len(m.desc.variableLabels)); err != nil {
+               return 0, err
        }
+
        h := hashNew()
        for _, val := range vals {
                h = m.hashAdd(h, val)
@@ -261,10 +219,11 @@ func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
        return h, nil
 }
 
-func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
-       if len(labels) != len(m.desc.variableLabels) {
-               return 0, errInconsistentCardinality
+func (m *metricVec) hashLabels(labels Labels) (uint64, error) {
+       if err := validateValuesInLabels(labels, len(m.desc.variableLabels)); err != nil {
+               return 0, err
        }
+
        h := hashNew()
        for _, label := range m.desc.variableLabels {
                val, ok := labels[label]
@@ -281,9 +240,9 @@ func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
 // or creates it and returns the new one.
 //
 // This function holds the mutex.
-func (m *MetricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string) Metric {
+func (m *metricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string) Metric {
        m.mtx.RLock()
-       metric, ok := m.getMetricWithLabelValues(hash, lvs)
+       metric, ok := m.getMetricWithHashAndLabelValues(hash, lvs)
        m.mtx.RUnlock()
        if ok {
                return metric
@@ -291,7 +250,7 @@ func (m *MetricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string)
 
        m.mtx.Lock()
        defer m.mtx.Unlock()
-       metric, ok = m.getMetricWithLabelValues(hash, lvs)
+       metric, ok = m.getMetricWithHashAndLabelValues(hash, lvs)
        if !ok {
                // Copy to avoid allocation in case wo don't go down this code path.
                copiedLVs := make([]string, len(lvs))
@@ -306,9 +265,9 @@ func (m *MetricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string)
 // or creates it and returns the new one.
 //
 // This function holds the mutex.
-func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metric {
+func (m *metricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metric {
        m.mtx.RLock()
-       metric, ok := m.getMetricWithLabels(hash, labels)
+       metric, ok := m.getMetricWithHashAndLabels(hash, labels)
        m.mtx.RUnlock()
        if ok {
                return metric
@@ -316,7 +275,7 @@ func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metr
 
        m.mtx.Lock()
        defer m.mtx.Unlock()
-       metric, ok = m.getMetricWithLabels(hash, labels)
+       metric, ok = m.getMetricWithHashAndLabels(hash, labels)
        if !ok {
                lvs := m.extractLabelValues(labels)
                metric = m.newMetric(lvs...)
@@ -325,9 +284,9 @@ func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metr
        return metric
 }
 
-// getMetricWithLabelValues gets a metric while handling possible collisions in
-// the hash space. Must be called while holding read mutex.
-func (m *MetricVec) getMetricWithLabelValues(h uint64, lvs []string) (Metric, bool) {
+// getMetricWithHashAndLabelValues gets a metric while handling possible
+// collisions in the hash space. Must be called while holding the read mutex.
+func (m *metricVec) getMetricWithHashAndLabelValues(h uint64, lvs []string) (Metric, bool) {
        metrics, ok := m.children[h]
        if ok {
                if i := m.findMetricWithLabelValues(metrics, lvs); i < len(metrics) {
@@ -337,9 +296,9 @@ func (m *MetricVec) getMetricWithLabelValues(h uint64, lvs []string) (Metric, bo
        return nil, false
 }
 
-// getMetricWithLabels gets a metric while handling possible collisions in
+// getMetricWithHashAndLabels gets a metric while handling possible collisions in
 // the hash space. Must be called while holding read mutex.
-func (m *MetricVec) getMetricWithLabels(h uint64, labels Labels) (Metric, bool) {
+func (m *metricVec) getMetricWithHashAndLabels(h uint64, labels Labels) (Metric, bool) {
        metrics, ok := m.children[h]
        if ok {
                if i := m.findMetricWithLabels(metrics, labels); i < len(metrics) {
@@ -351,7 +310,7 @@ func (m *MetricVec) getMetricWithLabels(h uint64, labels Labels) (Metric, bool)
 
 // findMetricWithLabelValues returns the index of the matching metric or
 // len(metrics) if not found.
-func (m *MetricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, lvs []string) int {
+func (m *metricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, lvs []string) int {
        for i, metric := range metrics {
                if m.matchLabelValues(metric.values, lvs) {
                        return i
@@ -362,7 +321,7 @@ func (m *MetricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, l
 
 // findMetricWithLabels returns the index of the matching metric or len(metrics)
 // if not found.
-func (m *MetricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels Labels) int {
+func (m *metricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels Labels) int {
        for i, metric := range metrics {
                if m.matchLabels(metric.values, labels) {
                        return i
@@ -371,7 +330,7 @@ func (m *MetricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels
        return len(metrics)
 }
 
-func (m *MetricVec) matchLabelValues(values []string, lvs []string) bool {
+func (m *metricVec) matchLabelValues(values []string, lvs []string) bool {
        if len(values) != len(lvs) {
                return false
        }
@@ -383,7 +342,7 @@ func (m *MetricVec) matchLabelValues(values []string, lvs []string) bool {
        return true
 }
 
-func (m *MetricVec) matchLabels(values []string, labels Labels) bool {
+func (m *metricVec) matchLabels(values []string, labels Labels) bool {
        if len(labels) != len(values) {
                return false
        }
@@ -395,7 +354,7 @@ func (m *MetricVec) matchLabels(values []string, labels Labels) bool {
        return true
 }
 
-func (m *MetricVec) extractLabelValues(labels Labels) []string {
+func (m *metricVec) extractLabelValues(labels Labels) []string {
        labelValues := make([]string, len(labels))
        for i, k := range m.desc.variableLabels {
                labelValues[i] = labels[k]
index d22a9eea62ae6432bcd8133da7f60d27359818a2..cf8307ad285cac4cf172287ee7f441e236136e41 100644 (file)
@@ -57,6 +57,7 @@ func (l *AllowedLevel) Set(s string) error {
 // with a timestamp. The output always goes to stderr.
 func New(al AllowedLevel) log.Logger {
        l := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
+       l = level.NewFilter(l, al.o)
        l = log.With(l, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
        return l
 }
diff --git a/vendor/github.com/prometheus/procfs/AUTHORS.md b/vendor/github.com/prometheus/procfs/AUTHORS.md
deleted file mode 100644 (file)
index 0c802dd..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-The Prometheus project was started by Matt T. Proud (emeritus) and
-Julius Volz in 2012.
-
-Maintainers of this repository:
-
-* Tobias Schmidt <ts@soundcloud.com>
-
-The following individuals have contributed code to this repository
-(listed in alphabetical order):
-
-* Armen Baghumian <abaghumian@noggin.com.au>
-* Bjoern Rabenstein <beorn@soundcloud.com>
-* David Cournapeau <cournape@gmail.com>
-* Ji-Hoon, Seol <jihoon.seol@gmail.com>
-* Jonas Große Sundrup <cherti@letopolis.de>
-* Julius Volz <julius.volz@gmail.com>
-* Matthias Rampke <mr@soundcloud.com>
-* Nicky Gerritsen <nicky@streamone.nl>
-* Rémi Audebert <contact@halfr.net>
-* Tobias Schmidt <tobidt@gmail.com>
index 5705f0fbea291b9ca633f3f7880058d09f420c5f..40503edbf18fc9fbc06cda3f2dfd8035fadb01f0 100644 (file)
@@ -2,9 +2,9 @@
 
 Prometheus uses GitHub to manage reviews of pull requests.
 
-* If you have a trivial fix or improvement, go ahead and create a pull
-  request, addressing (with `@...`) one or more of the maintainers
-  (see [AUTHORS.md](AUTHORS.md)) in the description of the pull request.
+* If you have a trivial fix or improvement, go ahead and create a pull request,
+  addressing (with `@...`) the maintainer of this repository (see
+  [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request.
 
 * If you plan to do something more involved, first discuss your ideas
   on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers).
index c264a49d179705a261d1ca45370fcf27cedb1c95..dd48afdcd4570255c3043d5d8c14cfd3e1497e8f 100644 (file)
@@ -1,6 +1,18 @@
-ci:
+ci: fmt lint test
+
+fmt:
        ! gofmt -l *.go | read nothing
        go vet
-       go test -v ./...
+
+lint:
        go get github.com/golang/lint/golint
        golint *.go
+
+test: sysfs/fixtures/.unpacked
+       go test -v ./...
+
+sysfs/fixtures/.unpacked: sysfs/fixtures.ttar
+       ./ttar -C sysfs -x -f sysfs/fixtures.ttar
+       touch $@
+
+.PHONY: fmt lint test ci
index 6e7ee6b8b758b38762ff2bad9da63faea155e7f8..2095494719b08f9a72b69acf8860a37342a2b58b 100644 (file)
@@ -8,3 +8,4 @@ backwards-incompatible ways without warnings. Use it at your own risk.
 
 [![GoDoc](https://godoc.org/github.com/prometheus/procfs?status.png)](https://godoc.org/github.com/prometheus/procfs)
 [![Build Status](https://travis-ci.org/prometheus/procfs.svg?branch=master)](https://travis-ci.org/prometheus/procfs)
+[![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs)
index 49aaab0505d14f445b77c7bffe258e5d4c913c9d..17546756b336f3971d68d3c9b0cd34b9a9851415 100644 (file)
@@ -4,6 +4,8 @@ import (
        "fmt"
        "os"
        "path"
+
+       "github.com/prometheus/procfs/xfs"
 )
 
 // FS represents the pseudo-filesystem proc, which provides an interface to
@@ -31,3 +33,14 @@ func NewFS(mountPoint string) (FS, error) {
 func (fs FS) Path(p ...string) string {
        return path.Join(append([]string{string(fs)}, p...)...)
 }
+
+// XFSStats retrieves XFS filesystem runtime statistics.
+func (fs FS) XFSStats() (*xfs.Stats, error) {
+       f, err := os.Open(fs.Path("fs/xfs/stat"))
+       if err != nil {
+               return nil, err
+       }
+       defer f.Close()
+
+       return xfs.ParseStats(f)
+}
index e7012f7323ebd8b7f0fdddc9815a24d22e57b237..696d114e73e98cb52858a12c5f698befafc97084 100644 (file)
@@ -33,6 +33,8 @@ type IPVSBackendStatus struct {
        LocalAddress net.IP
        // The local (virtual) port.
        LocalPort uint16
+       // The local firewall mark
+       LocalMark string
        // The transport protocol (TCP, UDP).
        Proto string
        // The remote (real) IP address.
@@ -142,6 +144,7 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
                status       []IPVSBackendStatus
                scanner      = bufio.NewScanner(file)
                proto        string
+               localMark    string
                localAddress net.IP
                localPort    uint16
                err          error
@@ -160,10 +163,19 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
                                continue
                        }
                        proto = fields[0]
+                       localMark = ""
                        localAddress, localPort, err = parseIPPort(fields[1])
                        if err != nil {
                                return nil, err
                        }
+               case fields[0] == "FWM":
+                       if len(fields) < 2 {
+                               continue
+                       }
+                       proto = fields[0]
+                       localMark = fields[1]
+                       localAddress = nil
+                       localPort = 0
                case fields[0] == "->":
                        if len(fields) < 6 {
                                continue
@@ -187,6 +199,7 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
                        status = append(status, IPVSBackendStatus{
                                LocalAddress:  localAddress,
                                LocalPort:     localPort,
+                               LocalMark:     localMark,
                                RemoteAddress: remoteAddress,
                                RemotePort:    remotePort,
                                Proto:         proto,
@@ -200,22 +213,31 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
 }
 
 func parseIPPort(s string) (net.IP, uint16, error) {
-       tmp := strings.SplitN(s, ":", 2)
-
-       if len(tmp) != 2 {
-               return nil, 0, fmt.Errorf("invalid IP:Port: %s", s)
-       }
+       var (
+               ip  net.IP
+               err error
+       )
 
-       if len(tmp[0]) != 8 && len(tmp[0]) != 32 {
-               return nil, 0, fmt.Errorf("invalid IP: %s", tmp[0])
+       switch len(s) {
+       case 13:
+               ip, err = hex.DecodeString(s[0:8])
+               if err != nil {
+                       return nil, 0, err
+               }
+       case 46:
+               ip = net.ParseIP(s[1:40])
+               if ip == nil {
+                       return nil, 0, fmt.Errorf("invalid IPv6 address: %s", s[1:40])
+               }
+       default:
+               return nil, 0, fmt.Errorf("unexpected IP:Port: %s", s)
        }
 
-       ip, err := hex.DecodeString(tmp[0])
-       if err != nil {
-               return nil, 0, err
+       portString := s[len(s)-4:]
+       if len(portString) != 4 {
+               return nil, 0, fmt.Errorf("unexpected port string format: %s", portString)
        }
-
-       port, err := strconv.ParseUint(tmp[1], 16, 16)
+       port, err := strconv.ParseUint(portString, 16, 16)
        if err != nil {
                return nil, 0, err
        }
index deeab173591ac8e2294ef6a50ceb4e0723a0f313..8717e1fe0d2eff21bb866026535cf6c2ff424b05 100644 (file)
@@ -41,7 +41,7 @@ func NewProc(pid int) (Proc, error) {
        return fs.NewProc(pid)
 }
 
-// AllProcs returns a list of all currently avaible processes under /proc.
+// AllProcs returns a list of all currently available processes under /proc.
 func AllProcs() (Procs, error) {
        fs, err := NewFS(DefaultMountPoint)
        if err != nil {
@@ -71,7 +71,7 @@ func (fs FS) NewProc(pid int) (Proc, error) {
        return Proc{PID: pid, fs: fs}, nil
 }
 
-// AllProcs returns a list of all currently avaible processes.
+// AllProcs returns a list of all currently available processes.
 func (fs FS) AllProcs() (Procs, error) {
        d, err := os.Open(fs.Path())
        if err != nil {
@@ -192,6 +192,18 @@ func (p Proc) FileDescriptorsLen() (int, error) {
        return len(fds), nil
 }
 
+// MountStats retrieves statistics and configuration for mount points in a
+// process's namespace.
+func (p Proc) MountStats() ([]*Mount, error) {
+       f, err := os.Open(p.path("mountstats"))
+       if err != nil {
+               return nil, err
+       }
+       defer f.Close()
+
+       return parseMountStats(f)
+}
+
 func (p Proc) fileDescriptors() ([]string, error) {
        d, err := os.Open(p.path("fd"))
        if err != nil {
index acac02bb8ae964f8a546ab1bb19d3f5d79776237..2df997ce11fe090b7ce035572432feefb9d0c877 100644 (file)
@@ -87,7 +87,7 @@ func (p Proc) NewLimits() (ProcLimits, error) {
                case "Max cpu time":
                        l.CPUTime, err = parseInt(fields[1])
                case "Max file size":
-                       l.FileLocks, err = parseInt(fields[1])
+                       l.FileSize, err = parseInt(fields[1])
                case "Max data size":
                        l.DataSize, err = parseInt(fields[1])
                case "Max stack size":
index 1ca217e8c72e762aef10a40625a8547b104e67d9..701f4df6483777c38020a17f66d4df4505a347f5 100644 (file)
@@ -3,15 +3,66 @@ package procfs
 import (
        "bufio"
        "fmt"
+       "io"
        "os"
        "strconv"
        "strings"
 )
 
+// CPUStat shows how much time the cpu spend in various stages.
+type CPUStat struct {
+       User      float64
+       Nice      float64
+       System    float64
+       Idle      float64
+       Iowait    float64
+       IRQ       float64
+       SoftIRQ   float64
+       Steal     float64
+       Guest     float64
+       GuestNice float64
+}
+
+// SoftIRQStat represent the softirq statistics as exported in the procfs stat file.
+// A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html
+// It is possible to get per-cpu stats by reading /proc/softirqs
+type SoftIRQStat struct {
+       Hi          uint64
+       Timer       uint64
+       NetTx       uint64
+       NetRx       uint64
+       Block       uint64
+       BlockIoPoll uint64
+       Tasklet     uint64
+       Sched       uint64
+       Hrtimer     uint64
+       Rcu         uint64
+}
+
 // Stat represents kernel/system statistics.
 type Stat struct {
        // Boot time in seconds since the Epoch.
-       BootTime int64
+       BootTime uint64
+       // Summed up cpu statistics.
+       CPUTotal CPUStat
+       // Per-CPU statistics.
+       CPU []CPUStat
+       // Number of times interrupts were handled, which contains numbered and unnumbered IRQs.
+       IRQTotal uint64
+       // Number of times a numbered IRQ was triggered.
+       IRQ []uint64
+       // Number of times a context switch happened.
+       ContextSwitches uint64
+       // Number of times a process was created.
+       ProcessCreated uint64
+       // Number of processes currently running.
+       ProcessesRunning uint64
+       // Number of processes currently blocked (waiting for IO).
+       ProcessesBlocked uint64
+       // Number of times a softirq was scheduled.
+       SoftIRQTotal uint64
+       // Detailed softirq statistics.
+       SoftIRQ SoftIRQStat
 }
 
 // NewStat returns kernel/system statistics read from /proc/stat.
@@ -24,33 +75,145 @@ func NewStat() (Stat, error) {
        return fs.NewStat()
 }
 
+// Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum).
+func parseCPUStat(line string) (CPUStat, int64, error) {
+       cpuStat := CPUStat{}
+       var cpu string
+
+       count, err := fmt.Sscanf(line, "%s %f %f %f %f %f %f %f %f %f %f",
+               &cpu,
+               &cpuStat.User, &cpuStat.Nice, &cpuStat.System, &cpuStat.Idle,
+               &cpuStat.Iowait, &cpuStat.IRQ, &cpuStat.SoftIRQ, &cpuStat.Steal,
+               &cpuStat.Guest, &cpuStat.GuestNice)
+
+       if err != nil && err != io.EOF {
+               return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu): %s", line, err)
+       }
+       if count == 0 {
+               return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu): 0 elements parsed", line)
+       }
+
+       cpuStat.User /= userHZ
+       cpuStat.Nice /= userHZ
+       cpuStat.System /= userHZ
+       cpuStat.Idle /= userHZ
+       cpuStat.Iowait /= userHZ
+       cpuStat.IRQ /= userHZ
+       cpuStat.SoftIRQ /= userHZ
+       cpuStat.Steal /= userHZ
+       cpuStat.Guest /= userHZ
+       cpuStat.GuestNice /= userHZ
+
+       if cpu == "cpu" {
+               return cpuStat, -1, nil
+       }
+
+       cpuID, err := strconv.ParseInt(cpu[3:], 10, 64)
+       if err != nil {
+               return CPUStat{}, -1, fmt.Errorf("couldn't parse %s (cpu/cpuid): %s", line, err)
+       }
+
+       return cpuStat, cpuID, nil
+}
+
+// Parse a softirq line.
+func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) {
+       softIRQStat := SoftIRQStat{}
+       var total uint64
+       var prefix string
+
+       _, err := fmt.Sscanf(line, "%s %d %d %d %d %d %d %d %d %d %d %d",
+               &prefix, &total,
+               &softIRQStat.Hi, &softIRQStat.Timer, &softIRQStat.NetTx, &softIRQStat.NetRx,
+               &softIRQStat.Block, &softIRQStat.BlockIoPoll,
+               &softIRQStat.Tasklet, &softIRQStat.Sched,
+               &softIRQStat.Hrtimer, &softIRQStat.Rcu)
+
+       if err != nil {
+               return SoftIRQStat{}, 0, fmt.Errorf("couldn't parse %s (softirq): %s", line, err)
+       }
+
+       return softIRQStat, total, nil
+}
+
 // NewStat returns an information about current kernel/system statistics.
 func (fs FS) NewStat() (Stat, error) {
+       // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
+
        f, err := os.Open(fs.Path("stat"))
        if err != nil {
                return Stat{}, err
        }
        defer f.Close()
 
-       s := bufio.NewScanner(f)
-       for s.Scan() {
-               line := s.Text()
-               if !strings.HasPrefix(line, "btime") {
+       stat := Stat{}
+
+       scanner := bufio.NewScanner(f)
+       for scanner.Scan() {
+               line := scanner.Text()
+               parts := strings.Fields(scanner.Text())
+               // require at least <key> <value>
+               if len(parts) < 2 {
                        continue
                }
-               fields := strings.Fields(line)
-               if len(fields) != 2 {
-                       return Stat{}, fmt.Errorf("couldn't parse %s line %s", f.Name(), line)
-               }
-               i, err := strconv.ParseInt(fields[1], 10, 32)
-               if err != nil {
-                       return Stat{}, fmt.Errorf("couldn't parse %s: %s", fields[1], err)
+               switch {
+               case parts[0] == "btime":
+                       if stat.BootTime, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+                               return Stat{}, fmt.Errorf("couldn't parse %s (btime): %s", parts[1], err)
+                       }
+               case parts[0] == "intr":
+                       if stat.IRQTotal, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+                               return Stat{}, fmt.Errorf("couldn't parse %s (intr): %s", parts[1], err)
+                       }
+                       numberedIRQs := parts[2:]
+                       stat.IRQ = make([]uint64, len(numberedIRQs))
+                       for i, count := range numberedIRQs {
+                               if stat.IRQ[i], err = strconv.ParseUint(count, 10, 64); err != nil {
+                                       return Stat{}, fmt.Errorf("couldn't parse %s (intr%d): %s", count, i, err)
+                               }
+                       }
+               case parts[0] == "ctxt":
+                       if stat.ContextSwitches, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+                               return Stat{}, fmt.Errorf("couldn't parse %s (ctxt): %s", parts[1], err)
+                       }
+               case parts[0] == "processes":
+                       if stat.ProcessCreated, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+                               return Stat{}, fmt.Errorf("couldn't parse %s (processes): %s", parts[1], err)
+                       }
+               case parts[0] == "procs_running":
+                       if stat.ProcessesRunning, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+                               return Stat{}, fmt.Errorf("couldn't parse %s (procs_running): %s", parts[1], err)
+                       }
+               case parts[0] == "procs_blocked":
+                       if stat.ProcessesBlocked, err = strconv.ParseUint(parts[1], 10, 64); err != nil {
+                               return Stat{}, fmt.Errorf("couldn't parse %s (procs_blocked): %s", parts[1], err)
+                       }
+               case parts[0] == "softirq":
+                       softIRQStats, total, err := parseSoftIRQStat(line)
+                       if err != nil {
+                               return Stat{}, err
+                       }
+                       stat.SoftIRQTotal = total
+                       stat.SoftIRQ = softIRQStats
+               case strings.HasPrefix(parts[0], "cpu"):
+                       cpuStat, cpuID, err := parseCPUStat(line)
+                       if err != nil {
+                               return Stat{}, err
+                       }
+                       if cpuID == -1 {
+                               stat.CPUTotal = cpuStat
+                       } else {
+                               for int64(len(stat.CPU)) <= cpuID {
+                                       stat.CPU = append(stat.CPU, CPUStat{})
+                               }
+                               stat.CPU[cpuID] = cpuStat
+                       }
                }
-               return Stat{BootTime: i}, nil
        }
-       if err := s.Err(); err != nil {
+
+       if err := scanner.Err(); err != nil {
                return Stat{}, fmt.Errorf("couldn't parse %s: %s", f.Name(), err)
        }
 
-       return Stat{}, fmt.Errorf("couldn't parse %s, missing btime", f.Name())
+       return stat, nil
 }
index dd55181157686a577def344b9c0455c87a27e903..e6f15efd7d7dc93e9f29dc833c3a25f166c43f81 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
index 0213d1a1346a0637b600bd482dd1fd736c87e9a3..a68bfb010f5608126d37206b610f97d8d67da027 100644 (file)
@@ -51,7 +51,7 @@ func (c *PacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
        }
        // Please be informed that ipv4.NewPacketConn enables
        // IP_STRIPHDR option by default on Darwin.
-       // See golang.org/issue/9395 for futher information.
+       // See golang.org/issue/9395 for further information.
        if runtime.GOOS == "darwin" && c.p4 != nil {
                n, _, peer, err := c.p4.ReadFrom(b)
                return n, peer, err
diff --git a/vendor/golang.org/x/net/icmp/helper.go b/vendor/golang.org/x/net/icmp/helper.go
deleted file mode 100644 (file)
index 6c4e633..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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 icmp
-
-import (
-       "encoding/binary"
-       "unsafe"
-)
-
-var (
-       // See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
-       freebsdVersion uint32
-
-       nativeEndian binary.ByteOrder
-)
-
-func init() {
-       i := uint32(1)
-       b := (*[4]byte)(unsafe.Pointer(&i))
-       if b[0] == 1 {
-               nativeEndian = binary.LittleEndian
-       } else {
-               nativeEndian = binary.BigEndian
-       }
-}
index 729ddc97c00b75c2933acaa61f4c514f274eae6f..ffc66ed4d80d8bc7b0d044d998dcc3fee1ee84b4 100644 (file)
@@ -9,9 +9,14 @@ import (
        "net"
        "runtime"
 
+       "golang.org/x/net/internal/socket"
        "golang.org/x/net/ipv4"
 )
 
+// freebsdVersion is set in sys_freebsd.go.
+// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
+var freebsdVersion uint32
+
 // ParseIPv4Header parses b as an IPv4 header of ICMP error message
 // invoking packet, which is contained in ICMP error message.
 func ParseIPv4Header(b []byte) (*ipv4.Header, error) {
@@ -36,12 +41,12 @@ func ParseIPv4Header(b []byte) (*ipv4.Header, error) {
        }
        switch runtime.GOOS {
        case "darwin":
-               h.TotalLen = int(nativeEndian.Uint16(b[2:4]))
+               h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
        case "freebsd":
                if freebsdVersion >= 1000000 {
                        h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
                } else {
-                       h.TotalLen = int(nativeEndian.Uint16(b[2:4]))
+                       h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
                }
        default:
                h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
index 58eaa77d025b7649102216a577fb0939c1777a54..2e8cfeb131c15975a98d06d1cc061c8e59e8d0b7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
index b9f260796e9ee6410afef476acbccea076eb6f59..7fac4f9652415b705203cc78fda82bda01e7b472 100644 (file)
@@ -65,22 +65,24 @@ func ListenPacket(network, address string) (*PacketConn, error) {
                if err != nil {
                        return nil, os.NewSyscallError("socket", err)
                }
-               defer syscall.Close(s)
                if runtime.GOOS == "darwin" && family == syscall.AF_INET {
                        if err := syscall.SetsockoptInt(s, iana.ProtocolIP, sysIP_STRIPHDR, 1); err != nil {
+                               syscall.Close(s)
                                return nil, os.NewSyscallError("setsockopt", err)
                        }
                }
                sa, err := sockaddr(family, address)
                if err != nil {
+                       syscall.Close(s)
                        return nil, err
                }
                if err := syscall.Bind(s, sa); err != nil {
+                       syscall.Close(s)
                        return nil, os.NewSyscallError("bind", err)
                }
                f := os.NewFile(uintptr(s), "datagram-oriented icmp")
-               defer f.Close()
                c, cerr = net.FilePacketConn(f)
+               f.Close()
        default:
                c, cerr = net.ListenPacket(network, address)
        }
index 42d6df2c13df0b468333d88e19eba0a4f063b6d0..81140b0df6c1bdaba3da36248b756f1c881f136d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
@@ -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")
index 2121a17be260e29abb8e4cf54dd825a560531718..2463730ae839c860f138473fbe6ee65bececcc99 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
index 3438a27c8d82c207c064da9dcace28b1f6a56985..c9df24d95fcf6229c1207ff2c71797bf9e72e6c6 100644 (file)
@@ -4,7 +4,7 @@
 // Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
 package iana // import "golang.org/x/net/internal/iana"
 
-// Differentiated Services Field Codepoints (DSCP), Updated: 2013-06-25
+// Differentiated Services Field Codepoints (DSCP), Updated: 2017-05-12
 const (
        DiffServCS0        = 0x0  // CS0
        DiffServCS1        = 0x20 // CS1
@@ -26,7 +26,7 @@ const (
        DiffServAF41       = 0x88 // AF41
        DiffServAF42       = 0x90 // AF42
        DiffServAF43       = 0x98 // AF43
-       DiffServEFPHB      = 0xb8 // EF PHB
+       DiffServEF         = 0xb8 // EF
        DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT
 )
 
@@ -38,7 +38,7 @@ const (
        CongestionExperienced = 0x3 // CE (Congestion Experienced)
 )
 
-// Protocol Numbers, Updated: 2015-10-06
+// Protocol Numbers, Updated: 2016-06-22
 const (
        ProtocolIP             = 0   // IPv4 encapsulation, pseudo protocol number
        ProtocolHOPOPT         = 0   // IPv6 Hop-by-Hop Option
index 2d8c07ca1bc3cfe48f41c1cc4c777897df4138df..86c78b3bb7dccf513630e23c5573e96d3479f8be 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
index 8cadfd7f3ffaba7f215f90c9027f6fddb1bbf6e3..a2b02ca95b9747cba028d6c53bae808c7b079242 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
@@ -8,6 +8,9 @@ import (
        "fmt"
        "net"
        "sync"
+
+       "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
 type rawOpt struct {
@@ -51,6 +54,77 @@ func (cm *ControlMessage) String() string {
        return fmt.Sprintf("ttl=%d src=%v dst=%v ifindex=%d", cm.TTL, cm.Src, cm.Dst, cm.IfIndex)
 }
 
+// Marshal returns the binary encoding of cm.
+func (cm *ControlMessage) Marshal() []byte {
+       if cm == nil {
+               return nil
+       }
+       var m socket.ControlMessage
+       if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To4() != nil || cm.IfIndex > 0) {
+               m = socket.NewControlMessage([]int{ctlOpts[ctlPacketInfo].length})
+       }
+       if len(m) > 0 {
+               ctlOpts[ctlPacketInfo].marshal(m, cm)
+       }
+       return m
+}
+
+// Parse parses b as a control message and stores the result in cm.
+func (cm *ControlMessage) Parse(b []byte) error {
+       ms, err := socket.ControlMessage(b).Parse()
+       if err != nil {
+               return err
+       }
+       for _, m := range ms {
+               lvl, typ, l, err := m.ParseHeader()
+               if err != nil {
+                       return err
+               }
+               if lvl != iana.ProtocolIP {
+                       continue
+               }
+               switch {
+               case typ == ctlOpts[ctlTTL].name && l >= ctlOpts[ctlTTL].length:
+                       ctlOpts[ctlTTL].parse(cm, m.Data(l))
+               case typ == ctlOpts[ctlDst].name && l >= ctlOpts[ctlDst].length:
+                       ctlOpts[ctlDst].parse(cm, m.Data(l))
+               case typ == ctlOpts[ctlInterface].name && l >= ctlOpts[ctlInterface].length:
+                       ctlOpts[ctlInterface].parse(cm, m.Data(l))
+               case typ == ctlOpts[ctlPacketInfo].name && l >= ctlOpts[ctlPacketInfo].length:
+                       ctlOpts[ctlPacketInfo].parse(cm, m.Data(l))
+               }
+       }
+       return nil
+}
+
+// NewControlMessage returns a new control message.
+//
+// The returned message is large enough for options specified by cf.
+func NewControlMessage(cf ControlFlags) []byte {
+       opt := rawOpt{cflags: cf}
+       var l int
+       if opt.isset(FlagTTL) && ctlOpts[ctlTTL].name > 0 {
+               l += socket.ControlMessageSpace(ctlOpts[ctlTTL].length)
+       }
+       if ctlOpts[ctlPacketInfo].name > 0 {
+               if opt.isset(FlagSrc | FlagDst | FlagInterface) {
+                       l += socket.ControlMessageSpace(ctlOpts[ctlPacketInfo].length)
+               }
+       } else {
+               if opt.isset(FlagDst) && ctlOpts[ctlDst].name > 0 {
+                       l += socket.ControlMessageSpace(ctlOpts[ctlDst].length)
+               }
+               if opt.isset(FlagInterface) && ctlOpts[ctlInterface].name > 0 {
+                       l += socket.ControlMessageSpace(ctlOpts[ctlInterface].length)
+               }
+       }
+       var b []byte
+       if l > 0 {
+               b = make([]byte, l)
+       }
+       return b
+}
+
 // Ancillary data socket options
 const (
        ctlTTL        = iota // header field
index 33d8bc8b3817c09b31aaeedbeacd11b2a3593db2..77e7ad5bed76bec1b5f3d3d0fa75d6e5db04821a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
@@ -12,26 +12,26 @@ import (
        "unsafe"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
 func marshalDst(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIP
-       m.Type = sysIP_RECVDSTADDR
-       m.SetLen(syscall.CmsgLen(net.IPv4len))
-       return b[syscall.CmsgSpace(net.IPv4len):]
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIP, sysIP_RECVDSTADDR, net.IPv4len)
+       return m.Next(net.IPv4len)
 }
 
 func parseDst(cm *ControlMessage, b []byte) {
-       cm.Dst = b[:net.IPv4len]
+       if len(cm.Dst) < net.IPv4len {
+               cm.Dst = make(net.IP, net.IPv4len)
+       }
+       copy(cm.Dst, b[:net.IPv4len])
 }
 
 func marshalInterface(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIP
-       m.Type = sysIP_RECVIF
-       m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
-       return b[syscall.CmsgSpace(syscall.SizeofSockaddrDatalink):]
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIP, sysIP_RECVIF, syscall.SizeofSockaddrDatalink)
+       return m.Next(syscall.SizeofSockaddrDatalink)
 }
 
 func parseInterface(cm *ControlMessage, b []byte) {
index 444782f39799dad5cd528d6907c2ff7bdeb1d9ef..425338f35bf1b71442e22c6530980f84dfc84323 100644 (file)
@@ -2,24 +2,23 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin linux
+// +build darwin linux solaris
 
 package ipv4
 
 import (
-       "syscall"
+       "net"
        "unsafe"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
 func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIP
-       m.Type = sysIP_PKTINFO
-       m.SetLen(syscall.CmsgLen(sysSizeofInetPktinfo))
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIP, sysIP_PKTINFO, sizeofInetPktinfo)
        if cm != nil {
-               pi := (*sysInetPktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
+               pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))
                if ip := cm.Src.To4(); ip != nil {
                        copy(pi.Spec_dst[:], ip)
                }
@@ -27,11 +26,14 @@ func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
                        pi.setIfindex(cm.IfIndex)
                }
        }
-       return b[syscall.CmsgSpace(sysSizeofInetPktinfo):]
+       return m.Next(sizeofInetPktinfo)
 }
 
 func parsePacketInfo(cm *ControlMessage, b []byte) {
-       pi := (*sysInetPktinfo)(unsafe.Pointer(&b[0]))
+       pi := (*inetPktinfo)(unsafe.Pointer(&b[0]))
        cm.IfIndex = int(pi.Ifindex)
-       cm.Dst = pi.Addr[:]
+       if len(cm.Dst) < net.IPv4len {
+               cm.Dst = make(net.IP, net.IPv4len)
+       }
+       copy(cm.Dst, pi.Addr[:])
 }
index 4d8507194c3ce3d3b9610a6fa72dc0aaf69e81a2..5a2f7d8d3c9b7ed84af3d7405ba1be8be0524040 100644 (file)
@@ -1,23 +1,13 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
-// +build nacl plan9 solaris
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv4
 
-func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
-       return errOpNoSupport
-}
-
-func newControlMessage(opt *rawOpt) []byte {
-       return nil
-}
+import "golang.org/x/net/internal/socket"
 
-func parseControlMessage(b []byte) (*ControlMessage, error) {
-       return nil, errOpNoSupport
-}
-
-func marshalControlMessage(cm *ControlMessage) []byte {
-       return nil
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+       return errOpNoSupport
 }
index 3000c52e40892711e81e99a43cce2c732068d8f2..e1ae8167b3a4bad4d9bb1feeb4a92ecd0ed341c6 100644 (file)
@@ -1,24 +1,23 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv4
 
 import (
-       "os"
-       "syscall"
        "unsafe"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
-func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
        opt.Lock()
        defer opt.Unlock()
-       if cf&FlagTTL != 0 && sockOpts[ssoReceiveTTL].name > 0 {
-               if err := setInt(fd, &sockOpts[ssoReceiveTTL], boolint(on)); err != nil {
+       if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
+               if err := so.SetInt(c, boolint(on)); err != nil {
                        return err
                }
                if on {
@@ -27,9 +26,9 @@ func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
                        opt.clear(FlagTTL)
                }
        }
-       if sockOpts[ssoPacketInfo].name > 0 {
+       if so, ok := sockOpts[ssoPacketInfo]; ok {
                if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
-                       if err := setInt(fd, &sockOpts[ssoPacketInfo], boolint(on)); err != nil {
+                       if err := so.SetInt(c, boolint(on)); err != nil {
                                return err
                        }
                        if on {
@@ -39,8 +38,8 @@ func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
                        }
                }
        } else {
-               if cf&FlagDst != 0 && sockOpts[ssoReceiveDst].name > 0 {
-                       if err := setInt(fd, &sockOpts[ssoReceiveDst], boolint(on)); err != nil {
+               if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
+                       if err := so.SetInt(c, boolint(on)); err != nil {
                                return err
                        }
                        if on {
@@ -49,8 +48,8 @@ func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
                                opt.clear(FlagDst)
                        }
                }
-               if cf&FlagInterface != 0 && sockOpts[ssoReceiveInterface].name > 0 {
-                       if err := setInt(fd, &sockOpts[ssoReceiveInterface], boolint(on)); err != nil {
+               if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
+                       if err := so.SetInt(c, boolint(on)); err != nil {
                                return err
                        }
                        if on {
@@ -63,100 +62,10 @@ func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
        return nil
 }
 
-func newControlMessage(opt *rawOpt) (oob []byte) {
-       opt.RLock()
-       var l int
-       if opt.isset(FlagTTL) && ctlOpts[ctlTTL].name > 0 {
-               l += syscall.CmsgSpace(ctlOpts[ctlTTL].length)
-       }
-       if ctlOpts[ctlPacketInfo].name > 0 {
-               if opt.isset(FlagSrc | FlagDst | FlagInterface) {
-                       l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
-               }
-       } else {
-               if opt.isset(FlagDst) && ctlOpts[ctlDst].name > 0 {
-                       l += syscall.CmsgSpace(ctlOpts[ctlDst].length)
-               }
-               if opt.isset(FlagInterface) && ctlOpts[ctlInterface].name > 0 {
-                       l += syscall.CmsgSpace(ctlOpts[ctlInterface].length)
-               }
-       }
-       if l > 0 {
-               oob = make([]byte, l)
-               b := oob
-               if opt.isset(FlagTTL) && ctlOpts[ctlTTL].name > 0 {
-                       b = ctlOpts[ctlTTL].marshal(b, nil)
-               }
-               if ctlOpts[ctlPacketInfo].name > 0 {
-                       if opt.isset(FlagSrc | FlagDst | FlagInterface) {
-                               b = ctlOpts[ctlPacketInfo].marshal(b, nil)
-                       }
-               } else {
-                       if opt.isset(FlagDst) && ctlOpts[ctlDst].name > 0 {
-                               b = ctlOpts[ctlDst].marshal(b, nil)
-                       }
-                       if opt.isset(FlagInterface) && ctlOpts[ctlInterface].name > 0 {
-                               b = ctlOpts[ctlInterface].marshal(b, nil)
-                       }
-               }
-       }
-       opt.RUnlock()
-       return
-}
-
-func parseControlMessage(b []byte) (*ControlMessage, error) {
-       if len(b) == 0 {
-               return nil, nil
-       }
-       cmsgs, err := syscall.ParseSocketControlMessage(b)
-       if err != nil {
-               return nil, os.NewSyscallError("parse socket control message", err)
-       }
-       cm := &ControlMessage{}
-       for _, m := range cmsgs {
-               if m.Header.Level != iana.ProtocolIP {
-                       continue
-               }
-               switch int(m.Header.Type) {
-               case ctlOpts[ctlTTL].name:
-                       ctlOpts[ctlTTL].parse(cm, m.Data[:])
-               case ctlOpts[ctlDst].name:
-                       ctlOpts[ctlDst].parse(cm, m.Data[:])
-               case ctlOpts[ctlInterface].name:
-                       ctlOpts[ctlInterface].parse(cm, m.Data[:])
-               case ctlOpts[ctlPacketInfo].name:
-                       ctlOpts[ctlPacketInfo].parse(cm, m.Data[:])
-               }
-       }
-       return cm, nil
-}
-
-func marshalControlMessage(cm *ControlMessage) (oob []byte) {
-       if cm == nil {
-               return nil
-       }
-       var l int
-       pktinfo := false
-       if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To4() != nil || cm.IfIndex > 0) {
-               pktinfo = true
-               l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
-       }
-       if l > 0 {
-               oob = make([]byte, l)
-               b := oob
-               if pktinfo {
-                       b = ctlOpts[ctlPacketInfo].marshal(b, cm)
-               }
-       }
-       return
-}
-
 func marshalTTL(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIP
-       m.Type = sysIP_RECVTTL
-       m.SetLen(syscall.CmsgLen(1))
-       return b[syscall.CmsgSpace(1):]
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIP, sysIP_RECVTTL, 1)
+       return m.Next(1)
 }
 
 func parseTTL(cm *ControlMessage, b []byte) {
index 800f63779526afa0caa948da350c731862a964aa..ce55c66447d07bab43ce407a5a7363d04601c072 100644 (file)
@@ -1,27 +1,16 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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
 
-import "syscall"
+import (
+       "syscall"
 
-func setControlMessage(fd syscall.Handle, opt *rawOpt, cf ControlFlags, on bool) error {
-       // TODO(mikio): implement this
-       return syscall.EWINDOWS
-}
-
-func newControlMessage(opt *rawOpt) []byte {
-       // TODO(mikio): implement this
-       return nil
-}
+       "golang.org/x/net/internal/socket"
+)
 
-func parseControlMessage(b []byte) (*ControlMessage, error) {
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
        // TODO(mikio): implement this
-       return nil, syscall.EWINDOWS
-}
-
-func marshalControlMessage(cm *ControlMessage) []byte {
-       // TODO(mikio): implement this
-       return nil
+       return syscall.EWINDOWS
 }
index 731d56a711d9bd614463cc684707c9f17f98734c..c8f2e05b81a0007ab6b31e156925eb463c4ff3ef 100644 (file)
@@ -49,29 +49,29 @@ const (
        sysMCAST_BLOCK_SOURCE        = C.MCAST_BLOCK_SOURCE
        sysMCAST_UNBLOCK_SOURCE      = C.MCAST_UNBLOCK_SOURCE
 
-       sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
-       sysSizeofSockaddrInet    = C.sizeof_struct_sockaddr_in
-       sysSizeofInetPktinfo     = C.sizeof_struct_in_pktinfo
-
-       sysSizeofIPMreq         = C.sizeof_struct_ip_mreq
-       sysSizeofIPMreqn        = C.sizeof_struct_ip_mreqn
-       sysSizeofIPMreqSource   = C.sizeof_struct_ip_mreq_source
-       sysSizeofGroupReq       = C.sizeof_struct_group_req
-       sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
+       sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
+       sizeofSockaddrInet    = C.sizeof_struct_sockaddr_in
+       sizeofInetPktinfo     = C.sizeof_struct_in_pktinfo
+
+       sizeofIPMreq         = C.sizeof_struct_ip_mreq
+       sizeofIPMreqn        = C.sizeof_struct_ip_mreqn
+       sizeofIPMreqSource   = C.sizeof_struct_ip_mreq_source
+       sizeofGroupReq       = C.sizeof_struct_group_req
+       sizeofGroupSourceReq = C.sizeof_struct_group_source_req
 )
 
-type sysSockaddrStorage C.struct_sockaddr_storage
+type sockaddrStorage C.struct_sockaddr_storage
 
-type sysSockaddrInet C.struct_sockaddr_in
+type sockaddrInet C.struct_sockaddr_in
 
-type sysInetPktinfo C.struct_in_pktinfo
+type inetPktinfo C.struct_in_pktinfo
 
-type sysIPMreq C.struct_ip_mreq
+type ipMreq C.struct_ip_mreq
 
-type sysIPMreqn C.struct_ip_mreqn
+type ipMreqn C.struct_ip_mreqn
 
-type sysIPMreqSource C.struct_ip_mreq_source
+type ipMreqSource C.struct_ip_mreq_source
 
-type sysGroupReq C.struct_group_req
+type groupReq C.struct_group_req
 
-type sysGroupSourceReq C.struct_group_source_req
+type groupSourceReq C.struct_group_source_req
index 08e3b855d5e21e6cae8ce7a62a144d589629dff6..f30544ea24754fafee635c12cde08fd1cb1daed0 100644 (file)
@@ -32,7 +32,7 @@ const (
        sysIP_ADD_MEMBERSHIP  = C.IP_ADD_MEMBERSHIP
        sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP
 
-       sysSizeofIPMreq = C.sizeof_struct_ip_mreq
+       sizeofIPMreq = C.sizeof_struct_ip_mreq
 )
 
-type sysIPMreq C.struct_ip_mreq
+type ipMreq C.struct_ip_mreq
index f12ca327bf627bc01e2ae9b340d465b16570b972..4dd57d86537482d09e6cb73a3ec2b77182183710 100644 (file)
@@ -50,26 +50,26 @@ const (
        sysMCAST_BLOCK_SOURCE        = C.MCAST_BLOCK_SOURCE
        sysMCAST_UNBLOCK_SOURCE      = C.MCAST_UNBLOCK_SOURCE
 
-       sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
-       sysSizeofSockaddrInet    = C.sizeof_struct_sockaddr_in
-
-       sysSizeofIPMreq         = C.sizeof_struct_ip_mreq
-       sysSizeofIPMreqn        = C.sizeof_struct_ip_mreqn
-       sysSizeofIPMreqSource   = C.sizeof_struct_ip_mreq_source
-       sysSizeofGroupReq       = C.sizeof_struct_group_req
-       sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
+       sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
+       sizeofSockaddrInet    = C.sizeof_struct_sockaddr_in
+
+       sizeofIPMreq         = C.sizeof_struct_ip_mreq
+       sizeofIPMreqn        = C.sizeof_struct_ip_mreqn
+       sizeofIPMreqSource   = C.sizeof_struct_ip_mreq_source
+       sizeofGroupReq       = C.sizeof_struct_group_req
+       sizeofGroupSourceReq = C.sizeof_struct_group_source_req
 )
 
-type sysSockaddrStorage C.struct_sockaddr_storage
+type sockaddrStorage C.struct_sockaddr_storage
 
-type sysSockaddrInet C.struct_sockaddr_in
+type sockaddrInet C.struct_sockaddr_in
 
-type sysIPMreq C.struct_ip_mreq
+type ipMreq C.struct_ip_mreq
 
-type sysIPMreqn C.struct_ip_mreqn
+type ipMreqn C.struct_ip_mreqn
 
-type sysIPMreqSource C.struct_ip_mreq_source
+type ipMreqSource C.struct_ip_mreq_source
 
-type sysGroupReq C.struct_group_req
+type groupReq C.struct_group_req
 
-type sysGroupSourceReq C.struct_group_source_req
+type groupSourceReq C.struct_group_source_req
index fdba148a2f2319f5cd0f293f50da02479eb4de51..beb11071ad023953428d1d1b3a072e365bb0712f 100644 (file)
@@ -14,6 +14,8 @@ package ipv4
 #include <linux/errqueue.h>
 #include <linux/icmp.h>
 #include <linux/in.h>
+#include <linux/filter.h>
+#include <sys/socket.h>
 */
 import "C"
 
@@ -76,36 +78,45 @@ const (
        sysSO_EE_ORIGIN_TXSTATUS     = C.SO_EE_ORIGIN_TXSTATUS
        sysSO_EE_ORIGIN_TIMESTAMPING = C.SO_EE_ORIGIN_TIMESTAMPING
 
-       sysSizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage
-       sysSizeofSockaddrInet          = C.sizeof_struct_sockaddr_in
-       sysSizeofInetPktinfo           = C.sizeof_struct_in_pktinfo
-       sysSizeofSockExtendedErr       = C.sizeof_struct_sock_extended_err
+       sysSOL_SOCKET       = C.SOL_SOCKET
+       sysSO_ATTACH_FILTER = C.SO_ATTACH_FILTER
 
-       sysSizeofIPMreq         = C.sizeof_struct_ip_mreq
-       sysSizeofIPMreqn        = C.sizeof_struct_ip_mreqn
-       sysSizeofIPMreqSource   = C.sizeof_struct_ip_mreq_source
-       sysSizeofGroupReq       = C.sizeof_struct_group_req
-       sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
+       sizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage
+       sizeofSockaddrInet          = C.sizeof_struct_sockaddr_in
+       sizeofInetPktinfo           = C.sizeof_struct_in_pktinfo
+       sizeofSockExtendedErr       = C.sizeof_struct_sock_extended_err
 
-       sysSizeofICMPFilter = C.sizeof_struct_icmp_filter
+       sizeofIPMreq         = C.sizeof_struct_ip_mreq
+       sizeofIPMreqn        = C.sizeof_struct_ip_mreqn
+       sizeofIPMreqSource   = C.sizeof_struct_ip_mreq_source
+       sizeofGroupReq       = C.sizeof_struct_group_req
+       sizeofGroupSourceReq = C.sizeof_struct_group_source_req
+
+       sizeofICMPFilter = C.sizeof_struct_icmp_filter
+
+       sizeofSockFprog = C.sizeof_struct_sock_fprog
 )
 
-type sysKernelSockaddrStorage C.struct___kernel_sockaddr_storage
+type kernelSockaddrStorage C.struct___kernel_sockaddr_storage
+
+type sockaddrInet C.struct_sockaddr_in
+
+type inetPktinfo C.struct_in_pktinfo
 
-type sysSockaddrInet C.struct_sockaddr_in
+type sockExtendedErr C.struct_sock_extended_err
 
-type sysInetPktinfo C.struct_in_pktinfo
+type ipMreq C.struct_ip_mreq
 
-type sysSockExtendedErr C.struct_sock_extended_err
+type ipMreqn C.struct_ip_mreqn
 
-type sysIPMreq C.struct_ip_mreq
+type ipMreqSource C.struct_ip_mreq_source
 
-type sysIPMreqn C.struct_ip_mreqn
+type groupReq C.struct_group_req
 
-type sysIPMreqSource C.struct_ip_mreq_source
+type groupSourceReq C.struct_group_source_req
 
-type sysGroupReq C.struct_group_req
+type icmpFilter C.struct_icmp_filter
 
-type sysGroupSourceReq C.struct_group_source_req
+type sockFProg C.struct_sock_fprog
 
-type sysICMPFilter C.struct_icmp_filter
+type sockFilter C.struct_sock_filter
index 8642354f490b701a373b88305d944b65403be6f8..8f8af1b899ebc2ec8ebf8f2a203ba094a3fe8b20 100644 (file)
@@ -31,7 +31,7 @@ const (
        sysIP_ADD_MEMBERSHIP  = C.IP_ADD_MEMBERSHIP
        sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP
 
-       sysSizeofIPMreq = C.sizeof_struct_ip_mreq
+       sizeofIPMreq = C.sizeof_struct_ip_mreq
 )
 
-type sysIPMreq C.struct_ip_mreq
+type ipMreq C.struct_ip_mreq
index 8642354f490b701a373b88305d944b65403be6f8..8f8af1b899ebc2ec8ebf8f2a203ba094a3fe8b20 100644 (file)
@@ -31,7 +31,7 @@ const (
        sysIP_ADD_MEMBERSHIP  = C.IP_ADD_MEMBERSHIP
        sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP
 
-       sysSizeofIPMreq = C.sizeof_struct_ip_mreq
+       sizeofIPMreq = C.sizeof_struct_ip_mreq
 )
 
-type sysIPMreq C.struct_ip_mreq
+type ipMreq C.struct_ip_mreq
index bb74afa49bd52b4ef1e3b8267f21c77ec788c02b..aeb33e9c8f9a26d94619da6c76dfaa7fc3dd5882 100644 (file)
@@ -9,30 +9,24 @@
 package ipv4
 
 /*
+#include <sys/socket.h>
+
 #include <netinet/in.h>
 */
 import "C"
 
 const (
-       sysIP_OPTIONS       = C.IP_OPTIONS
-       sysIP_HDRINCL       = C.IP_HDRINCL
-       sysIP_TOS           = C.IP_TOS
-       sysIP_TTL           = C.IP_TTL
-       sysIP_RECVOPTS      = C.IP_RECVOPTS
-       sysIP_RECVRETOPTS   = C.IP_RECVRETOPTS
-       sysIP_RECVDSTADDR   = C.IP_RECVDSTADDR
-       sysIP_RETOPTS       = C.IP_RETOPTS
-       sysIP_RECVIF        = C.IP_RECVIF
-       sysIP_RECVSLLA      = C.IP_RECVSLLA
-       sysIP_RECVTTL       = C.IP_RECVTTL
-       sysIP_NEXTHOP       = C.IP_NEXTHOP
-       sysIP_PKTINFO       = C.IP_PKTINFO
-       sysIP_RECVPKTINFO   = C.IP_RECVPKTINFO
-       sysIP_DONTFRAG      = C.IP_DONTFRAG
-       sysIP_BOUND_IF      = C.IP_BOUND_IF
-       sysIP_UNSPEC_SRC    = C.IP_UNSPEC_SRC
-       sysIP_BROADCAST_TTL = C.IP_BROADCAST_TTL
-       sysIP_DHCPINIT_IF   = C.IP_DHCPINIT_IF
+       sysIP_OPTIONS     = C.IP_OPTIONS
+       sysIP_HDRINCL     = C.IP_HDRINCL
+       sysIP_TOS         = C.IP_TOS
+       sysIP_TTL         = C.IP_TTL
+       sysIP_RECVOPTS    = C.IP_RECVOPTS
+       sysIP_RECVRETOPTS = C.IP_RECVRETOPTS
+       sysIP_RECVDSTADDR = C.IP_RECVDSTADDR
+       sysIP_RETOPTS     = C.IP_RETOPTS
+       sysIP_RECVIF      = C.IP_RECVIF
+       sysIP_RECVSLLA    = C.IP_RECVSLLA
+       sysIP_RECVTTL     = C.IP_RECVTTL
 
        sysIP_MULTICAST_IF           = C.IP_MULTICAST_IF
        sysIP_MULTICAST_TTL          = C.IP_MULTICAST_TTL
@@ -43,15 +37,48 @@ const (
        sysIP_UNBLOCK_SOURCE         = C.IP_UNBLOCK_SOURCE
        sysIP_ADD_SOURCE_MEMBERSHIP  = C.IP_ADD_SOURCE_MEMBERSHIP
        sysIP_DROP_SOURCE_MEMBERSHIP = C.IP_DROP_SOURCE_MEMBERSHIP
+       sysIP_NEXTHOP                = C.IP_NEXTHOP
 
-       sysSizeofInetPktinfo = C.sizeof_struct_in_pktinfo
+       sysIP_PKTINFO     = C.IP_PKTINFO
+       sysIP_RECVPKTINFO = C.IP_RECVPKTINFO
+       sysIP_DONTFRAG    = C.IP_DONTFRAG
 
-       sysSizeofIPMreq       = C.sizeof_struct_ip_mreq
-       sysSizeofIPMreqSource = C.sizeof_struct_ip_mreq_source
+       sysIP_BOUND_IF      = C.IP_BOUND_IF
+       sysIP_UNSPEC_SRC    = C.IP_UNSPEC_SRC
+       sysIP_BROADCAST_TTL = C.IP_BROADCAST_TTL
+       sysIP_DHCPINIT_IF   = C.IP_DHCPINIT_IF
+
+       sysIP_REUSEADDR = C.IP_REUSEADDR
+       sysIP_DONTROUTE = C.IP_DONTROUTE
+       sysIP_BROADCAST = C.IP_BROADCAST
+
+       sysMCAST_JOIN_GROUP         = C.MCAST_JOIN_GROUP
+       sysMCAST_LEAVE_GROUP        = C.MCAST_LEAVE_GROUP
+       sysMCAST_BLOCK_SOURCE       = C.MCAST_BLOCK_SOURCE
+       sysMCAST_UNBLOCK_SOURCE     = C.MCAST_UNBLOCK_SOURCE
+       sysMCAST_JOIN_SOURCE_GROUP  = C.MCAST_JOIN_SOURCE_GROUP
+       sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP
+
+       sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
+       sizeofSockaddrInet    = C.sizeof_struct_sockaddr_in
+       sizeofInetPktinfo     = C.sizeof_struct_in_pktinfo
+
+       sizeofIPMreq         = C.sizeof_struct_ip_mreq
+       sizeofIPMreqSource   = C.sizeof_struct_ip_mreq_source
+       sizeofGroupReq       = C.sizeof_struct_group_req
+       sizeofGroupSourceReq = C.sizeof_struct_group_source_req
 )
 
-type sysInetPktinfo C.struct_in_pktinfo
+type sockaddrStorage C.struct_sockaddr_storage
+
+type sockaddrInet C.struct_sockaddr_in
+
+type inetPktinfo C.struct_in_pktinfo
+
+type ipMreq C.struct_ip_mreq
+
+type ipMreqSource C.struct_ip_mreq_source
 
-type sysIPMreq C.struct_ip_mreq
+type groupReq C.struct_group_req
 
-type sysIPMreqSource C.struct_ip_mreq_source
+type groupSourceReq C.struct_group_source_req
diff --git a/vendor/golang.org/x/net/ipv4/dgramopt_posix.go b/vendor/golang.org/x/net/ipv4/dgramopt_posix.go
deleted file mode 100644 (file)
index 103c4f6..0000000
+++ /dev/null
@@ -1,251 +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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
-
-package ipv4
-
-import (
-       "net"
-       "syscall"
-)
-
-// MulticastTTL returns the time-to-live field value for outgoing
-// multicast packets.
-func (c *dgramOpt) MulticastTTL() (int, error) {
-       if !c.ok() {
-               return 0, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return 0, err
-       }
-       return getInt(fd, &sockOpts[ssoMulticastTTL])
-}
-
-// SetMulticastTTL sets the time-to-live field value for future
-// outgoing multicast packets.
-func (c *dgramOpt) SetMulticastTTL(ttl int) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInt(fd, &sockOpts[ssoMulticastTTL], ttl)
-}
-
-// MulticastInterface returns the default interface for multicast
-// packet transmissions.
-func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
-       if !c.ok() {
-               return nil, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return nil, err
-       }
-       return getInterface(fd, &sockOpts[ssoMulticastInterface])
-}
-
-// SetMulticastInterface sets the default interface for future
-// multicast packet transmissions.
-func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInterface(fd, &sockOpts[ssoMulticastInterface], ifi)
-}
-
-// MulticastLoopback reports whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) MulticastLoopback() (bool, error) {
-       if !c.ok() {
-               return false, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return false, err
-       }
-       on, err := getInt(fd, &sockOpts[ssoMulticastLoopback])
-       if err != nil {
-               return false, err
-       }
-       return on == 1, nil
-}
-
-// SetMulticastLoopback sets whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) SetMulticastLoopback(on bool) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInt(fd, &sockOpts[ssoMulticastLoopback], boolint(on))
-}
-
-// JoinGroup joins the group address group on the interface ifi.
-// By default all sources that can cast data to group are accepted.
-// It's possible to mute and unmute data transmission from a specific
-// source by using ExcludeSourceSpecificGroup and
-// IncludeSourceSpecificGroup.
-// JoinGroup uses the system assigned multicast interface when ifi is
-// nil, although this is not recommended because the assignment
-// depends on platforms and sometimes it might require routing
-// configuration.
-func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP4(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       return setGroup(fd, &sockOpts[ssoJoinGroup], ifi, grp)
-}
-
-// LeaveGroup leaves the group address group on the interface ifi
-// regardless of whether the group is any-source group or
-// source-specific group.
-func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP4(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       return setGroup(fd, &sockOpts[ssoLeaveGroup], ifi, grp)
-}
-
-// JoinSourceSpecificGroup joins the source-specific group comprising
-// group and source on the interface ifi.
-// JoinSourceSpecificGroup uses the system assigned multicast
-// interface when ifi is nil, although this is not recommended because
-// the assignment depends on platforms and sometimes it might require
-// routing configuration.
-func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP4(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       src := netAddrToIP4(source)
-       if src == nil {
-               return errMissingAddress
-       }
-       return setSourceGroup(fd, &sockOpts[ssoJoinSourceGroup], ifi, grp, src)
-}
-
-// LeaveSourceSpecificGroup leaves the source-specific group on the
-// interface ifi.
-func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP4(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       src := netAddrToIP4(source)
-       if src == nil {
-               return errMissingAddress
-       }
-       return setSourceGroup(fd, &sockOpts[ssoLeaveSourceGroup], ifi, grp, src)
-}
-
-// ExcludeSourceSpecificGroup excludes the source-specific group from
-// the already joined any-source groups by JoinGroup on the interface
-// ifi.
-func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP4(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       src := netAddrToIP4(source)
-       if src == nil {
-               return errMissingAddress
-       }
-       return setSourceGroup(fd, &sockOpts[ssoBlockSourceGroup], ifi, grp, src)
-}
-
-// IncludeSourceSpecificGroup includes the excluded source-specific
-// group by ExcludeSourceSpecificGroup again on the interface ifi.
-func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP4(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       src := netAddrToIP4(source)
-       if src == nil {
-               return errMissingAddress
-       }
-       return setSourceGroup(fd, &sockOpts[ssoUnblockSourceGroup], ifi, grp, src)
-}
-
-// ICMPFilter returns an ICMP filter.
-// Currently only Linux supports this.
-func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
-       if !c.ok() {
-               return nil, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return nil, err
-       }
-       return getICMPFilter(fd, &sockOpts[ssoICMPFilter])
-}
-
-// SetICMPFilter deploys the ICMP filter.
-// Currently only Linux supports this.
-func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setICMPFilter(fd, &sockOpts[ssoICMPFilter], f)
-}
diff --git a/vendor/golang.org/x/net/ipv4/dgramopt_stub.go b/vendor/golang.org/x/net/ipv4/dgramopt_stub.go
deleted file mode 100644 (file)
index b74df69..0000000
+++ /dev/null
@@ -1,106 +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.
-
-// +build nacl plan9 solaris
-
-package ipv4
-
-import "net"
-
-// MulticastTTL returns the time-to-live field value for outgoing
-// multicast packets.
-func (c *dgramOpt) MulticastTTL() (int, error) {
-       return 0, errOpNoSupport
-}
-
-// SetMulticastTTL sets the time-to-live field value for future
-// outgoing multicast packets.
-func (c *dgramOpt) SetMulticastTTL(ttl int) error {
-       return errOpNoSupport
-}
-
-// MulticastInterface returns the default interface for multicast
-// packet transmissions.
-func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
-       return nil, errOpNoSupport
-}
-
-// SetMulticastInterface sets the default interface for future
-// multicast packet transmissions.
-func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
-       return errOpNoSupport
-}
-
-// MulticastLoopback reports whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) MulticastLoopback() (bool, error) {
-       return false, errOpNoSupport
-}
-
-// SetMulticastLoopback sets whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) SetMulticastLoopback(on bool) error {
-       return errOpNoSupport
-}
-
-// JoinGroup joins the group address group on the interface ifi.
-// By default all sources that can cast data to group are accepted.
-// It's possible to mute and unmute data transmission from a specific
-// source by using ExcludeSourceSpecificGroup and
-// IncludeSourceSpecificGroup.
-// JoinGroup uses the system assigned multicast interface when ifi is
-// nil, although this is not recommended because the assignment
-// depends on platforms and sometimes it might require routing
-// configuration.
-func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
-       return errOpNoSupport
-}
-
-// LeaveGroup leaves the group address group on the interface ifi
-// regardless of whether the group is any-source group or
-// source-specific group.
-func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
-       return errOpNoSupport
-}
-
-// JoinSourceSpecificGroup joins the source-specific group comprising
-// group and source on the interface ifi.
-// JoinSourceSpecificGroup uses the system assigned multicast
-// interface when ifi is nil, although this is not recommended because
-// the assignment depends on platforms and sometimes it might require
-// routing configuration.
-func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       return errOpNoSupport
-}
-
-// LeaveSourceSpecificGroup leaves the source-specific group on the
-// interface ifi.
-func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       return errOpNoSupport
-}
-
-// ExcludeSourceSpecificGroup excludes the source-specific group from
-// the already joined any-source groups by JoinGroup on the interface
-// ifi.
-func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       return errOpNoSupport
-}
-
-// IncludeSourceSpecificGroup includes the excluded source-specific
-// group by ExcludeSourceSpecificGroup again on the interface ifi.
-func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       return errOpNoSupport
-}
-
-// ICMPFilter returns an ICMP filter.
-// Currently only Linux supports this.
-func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
-       return nil, errOpNoSupport
-}
-
-// SetICMPFilter deploys the ICMP filter.
-// Currently only Linux supports this.
-func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
-       return errOpNoSupport
-}
index 9a79badfe2471e08ed7a5e8fc231dd604c1e360b..b43935a5aecb25b9e9fc6439e16e35eeea46b998 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
 //
 // The options for unicasting are available for net.TCPConn,
 // net.UDPConn and net.IPConn which are created as network connections
-// that use the IPv4 transport.  When a single TCP connection carrying
+// 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 {
@@ -56,7 +56,7 @@
 //
 // The options for multicasting are available for net.UDPConn and
 // net.IPconn which are created as network connections that use the
-// IPv4 transport.  A few network facilities must be prepared before
+// IPv4 transport. A few network facilities must be prepared before
 // you begin multicasting, at a minimum joining network interfaces and
 // multicast groups.
 //
@@ -80,7 +80,7 @@
 //     defer c.Close()
 //
 // Second, the application joins multicast groups, starts listening to
-// the groups on the specified network interfaces.  Note that the
+// the groups on the specified network interfaces. Note that the
 // service port for transport layer protocol does not matter with this
 // operation as joining groups affects only network and link layer
 // protocols, such as IPv4 and Ethernet.
 //     }
 //
 // The application might set per packet control message transmissions
-// between the protocol stack within the kernel.  When the application
+// 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 transmissons.
+// SetControlMessage of PacketConn is used to enable control message
+// transmissions.
 //
 //     if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil {
 //             // error handling
 // More multicasting
 //
 // An application that uses PacketConn or RawConn may join multiple
-// multicast groups.  For example, a UDP listener with port 1024 might
+// multicast groups. For example, a UDP listener with port 1024 might
 // join two different groups across over two different network
 // interfaces by using:
 //
 //     }
 //
 // It is possible for multiple UDP listeners that listen on the same
-// UDP port to join the same multicast group.  The net package will
+// UDP port to join the same multicast group. The net package will
 // provide a socket that listens to a wildcard address with reusable
 // UDP port when an appropriate multicast address prefix is passed to
 // the net.ListenPacket or net.ListenUDP.
 // 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.
index bc45bf054ca8955c5ac8e8765446af15501dced2..2ab8773630e5dc02ea9740baf09752e4e5e4e97f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
@@ -8,8 +8,15 @@ import (
        "net"
        "syscall"
        "time"
+
+       "golang.org/x/net/internal/socket"
 )
 
+// 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.
@@ -18,21 +25,22 @@ type Conn struct {
 }
 
 type genericOpt struct {
-       net.Conn
+       *socket.Conn
 }
 
 func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
 
 // NewConn returns a new Conn.
 func NewConn(c net.Conn) *Conn {
+       cc, _ := socket.NewConn(c)
        return &Conn{
-               genericOpt: genericOpt{Conn: c},
+               genericOpt: genericOpt{Conn: cc},
        }
 }
 
 // A PacketConn represents a packet network endpoint that uses the
-// IPv4 transport.  It is used to control several IP-level socket
-// options including multicasting.  It also provides datagram based
+// IPv4 transport. It is used to control several IP-level socket
+// options including multicasting. It also provides datagram based
 // network I/O methods specific to the IPv4 and higher layer protocols
 // such as UDP.
 type PacketConn struct {
@@ -42,21 +50,17 @@ type PacketConn struct {
 }
 
 type dgramOpt struct {
-       net.PacketConn
+       *socket.Conn
 }
 
-func (c *dgramOpt) ok() bool { return c != nil && c.PacketConn != nil }
+func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
 
 // SetControlMessage sets the per packet IP-level socket options.
 func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
        if !c.payloadHandler.ok() {
                return syscall.EINVAL
        }
-       fd, err := c.payloadHandler.sysfd()
-       if err != nil {
-               return err
-       }
-       return setControlMessage(fd, &c.payloadHandler.rawOpt, cf, on)
+       return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
 }
 
 // SetDeadline sets the read and write deadlines associated with the
@@ -97,22 +101,18 @@ func (c *PacketConn) Close() error {
 // NewPacketConn returns a new PacketConn using c as its underlying
 // transport.
 func NewPacketConn(c net.PacketConn) *PacketConn {
+       cc, _ := socket.NewConn(c.(net.Conn))
        p := &PacketConn{
-               genericOpt:     genericOpt{Conn: c.(net.Conn)},
-               dgramOpt:       dgramOpt{PacketConn: c},
-               payloadHandler: payloadHandler{PacketConn: c},
-       }
-       if _, ok := c.(*net.IPConn); ok && sockOpts[ssoStripHeader].name > 0 {
-               if fd, err := p.payloadHandler.sysfd(); err == nil {
-                       setInt(fd, &sockOpts[ssoStripHeader], boolint(true))
-               }
+               genericOpt:     genericOpt{Conn: cc},
+               dgramOpt:       dgramOpt{Conn: cc},
+               payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
        }
        return p
 }
 
 // A RawConn represents a packet network endpoint that uses the IPv4
-// transport.  It is used to control several IP-level socket options
-// including IPv4 header manipulation.  It also provides datagram
+// transport. It is used to control several IP-level socket options
+// including IPv4 header manipulation. It also provides datagram
 // based network I/O methods specific to the IPv4 and higher layer
 // protocols that handle IPv4 datagram directly such as OSPF, GRE.
 type RawConn struct {
@@ -126,11 +126,7 @@ func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error {
        if !c.packetHandler.ok() {
                return syscall.EINVAL
        }
-       fd, err := c.packetHandler.sysfd()
-       if err != nil {
-               return err
-       }
-       return setControlMessage(fd, &c.packetHandler.rawOpt, cf, on)
+       return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on)
 }
 
 // SetDeadline sets the read and write deadlines associated with the
@@ -139,7 +135,7 @@ func (c *RawConn) SetDeadline(t time.Time) error {
        if !c.packetHandler.ok() {
                return syscall.EINVAL
        }
-       return c.packetHandler.c.SetDeadline(t)
+       return c.packetHandler.IPConn.SetDeadline(t)
 }
 
 // SetReadDeadline sets the read deadline associated with the
@@ -148,7 +144,7 @@ func (c *RawConn) SetReadDeadline(t time.Time) error {
        if !c.packetHandler.ok() {
                return syscall.EINVAL
        }
-       return c.packetHandler.c.SetReadDeadline(t)
+       return c.packetHandler.IPConn.SetReadDeadline(t)
 }
 
 // SetWriteDeadline sets the write deadline associated with the
@@ -157,7 +153,7 @@ func (c *RawConn) SetWriteDeadline(t time.Time) error {
        if !c.packetHandler.ok() {
                return syscall.EINVAL
        }
-       return c.packetHandler.c.SetWriteDeadline(t)
+       return c.packetHandler.IPConn.SetWriteDeadline(t)
 }
 
 // Close closes the endpoint.
@@ -165,22 +161,26 @@ func (c *RawConn) Close() error {
        if !c.packetHandler.ok() {
                return syscall.EINVAL
        }
-       return c.packetHandler.c.Close()
+       return c.packetHandler.IPConn.Close()
 }
 
 // NewRawConn returns a new RawConn using c as its underlying
 // transport.
 func NewRawConn(c net.PacketConn) (*RawConn, error) {
-       r := &RawConn{
-               genericOpt:    genericOpt{Conn: c.(net.Conn)},
-               dgramOpt:      dgramOpt{PacketConn: c},
-               packetHandler: packetHandler{c: c.(*net.IPConn)},
-       }
-       fd, err := r.packetHandler.sysfd()
+       cc, err := socket.NewConn(c.(net.Conn))
        if err != nil {
                return nil, err
        }
-       if err := setInt(fd, &sockOpts[ssoHeaderPrepend], boolint(true)); err != nil {
+       r := &RawConn{
+               genericOpt:    genericOpt{Conn: cc},
+               dgramOpt:      dgramOpt{Conn: cc},
+               packetHandler: packetHandler{IPConn: c.(*net.IPConn), Conn: cc},
+       }
+       so, ok := sockOpts[ssoHeaderPrepend]
+       if !ok {
+               return nil, errOpNoSupport
+       }
+       if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil {
                return nil, err
        }
        return r, nil
index 4785212a7b4a98d97010c07a2c597fce3ec6ebf5..ffb44fe681fe4332bff2b0eb0e3f6205f605cb1c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -52,15 +52,6 @@ func genzsys() error {
        if err != nil {
                return err
        }
-       // The ipv4 pacakge still supports go1.2, and so we need to
-       // take care of additional platforms in go1.3 and above for
-       // working with go1.2.
-       switch {
-       case runtime.GOOS == "dragonfly" || runtime.GOOS == "solaris":
-               b = bytes.Replace(b, []byte("package ipv4\n"), []byte("// +build "+runtime.GOOS+"\n\npackage ipv4\n"), 1)
-       case runtime.GOOS == "linux" && (runtime.GOARCH == "arm64" || runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"):
-               b = bytes.Replace(b, []byte("package ipv4\n"), []byte("// +build "+runtime.GOOS+","+runtime.GOARCH+"\n\npackage ipv4\n"), 1)
-       }
        b, err = format.Source(b)
        if err != nil {
                return err
diff --git a/vendor/golang.org/x/net/ipv4/genericopt_posix.go b/vendor/golang.org/x/net/ipv4/genericopt_posix.go
deleted file mode 100644 (file)
index fefa0be..0000000
+++ /dev/null
@@ -1,59 +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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
-
-package ipv4
-
-import "syscall"
-
-// TOS returns the type-of-service field value for outgoing packets.
-func (c *genericOpt) TOS() (int, error) {
-       if !c.ok() {
-               return 0, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return 0, err
-       }
-       return getInt(fd, &sockOpts[ssoTOS])
-}
-
-// SetTOS sets the type-of-service field value for future outgoing
-// packets.
-func (c *genericOpt) SetTOS(tos int) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInt(fd, &sockOpts[ssoTOS], tos)
-}
-
-// TTL returns the time-to-live field value for outgoing packets.
-func (c *genericOpt) TTL() (int, error) {
-       if !c.ok() {
-               return 0, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return 0, err
-       }
-       return getInt(fd, &sockOpts[ssoTTL])
-}
-
-// SetTTL sets the time-to-live field value for future outgoing
-// packets.
-func (c *genericOpt) SetTTL(ttl int) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInt(fd, &sockOpts[ssoTTL], ttl)
-}
diff --git a/vendor/golang.org/x/net/ipv4/genericopt_stub.go b/vendor/golang.org/x/net/ipv4/genericopt_stub.go
deleted file mode 100644 (file)
index 1817bad..0000000
+++ /dev/null
@@ -1,29 +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.
-
-// +build nacl plan9 solaris
-
-package ipv4
-
-// TOS returns the type-of-service field value for outgoing packets.
-func (c *genericOpt) TOS() (int, error) {
-       return 0, errOpNoSupport
-}
-
-// SetTOS sets the type-of-service field value for future outgoing
-// packets.
-func (c *genericOpt) SetTOS(tos int) error {
-       return errOpNoSupport
-}
-
-// TTL returns the time-to-live field value for outgoing packets.
-func (c *genericOpt) TTL() (int, error) {
-       return 0, errOpNoSupport
-}
-
-// SetTTL sets the time-to-live field value for future outgoing
-// packets.
-func (c *genericOpt) SetTTL(ttl int) error {
-       return errOpNoSupport
-}
index 363d9c21a6683532275d8bf232293a33b24fa5ea..8bb0f0f4d4be55caa5233fe832a61801d3ed1aa1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
@@ -10,6 +10,8 @@ import (
        "net"
        "runtime"
        "syscall"
+
+       "golang.org/x/net/internal/socket"
 )
 
 const (
@@ -49,7 +51,7 @@ func (h *Header) String() string {
        return fmt.Sprintf("ver=%d hdrlen=%d tos=%#x totallen=%d id=%#x flags=%#x fragoff=%#x ttl=%d proto=%d cksum=%#x src=%v dst=%v", h.Version, h.Len, h.TOS, h.TotalLen, h.ID, h.Flags, h.FragOff, h.TTL, h.Protocol, h.Checksum, h.Src, h.Dst)
 }
 
-// Marshal returns the binary encoding of the IPv4 header h.
+// Marshal returns the binary encoding of h.
 func (h *Header) Marshal() ([]byte, error) {
        if h == nil {
                return nil, syscall.EINVAL
@@ -63,9 +65,17 @@ func (h *Header) Marshal() ([]byte, error) {
        b[1] = byte(h.TOS)
        flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13)
        switch runtime.GOOS {
-       case "darwin", "dragonfly", "freebsd", "netbsd":
-               nativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
-               nativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+       case "darwin", "dragonfly", "netbsd":
+               socket.NativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
+               socket.NativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+       case "freebsd":
+               if freebsdVersion < 1100000 {
+                       socket.NativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
+                       socket.NativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+               } else {
+                       binary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen))
+                       binary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+               }
        default:
                binary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen))
                binary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
@@ -88,45 +98,62 @@ func (h *Header) Marshal() ([]byte, error) {
        return b, nil
 }
 
-// ParseHeader parses b as an IPv4 header.
-func ParseHeader(b []byte) (*Header, error) {
-       if len(b) < HeaderLen {
-               return nil, errHeaderTooShort
+// Parse parses b as an IPv4 header and sotres the result in h.
+func (h *Header) Parse(b []byte) error {
+       if h == nil || len(b) < HeaderLen {
+               return errHeaderTooShort
        }
        hdrlen := int(b[0]&0x0f) << 2
        if hdrlen > len(b) {
-               return nil, errBufferTooShort
-       }
-       h := &Header{
-               Version:  int(b[0] >> 4),
-               Len:      hdrlen,
-               TOS:      int(b[1]),
-               ID:       int(binary.BigEndian.Uint16(b[4:6])),
-               TTL:      int(b[8]),
-               Protocol: int(b[9]),
-               Checksum: int(binary.BigEndian.Uint16(b[10:12])),
-               Src:      net.IPv4(b[12], b[13], b[14], b[15]),
-               Dst:      net.IPv4(b[16], b[17], b[18], b[19]),
+               return errBufferTooShort
        }
+       h.Version = int(b[0] >> 4)
+       h.Len = hdrlen
+       h.TOS = int(b[1])
+       h.ID = int(binary.BigEndian.Uint16(b[4:6]))
+       h.TTL = int(b[8])
+       h.Protocol = int(b[9])
+       h.Checksum = int(binary.BigEndian.Uint16(b[10:12]))
+       h.Src = net.IPv4(b[12], b[13], b[14], b[15])
+       h.Dst = net.IPv4(b[16], b[17], b[18], b[19])
        switch runtime.GOOS {
        case "darwin", "dragonfly", "netbsd":
-               h.TotalLen = int(nativeEndian.Uint16(b[2:4])) + hdrlen
-               h.FragOff = int(nativeEndian.Uint16(b[6:8]))
+               h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4])) + hdrlen
+               h.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))
        case "freebsd":
-               h.TotalLen = int(nativeEndian.Uint16(b[2:4]))
-               if freebsdVersion < 1000000 {
-                       h.TotalLen += hdrlen
+               if freebsdVersion < 1100000 {
+                       h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
+                       if freebsdVersion < 1000000 {
+                               h.TotalLen += hdrlen
+                       }
+                       h.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))
+               } else {
+                       h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
+                       h.FragOff = int(binary.BigEndian.Uint16(b[6:8]))
                }
-               h.FragOff = int(nativeEndian.Uint16(b[6:8]))
        default:
                h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
                h.FragOff = int(binary.BigEndian.Uint16(b[6:8]))
        }
        h.Flags = HeaderFlags(h.FragOff&0xe000) >> 13
        h.FragOff = h.FragOff & 0x1fff
-       if hdrlen-HeaderLen > 0 {
-               h.Options = make([]byte, hdrlen-HeaderLen)
-               copy(h.Options, b[HeaderLen:])
+       optlen := hdrlen - HeaderLen
+       if optlen > 0 && len(b) >= hdrlen {
+               if cap(h.Options) < optlen {
+                       h.Options = make([]byte, optlen)
+               } else {
+                       h.Options = h.Options[:optlen]
+               }
+               copy(h.Options, b[HeaderLen:hdrlen])
+       }
+       return nil
+}
+
+// ParseHeader parses b as an IPv4 header.
+func ParseHeader(b []byte) (*Header, error) {
+       h := new(Header)
+       if err := h.Parse(b); err != nil {
+               return nil, err
        }
        return h, nil
 }
index acecfd0d348d0affb417de8365e4a1391cd04838..a5052e3249e6031ddba57ae6b448c558554e718f 100644 (file)
@@ -1,14 +1,12 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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
 
 import (
-       "encoding/binary"
        "errors"
        "net"
-       "unsafe"
 )
 
 var (
@@ -23,20 +21,8 @@ var (
 
        // See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
        freebsdVersion uint32
-
-       nativeEndian binary.ByteOrder
 )
 
-func init() {
-       i := uint32(1)
-       b := (*[4]byte)(unsafe.Pointer(&i))
-       if b[0] == 1 {
-               nativeEndian = binary.LittleEndian
-       } else {
-               nativeEndian = binary.BigEndian
-       }
-}
-
 func boolint(b bool) int {
        if b {
                return 1
@@ -57,3 +43,21 @@ func netAddrToIP4(a net.Addr) net.IP {
        }
        return nil
 }
+
+func opAddr(a net.Addr) net.Addr {
+       switch a.(type) {
+       case *net.TCPAddr:
+               if a == nil {
+                       return nil
+               }
+       case *net.UDPAddr:
+               if a == nil {
+                       return nil
+               }
+       case *net.IPAddr:
+               if a == nil {
+                       return nil
+               }
+       }
+       return a
+}
diff --git a/vendor/golang.org/x/net/ipv4/helper_stub.go b/vendor/golang.org/x/net/ipv4/helper_stub.go
deleted file mode 100644 (file)
index dc2120c..0000000
+++ /dev/null
@@ -1,23 +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.
-
-// +build nacl plan9 solaris
-
-package ipv4
-
-func (c *genericOpt) sysfd() (int, error) {
-       return 0, errOpNoSupport
-}
-
-func (c *dgramOpt) sysfd() (int, error) {
-       return 0, errOpNoSupport
-}
-
-func (c *payloadHandler) sysfd() (int, error) {
-       return 0, errOpNoSupport
-}
-
-func (c *packetHandler) sysfd() (int, error) {
-       return 0, errOpNoSupport
-}
diff --git a/vendor/golang.org/x/net/ipv4/helper_unix.go b/vendor/golang.org/x/net/ipv4/helper_unix.go
deleted file mode 100644 (file)
index 345ca7d..0000000
+++ /dev/null
@@ -1,50 +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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd
-
-package ipv4
-
-import (
-       "net"
-       "reflect"
-)
-
-func (c *genericOpt) sysfd() (int, error) {
-       switch p := c.Conn.(type) {
-       case *net.TCPConn, *net.UDPConn, *net.IPConn:
-               return sysfd(p)
-       }
-       return 0, errInvalidConnType
-}
-
-func (c *dgramOpt) sysfd() (int, error) {
-       switch p := c.PacketConn.(type) {
-       case *net.UDPConn, *net.IPConn:
-               return sysfd(p.(net.Conn))
-       }
-       return 0, errInvalidConnType
-}
-
-func (c *payloadHandler) sysfd() (int, error) {
-       return sysfd(c.PacketConn.(net.Conn))
-}
-
-func (c *packetHandler) sysfd() (int, error) {
-       return sysfd(c.c)
-}
-
-func sysfd(c net.Conn) (int, error) {
-       cv := reflect.ValueOf(c)
-       switch ce := cv.Elem(); ce.Kind() {
-       case reflect.Struct:
-               netfd := ce.FieldByName("conn").FieldByName("fd")
-               switch fe := netfd.Elem(); fe.Kind() {
-               case reflect.Struct:
-                       fd := fe.FieldByName("sysfd")
-                       return int(fd.Int()), nil
-               }
-       }
-       return 0, errInvalidConnType
-}
diff --git a/vendor/golang.org/x/net/ipv4/helper_windows.go b/vendor/golang.org/x/net/ipv4/helper_windows.go
deleted file mode 100644 (file)
index 322b2a5..0000000
+++ /dev/null
@@ -1,49 +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
-
-import (
-       "net"
-       "reflect"
-       "syscall"
-)
-
-func (c *genericOpt) sysfd() (syscall.Handle, error) {
-       switch p := c.Conn.(type) {
-       case *net.TCPConn, *net.UDPConn, *net.IPConn:
-               return sysfd(p)
-       }
-       return syscall.InvalidHandle, errInvalidConnType
-}
-
-func (c *dgramOpt) sysfd() (syscall.Handle, error) {
-       switch p := c.PacketConn.(type) {
-       case *net.UDPConn, *net.IPConn:
-               return sysfd(p.(net.Conn))
-       }
-       return syscall.InvalidHandle, errInvalidConnType
-}
-
-func (c *payloadHandler) sysfd() (syscall.Handle, error) {
-       return sysfd(c.PacketConn.(net.Conn))
-}
-
-func (c *packetHandler) sysfd() (syscall.Handle, error) {
-       return sysfd(c.c)
-}
-
-func sysfd(c net.Conn) (syscall.Handle, error) {
-       cv := reflect.ValueOf(c)
-       switch ce := cv.Elem(); ce.Kind() {
-       case reflect.Struct:
-               netfd := ce.FieldByName("conn").FieldByName("fd")
-               switch fe := netfd.Elem(); fe.Kind() {
-               case reflect.Struct:
-                       fd := fe.FieldByName("sysfd")
-                       return syscall.Handle(fd.Uint()), nil
-               }
-       }
-       return syscall.InvalidHandle, errInvalidConnType
-}
index dbd05cff2cf520dd5495a050f1fd58db4c5baf24..9902bb3d2a5575656dcaaad9cc3372b9ec6e5796 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -26,12 +26,12 @@ func (typ ICMPType) Protocol() int {
 // packets. The filter belongs to a packet delivery path on a host and
 // it cannot interact with forwarding packets or tunnel-outer packets.
 //
-// Note: RFC 2460 defines a reasonable role model and it works not
+// Note: RFC 8200 defines a reasonable role model and it works not
 // only for IPv6 but IPv4. A node means a device that implements IP.
 // A router means a node that forwards IP packets not explicitly
 // addressed to itself, and a host means a node that is not a router.
 type ICMPFilter struct {
-       sysICMPFilter
+       icmpFilter
 }
 
 // Accept accepts incoming ICMP packets including the type field value
index c9122533549785b38d987d36635cd601c1e90718..6e1c5c80ad1dd1d39216e9ef12e46bb525d400a3 100644 (file)
@@ -4,15 +4,15 @@
 
 package ipv4
 
-func (f *sysICMPFilter) accept(typ ICMPType) {
+func (f *icmpFilter) accept(typ ICMPType) {
        f.Data &^= 1 << (uint32(typ) & 31)
 }
 
-func (f *sysICMPFilter) block(typ ICMPType) {
+func (f *icmpFilter) block(typ ICMPType) {
        f.Data |= 1 << (uint32(typ) & 31)
 }
 
-func (f *sysICMPFilter) setAll(block bool) {
+func (f *icmpFilter) setAll(block bool) {
        if block {
                f.Data = 1<<32 - 1
        } else {
@@ -20,6 +20,6 @@ func (f *sysICMPFilter) setAll(block bool) {
        }
 }
 
-func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
+func (f *icmpFilter) willBlock(typ ICMPType) bool {
        return f.Data&(1<<(uint32(typ)&31)) != 0
 }
index 9ee9b6a3295730996d6d3cf3f4507ba2a00574ef..21bb29ab3669a77b92cc80c666dd47d457833980 100644 (file)
@@ -6,20 +6,20 @@
 
 package ipv4
 
-const sysSizeofICMPFilter = 0x0
+const sizeofICMPFilter = 0x0
 
-type sysICMPFilter struct {
+type icmpFilter struct {
 }
 
-func (f *sysICMPFilter) accept(typ ICMPType) {
+func (f *icmpFilter) accept(typ ICMPType) {
 }
 
-func (f *sysICMPFilter) block(typ ICMPType) {
+func (f *icmpFilter) block(typ ICMPType) {
 }
 
-func (f *sysICMPFilter) setAll(block bool) {
+func (f *icmpFilter) setAll(block bool) {
 }
 
-func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
+func (f *icmpFilter) willBlock(typ ICMPType) bool {
        return false
 }
index 09864314e4b3c5ca109db16be8ea9f605414d210..f00f5b052f416dece5a5d71d5831e51e7de722c3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
@@ -7,42 +7,30 @@ package ipv4
 import (
        "net"
        "syscall"
+
+       "golang.org/x/net/internal/socket"
 )
 
+// 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
+       *net.IPConn
+       *socket.Conn
        rawOpt
 }
 
-func (c *packetHandler) ok() bool { return c != nil && c.c != nil }
+func (c *packetHandler) ok() bool { return c != nil && c.IPConn != nil && c.Conn != nil }
 
 // ReadFrom reads an IPv4 datagram from the endpoint c, copying the
-// datagram into b.  It returns the received datagram as the IPv4
+// datagram into b. It returns the received datagram as the IPv4
 // header h, the payload p and the control message cm.
 func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) {
        if !c.ok() {
                return nil, nil, nil, syscall.EINVAL
        }
-       oob := newControlMessage(&c.rawOpt)
-       n, oobn, _, src, err := c.c.ReadMsgIP(b, oob)
-       if err != nil {
-               return nil, nil, nil, err
-       }
-       var hs []byte
-       if hs, p, err = slicePacket(b[:n]); err != nil {
-               return nil, nil, nil, err
-       }
-       if h, err = ParseHeader(hs); err != nil {
-               return nil, nil, nil, err
-       }
-       if cm, err = parseControlMessage(oob[:oobn]); err != nil {
-               return nil, nil, nil, err
-       }
-       if src != nil && cm != nil {
-               cm.Src = src.IP
-       }
-       return
+       return c.readFrom(b)
 }
 
 func slicePacket(b []byte) (h, p []byte, err error) {
@@ -54,14 +42,14 @@ func slicePacket(b []byte) (h, p []byte, err error) {
 }
 
 // WriteTo writes an IPv4 datagram through the endpoint c, copying the
-// datagram from the IPv4 header h and the payload p.  The control
+// datagram from the IPv4 header h and the payload p. The control
 // message cm allows the datagram path and the outgoing interface to be
-// specified.  Currently only Darwin and Linux support this.  The cm
+// specified.  Currently only Darwin and Linux support this. The cm
 // may be nil if control of the outgoing datagram is not required.
 //
 // 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>
@@ -77,21 +65,5 @@ func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error {
        if !c.ok() {
                return syscall.EINVAL
        }
-       oob := marshalControlMessage(cm)
-       wh, err := h.Marshal()
-       if err != nil {
-               return err
-       }
-       dst := &net.IPAddr{}
-       if cm != nil {
-               if ip := cm.Dst.To4(); ip != nil {
-                       dst.IP = ip
-               }
-       }
-       if dst.IP == nil {
-               dst.IP = h.Dst
-       }
-       wh = append(wh, p...)
-       _, _, err = c.c.WriteMsgIP(wh, oob, dst)
-       return err
+       return c.writeTo(h, p, cm)
 }
index d7698cbd35f07616606df02d3b92345fffd7eeb9..f95f811acd2b15d0ff395f9d2886d63ddf13e474 100644 (file)
@@ -1,15 +1,23 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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
 
-import "net"
+import (
+       "net"
+
+       "golang.org/x/net/internal/socket"
+)
+
+// 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
+       *socket.Conn
        rawOpt
 }
 
-func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil }
+func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil && c.Conn != nil }
index d358fc3ac4b766e23e995a03055ebeab6eb27e5d..3f06d76063397bdbfa658d5a49452019aade5155 100644 (file)
@@ -1,8 +1,8 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
-// +build !plan9,!solaris,!windows
+// +build !nacl,!plan9,!windows
 
 package ipv4
 
@@ -12,70 +12,25 @@ import (
 )
 
 // ReadFrom reads a payload of the received IPv4 datagram, from the
-// endpoint c, copying the payload into b.  It returns the number of
+// endpoint c, copying the payload into b. It returns the number of
 // bytes copied into b, the control message cm and the source address
 // src of the received datagram.
 func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
        if !c.ok() {
                return 0, nil, nil, syscall.EINVAL
        }
-       oob := newControlMessage(&c.rawOpt)
-       var oobn int
-       switch c := c.PacketConn.(type) {
-       case *net.UDPConn:
-               if n, oobn, _, src, err = c.ReadMsgUDP(b, oob); err != nil {
-                       return 0, nil, nil, err
-               }
-       case *net.IPConn:
-               if sockOpts[ssoStripHeader].name > 0 {
-                       if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil {
-                               return 0, nil, nil, err
-                       }
-               } else {
-                       nb := make([]byte, maxHeaderLen+len(b))
-                       if n, oobn, _, src, err = c.ReadMsgIP(nb, oob); err != nil {
-                               return 0, nil, nil, err
-                       }
-                       hdrlen := int(nb[0]&0x0f) << 2
-                       copy(b, nb[hdrlen:])
-                       n -= hdrlen
-               }
-       default:
-               return 0, nil, nil, errInvalidConnType
-       }
-       if cm, err = parseControlMessage(oob[:oobn]); err != nil {
-               return 0, nil, nil, err
-       }
-       if cm != nil {
-               cm.Src = netAddrToIP4(src)
-       }
-       return
+       return c.readFrom(b)
 }
 
 // WriteTo writes a payload of the IPv4 datagram, to the destination
-// address dst through the endpoint c, copying the payload from b.  It
-// returns the number of bytes written.  The control message cm allows
+// address dst through the endpoint c, copying the payload from b. It
+// returns the number of bytes written. The control message cm allows
 // the datagram path and the outgoing interface to be specified.
-// Currently only Darwin and Linux support this.  The cm may be nil if
+// Currently only Darwin and Linux support this. The cm may be nil if
 // control of the outgoing datagram is not required.
 func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
        if !c.ok() {
                return 0, syscall.EINVAL
        }
-       oob := marshalControlMessage(cm)
-       if dst == nil {
-               return 0, errMissingAddress
-       }
-       switch c := c.PacketConn.(type) {
-       case *net.UDPConn:
-               n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr))
-       case *net.IPConn:
-               n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr))
-       default:
-               return 0, errInvalidConnType
-       }
-       if err != nil {
-               return 0, err
-       }
-       return
+       return c.writeTo(b, cm, dst)
 }
index d128c9c2e7418196c36d870d6d4791f9790307f6..3926de70b8818dc648fb1b1ae84cbca6b6522b94 100644 (file)
@@ -1,8 +1,8 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
-// +build plan9 solaris windows
+// +build nacl plan9 windows
 
 package ipv4
 
@@ -12,7 +12,7 @@ import (
 )
 
 // ReadFrom reads a payload of the received IPv4 datagram, from the
-// endpoint c, copying the payload into b.  It returns the number of
+// endpoint c, copying the payload into b. It returns the number of
 // bytes copied into b, the control message cm and the source address
 // src of the received datagram.
 func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
@@ -26,10 +26,10 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.
 }
 
 // WriteTo writes a payload of the IPv4 datagram, to the destination
-// address dst through the endpoint c, copying the payload from b.  It
-// returns the number of bytes written.  The control message cm allows
+// address dst through the endpoint c, copying the payload from b. It
+// returns the number of bytes written. The control message cm allows
 // the datagram path and the outgoing interface to be specified.
-// Currently only Darwin and Linux support this.  The cm may be nil if
+// Currently only Darwin and Linux support this. The cm may be nil if
 // control of the outgoing datagram is not required.
 func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
        if !c.ok() {
index ace37d30f5f1e904474f14c6bdbdba231a055306..22e90c0392c5b906e269e2a6bef745b9b92a5aed 100644 (file)
@@ -4,6 +4,8 @@
 
 package ipv4
 
+import "golang.org/x/net/internal/socket"
+
 // Sticky socket options
 const (
        ssoTOS                = iota // header field for unicast packet
@@ -24,16 +26,12 @@ const (
        ssoLeaveSourceGroup          // source-specific multicast
        ssoBlockSourceGroup          // any-source or source-specific multicast
        ssoUnblockSourceGroup        // any-source or source-specific multicast
-       ssoMax
+       ssoAttachFilter              // attach BPF for filtering inbound traffic
 )
 
 // Sticky socket option value types
 const (
-       ssoTypeByte = iota + 1
-       ssoTypeInt
-       ssoTypeInterface
-       ssoTypeICMPFilter
-       ssoTypeIPMreq
+       ssoTypeIPMreq = iota + 1
        ssoTypeIPMreqn
        ssoTypeGroupReq
        ssoTypeGroupSourceReq
@@ -41,6 +39,6 @@ const (
 
 // A sockOpt represents a binding for sticky socket option.
 type sockOpt struct {
-       name int // option name, must be equal or greater than 1
-       typ  int // option value type, must be equal or greater than 1
+       socket.Option
+       typ int // hint for option value type; optional
 }
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_asmreq.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreq.go
deleted file mode 100644 (file)
index 4a6aa78..0000000
+++ /dev/null
@@ -1,83 +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.
-
-// +build darwin dragonfly freebsd netbsd openbsd windows
-
-package ipv4
-
-import "net"
-
-func setIPMreqInterface(mreq *sysIPMreq, ifi *net.Interface) error {
-       if ifi == nil {
-               return nil
-       }
-       ifat, err := ifi.Addrs()
-       if err != nil {
-               return err
-       }
-       for _, ifa := range ifat {
-               switch ifa := ifa.(type) {
-               case *net.IPAddr:
-                       if ip := ifa.IP.To4(); ip != nil {
-                               copy(mreq.Interface[:], ip)
-                               return nil
-                       }
-               case *net.IPNet:
-                       if ip := ifa.IP.To4(); ip != nil {
-                               copy(mreq.Interface[:], ip)
-                               return nil
-                       }
-               }
-       }
-       return errNoSuchInterface
-}
-
-func netIP4ToInterface(ip net.IP) (*net.Interface, error) {
-       ift, err := net.Interfaces()
-       if err != nil {
-               return nil, err
-       }
-       for _, ifi := range ift {
-               ifat, err := ifi.Addrs()
-               if err != nil {
-                       return nil, err
-               }
-               for _, ifa := range ifat {
-                       switch ifa := ifa.(type) {
-                       case *net.IPAddr:
-                               if ip.Equal(ifa.IP) {
-                                       return &ifi, nil
-                               }
-                       case *net.IPNet:
-                               if ip.Equal(ifa.IP) {
-                                       return &ifi, nil
-                               }
-                       }
-               }
-       }
-       return nil, errNoSuchInterface
-}
-
-func netInterfaceToIP4(ifi *net.Interface) (net.IP, error) {
-       if ifi == nil {
-               return net.IPv4zero.To4(), nil
-       }
-       ifat, err := ifi.Addrs()
-       if err != nil {
-               return nil, err
-       }
-       for _, ifa := range ifat {
-               switch ifa := ifa.(type) {
-               case *net.IPAddr:
-                       if ip := ifa.IP.To4(); ip != nil {
-                               return ip, nil
-                       }
-               case *net.IPNet:
-                       if ip := ifa.IP.To4(); ip != nil {
-                               return ip, nil
-                       }
-               }
-       }
-       return nil, errNoSuchInterface
-}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_asmreq_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreq_stub.go
deleted file mode 100644 (file)
index 4555152..0000000
+++ /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.
-
-// +build !darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!windows
-
-package ipv4
-
-import "net"
-
-func setsockoptIPMreq(fd, name int, ifi *net.Interface, grp net.IP) error {
-       return errOpNoSupport
-}
-
-func getsockoptInterface(fd, name int) (*net.Interface, error) {
-       return nil, errOpNoSupport
-}
-
-func setsockoptInterface(fd, name int, ifi *net.Interface) error {
-       return errOpNoSupport
-}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_asmreq_unix.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreq_unix.go
deleted file mode 100644 (file)
index fefa901..0000000
+++ /dev/null
@@ -1,46 +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.
-
-// +build darwin dragonfly freebsd netbsd openbsd
-
-package ipv4
-
-import (
-       "net"
-       "os"
-       "unsafe"
-
-       "golang.org/x/net/internal/iana"
-)
-
-func setsockoptIPMreq(fd, name int, ifi *net.Interface, grp net.IP) error {
-       mreq := sysIPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
-       if err := setIPMreqInterface(&mreq, ifi); err != nil {
-               return err
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&mreq), sysSizeofIPMreq))
-}
-
-func getsockoptInterface(fd, name int) (*net.Interface, error) {
-       var b [4]byte
-       l := sysSockoptLen(4)
-       if err := getsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&b[0]), &l); err != nil {
-               return nil, os.NewSyscallError("getsockopt", err)
-       }
-       ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3]))
-       if err != nil {
-               return nil, err
-       }
-       return ifi, nil
-}
-
-func setsockoptInterface(fd, name int, ifi *net.Interface) error {
-       ip, err := netInterfaceToIP4(ifi)
-       if err != nil {
-               return err
-       }
-       var b [4]byte
-       copy(b[:], ip)
-       return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&b[0]), sysSockoptLen(4)))
-}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_asmreq_windows.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreq_windows.go
deleted file mode 100644 (file)
index 431930d..0000000
+++ /dev/null
@@ -1,45 +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
-
-import (
-       "net"
-       "os"
-       "syscall"
-       "unsafe"
-
-       "golang.org/x/net/internal/iana"
-)
-
-func setsockoptIPMreq(fd syscall.Handle, name int, ifi *net.Interface, grp net.IP) error {
-       mreq := sysIPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
-       if err := setIPMreqInterface(&mreq, ifi); err != nil {
-               return err
-       }
-       return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, iana.ProtocolIP, int32(name), (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofIPMreq)))
-}
-
-func getsockoptInterface(fd syscall.Handle, name int) (*net.Interface, error) {
-       var b [4]byte
-       l := int32(4)
-       if err := syscall.Getsockopt(fd, iana.ProtocolIP, int32(name), (*byte)(unsafe.Pointer(&b[0])), &l); err != nil {
-               return nil, os.NewSyscallError("getsockopt", err)
-       }
-       ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3]))
-       if err != nil {
-               return nil, err
-       }
-       return ifi, nil
-}
-
-func setsockoptInterface(fd syscall.Handle, name int, ifi *net.Interface) error {
-       ip, err := netInterfaceToIP4(ifi)
-       if err != nil {
-               return err
-       }
-       var b [4]byte
-       copy(b[:], ip)
-       return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, iana.ProtocolIP, int32(name), (*byte)(unsafe.Pointer(&b[0])), 4))
-}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go
deleted file mode 100644 (file)
index 332f403..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !darwin,!freebsd,!linux,!windows
-
-package ipv4
-
-import "net"
-
-func getsockoptIPMreqn(fd, name int) (*net.Interface, error) {
-       return nil, errOpNoSupport
-}
-
-func setsockoptIPMreqn(fd, name int, ifi *net.Interface, grp net.IP) error {
-       return errOpNoSupport
-}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go b/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go
deleted file mode 100644 (file)
index 92c8e34..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin freebsd linux
-
-package ipv4
-
-import (
-       "net"
-       "os"
-       "unsafe"
-
-       "golang.org/x/net/internal/iana"
-)
-
-func getsockoptIPMreqn(fd, name int) (*net.Interface, error) {
-       var mreqn sysIPMreqn
-       l := sysSockoptLen(sysSizeofIPMreqn)
-       if err := getsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&mreqn), &l); err != nil {
-               return nil, os.NewSyscallError("getsockopt", err)
-       }
-       if mreqn.Ifindex == 0 {
-               return nil, nil
-       }
-       ifi, err := net.InterfaceByIndex(int(mreqn.Ifindex))
-       if err != nil {
-               return nil, err
-       }
-       return ifi, nil
-}
-
-func setsockoptIPMreqn(fd, name int, ifi *net.Interface, grp net.IP) error {
-       var mreqn sysIPMreqn
-       if ifi != nil {
-               mreqn.Ifindex = int32(ifi.Index)
-       }
-       if grp != nil {
-               mreqn.Multiaddr = [4]byte{grp[0], grp[1], grp[2], grp[3]}
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&mreqn), sysSizeofIPMreqn))
-}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go
deleted file mode 100644 (file)
index 8546524..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !darwin,!freebsd,!linux
-
-package ipv4
-
-import "net"
-
-func setsockoptGroupReq(fd, name int, ifi *net.Interface, grp net.IP) error {
-       return errOpNoSupport
-}
-
-func setsockoptGroupSourceReq(fd, name int, ifi *net.Interface, grp, src net.IP) error {
-       return errOpNoSupport
-}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go b/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go
deleted file mode 100644 (file)
index 6f647bc..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin freebsd linux
-
-package ipv4
-
-import (
-       "net"
-       "os"
-       "unsafe"
-
-       "golang.org/x/net/internal/iana"
-)
-
-var freebsd32o64 bool
-
-func setsockoptGroupReq(fd, name int, ifi *net.Interface, grp net.IP) error {
-       var gr sysGroupReq
-       if ifi != nil {
-               gr.Interface = uint32(ifi.Index)
-       }
-       gr.setGroup(grp)
-       var p unsafe.Pointer
-       var l sysSockoptLen
-       if freebsd32o64 {
-               var d [sysSizeofGroupReq + 4]byte
-               s := (*[sysSizeofGroupReq]byte)(unsafe.Pointer(&gr))
-               copy(d[:4], s[:4])
-               copy(d[8:], s[4:])
-               p = unsafe.Pointer(&d[0])
-               l = sysSizeofGroupReq + 4
-       } else {
-               p = unsafe.Pointer(&gr)
-               l = sysSizeofGroupReq
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, p, l))
-}
-
-func setsockoptGroupSourceReq(fd, name int, ifi *net.Interface, grp, src net.IP) error {
-       var gsr sysGroupSourceReq
-       if ifi != nil {
-               gsr.Interface = uint32(ifi.Index)
-       }
-       gsr.setSourceGroup(grp, src)
-       var p unsafe.Pointer
-       var l sysSockoptLen
-       if freebsd32o64 {
-               var d [sysSizeofGroupSourceReq + 4]byte
-               s := (*[sysSizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))
-               copy(d[:4], s[:4])
-               copy(d[8:], s[4:])
-               p = unsafe.Pointer(&d[0])
-               l = sysSizeofGroupSourceReq + 4
-       } else {
-               p = unsafe.Pointer(&gsr)
-               l = sysSizeofGroupSourceReq
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, p, l))
-}
index 9d19f5dfed6562933043d160c0ab2cbfe58e27a5..23249b782e3355bd8a3d235a12cd09d05aeac820 100644 (file)
@@ -1,11 +1,42 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
+// 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.
 
-// +build nacl plan9 solaris
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv4
 
-func setInt(fd int, opt *sockOpt, v int) error {
+import (
+       "net"
+
+       "golang.org/x/net/bpf"
+       "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
+       return nil, errOpNoSupport
+}
+
+func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
+       return errOpNoSupport
+}
+
+func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
+       return nil, errOpNoSupport
+}
+
+func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
+       return errOpNoSupport
+}
+
+func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+       return errOpNoSupport
+}
+
+func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+       return errOpNoSupport
+}
+
+func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
        return errOpNoSupport
 }
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_unix.go b/vendor/golang.org/x/net/ipv4/sockopt_unix.go
deleted file mode 100644 (file)
index 50cdbd8..0000000
+++ /dev/null
@@ -1,122 +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.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd
-
-package ipv4
-
-import (
-       "net"
-       "os"
-       "unsafe"
-
-       "golang.org/x/net/internal/iana"
-)
-
-func getInt(fd int, opt *sockOpt) (int, error) {
-       if opt.name < 1 || (opt.typ != ssoTypeByte && opt.typ != ssoTypeInt) {
-               return 0, errOpNoSupport
-       }
-       var i int32
-       var b byte
-       p := unsafe.Pointer(&i)
-       l := sysSockoptLen(4)
-       if opt.typ == ssoTypeByte {
-               p = unsafe.Pointer(&b)
-               l = sysSockoptLen(1)
-       }
-       if err := getsockopt(fd, iana.ProtocolIP, opt.name, p, &l); err != nil {
-               return 0, os.NewSyscallError("getsockopt", err)
-       }
-       if opt.typ == ssoTypeByte {
-               return int(b), nil
-       }
-       return int(i), nil
-}
-
-func setInt(fd int, opt *sockOpt, v int) error {
-       if opt.name < 1 || (opt.typ != ssoTypeByte && opt.typ != ssoTypeInt) {
-               return errOpNoSupport
-       }
-       i := int32(v)
-       var b byte
-       p := unsafe.Pointer(&i)
-       l := sysSockoptLen(4)
-       if opt.typ == ssoTypeByte {
-               b = byte(v)
-               p = unsafe.Pointer(&b)
-               l = sysSockoptLen(1)
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, opt.name, p, l))
-}
-
-func getInterface(fd int, opt *sockOpt) (*net.Interface, error) {
-       if opt.name < 1 {
-               return nil, errOpNoSupport
-       }
-       switch opt.typ {
-       case ssoTypeInterface:
-               return getsockoptInterface(fd, opt.name)
-       case ssoTypeIPMreqn:
-               return getsockoptIPMreqn(fd, opt.name)
-       default:
-               return nil, errOpNoSupport
-       }
-}
-
-func setInterface(fd int, opt *sockOpt, ifi *net.Interface) error {
-       if opt.name < 1 {
-               return errOpNoSupport
-       }
-       switch opt.typ {
-       case ssoTypeInterface:
-               return setsockoptInterface(fd, opt.name, ifi)
-       case ssoTypeIPMreqn:
-               return setsockoptIPMreqn(fd, opt.name, ifi, nil)
-       default:
-               return errOpNoSupport
-       }
-}
-
-func getICMPFilter(fd int, opt *sockOpt) (*ICMPFilter, error) {
-       if opt.name < 1 || opt.typ != ssoTypeICMPFilter {
-               return nil, errOpNoSupport
-       }
-       var f ICMPFilter
-       l := sysSockoptLen(sysSizeofICMPFilter)
-       if err := getsockopt(fd, iana.ProtocolReserved, opt.name, unsafe.Pointer(&f.sysICMPFilter), &l); err != nil {
-               return nil, os.NewSyscallError("getsockopt", err)
-       }
-       return &f, nil
-}
-
-func setICMPFilter(fd int, opt *sockOpt, f *ICMPFilter) error {
-       if opt.name < 1 || opt.typ != ssoTypeICMPFilter {
-               return errOpNoSupport
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolReserved, opt.name, unsafe.Pointer(&f.sysICMPFilter), sysSizeofICMPFilter))
-}
-
-func setGroup(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
-       if opt.name < 1 {
-               return errOpNoSupport
-       }
-       switch opt.typ {
-       case ssoTypeIPMreq:
-               return setsockoptIPMreq(fd, opt.name, ifi, grp)
-       case ssoTypeIPMreqn:
-               return setsockoptIPMreqn(fd, opt.name, ifi, grp)
-       case ssoTypeGroupReq:
-               return setsockoptGroupReq(fd, opt.name, ifi, grp)
-       default:
-               return errOpNoSupport
-       }
-}
-
-func setSourceGroup(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
-       if opt.name < 1 || opt.typ != ssoTypeGroupSourceReq {
-               return errOpNoSupport
-       }
-       return setsockoptGroupSourceReq(fd, opt.name, ifi, grp, src)
-}
diff --git a/vendor/golang.org/x/net/ipv4/sockopt_windows.go b/vendor/golang.org/x/net/ipv4/sockopt_windows.go
deleted file mode 100644 (file)
index c4c2441..0000000
+++ /dev/null
@@ -1,68 +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
-
-import (
-       "net"
-       "os"
-       "syscall"
-       "unsafe"
-
-       "golang.org/x/net/internal/iana"
-)
-
-func getInt(fd syscall.Handle, opt *sockOpt) (int, error) {
-       if opt.name < 1 || opt.typ != ssoTypeInt {
-               return 0, errOpNoSupport
-       }
-       var i int32
-       l := int32(4)
-       if err := syscall.Getsockopt(fd, iana.ProtocolIP, int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil {
-               return 0, os.NewSyscallError("getsockopt", err)
-       }
-       return int(i), nil
-}
-
-func setInt(fd syscall.Handle, opt *sockOpt, v int) error {
-       if opt.name < 1 || opt.typ != ssoTypeInt {
-               return errOpNoSupport
-       }
-       i := int32(v)
-       return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, iana.ProtocolIP, int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4))
-}
-
-func getInterface(fd syscall.Handle, opt *sockOpt) (*net.Interface, error) {
-       if opt.name < 1 || opt.typ != ssoTypeInterface {
-               return nil, errOpNoSupport
-       }
-       return getsockoptInterface(fd, opt.name)
-}
-
-func setInterface(fd syscall.Handle, opt *sockOpt, ifi *net.Interface) error {
-       if opt.name < 1 || opt.typ != ssoTypeInterface {
-               return errOpNoSupport
-       }
-       return setsockoptInterface(fd, opt.name, ifi)
-}
-
-func getICMPFilter(fd syscall.Handle, opt *sockOpt) (*ICMPFilter, error) {
-       return nil, errOpNoSupport
-}
-
-func setICMPFilter(fd syscall.Handle, opt *sockOpt, f *ICMPFilter) error {
-       return errOpNoSupport
-}
-
-func setGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
-       if opt.name < 1 || opt.typ != ssoTypeIPMreq {
-               return errOpNoSupport
-       }
-       return setsockoptIPMreq(fd, opt.name, ifi, grp)
-}
-
-func setSourceGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
-       // TODO(mikio): implement this
-       return errOpNoSupport
-}
index a669a4403f733db1864330fa35e8320d79cb9bb7..58256dd9d6fa98ec17953c5bb43e5aef45d6c2aa 100644 (file)
@@ -2,16 +2,17 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build dragonfly netbsd
+// +build netbsd openbsd
 
 package ipv4
 
 import (
        "net"
        "syscall"
-)
 
-type sysSockoptLen int32
+       "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
+)
 
 var (
        ctlOpts = [ctlMax]ctlOpt{
@@ -20,17 +21,17 @@ var (
                ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
        }
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoTOS:                {sysIP_TOS, ssoTypeInt},
-               ssoTTL:                {sysIP_TTL, ssoTypeInt},
-               ssoMulticastTTL:       {sysIP_MULTICAST_TTL, ssoTypeByte},
-               ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastLoopback:  {sysIP_MULTICAST_LOOP, ssoTypeInt},
-               ssoReceiveTTL:         {sysIP_RECVTTL, ssoTypeInt},
-               ssoReceiveDst:         {sysIP_RECVDSTADDR, ssoTypeInt},
-               ssoReceiveInterface:   {sysIP_RECVIF, ssoTypeInt},
-               ssoHeaderPrepend:      {sysIP_HDRINCL, ssoTypeInt},
-               ssoJoinGroup:          {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq},
-               ssoLeaveGroup:         {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq},
+       sockOpts = map[int]*sockOpt{
+               ssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+               ssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+               ssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
+               ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+               ssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 1}},
+               ssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+               ssoReceiveDst:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
+               ssoReceiveInterface:   {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
+               ssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+               ssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+               ssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
        }
 )
index 3f347348182a82dbb5925739e8a345f4e97360b9..e8fb19169205f9eff85d5668b296d83a1f188d6c 100644 (file)
@@ -6,11 +6,14 @@ package ipv4
 
 import (
        "net"
+       "strconv"
+       "strings"
        "syscall"
        "unsafe"
-)
 
-type sysSockoptLen int32
+       "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
+)
 
 var (
        ctlOpts = [ctlMax]ctlOpt{
@@ -19,80 +22,72 @@ var (
                ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
        }
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoTOS:                {sysIP_TOS, ssoTypeInt},
-               ssoTTL:                {sysIP_TTL, ssoTypeInt},
-               ssoMulticastTTL:       {sysIP_MULTICAST_TTL, ssoTypeByte},
-               ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastLoopback:  {sysIP_MULTICAST_LOOP, ssoTypeInt},
-               ssoReceiveTTL:         {sysIP_RECVTTL, ssoTypeInt},
-               ssoReceiveDst:         {sysIP_RECVDSTADDR, ssoTypeInt},
-               ssoReceiveInterface:   {sysIP_RECVIF, ssoTypeInt},
-               ssoHeaderPrepend:      {sysIP_HDRINCL, ssoTypeInt},
-               ssoStripHeader:        {sysIP_STRIPHDR, ssoTypeInt},
-               ssoJoinGroup:          {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq},
-               ssoLeaveGroup:         {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq},
+       sockOpts = map[int]*sockOpt{
+               ssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+               ssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+               ssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
+               ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+               ssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
+               ssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+               ssoReceiveDst:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
+               ssoReceiveInterface:   {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
+               ssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+               ssoStripHeader:        {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_STRIPHDR, Len: 4}},
+               ssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+               ssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
        }
 )
 
 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 = sysSizeofInetPktinfo
-               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] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, Len: 4}}
+       sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn}
+       sockOpts[ssoJoinGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
+       sockOpts[ssoLeaveGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
+       sockOpts[ssoJoinSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
+       sockOpts[ssoLeaveSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
+       sockOpts[ssoBlockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
+       sockOpts[ssoUnblockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
 }
 
-func (pi *sysInetPktinfo) setIfindex(i int) {
+func (pi *inetPktinfo) setIfindex(i int) {
        pi.Ifindex = uint32(i)
 }
 
-func (gr *sysGroupReq) setGroup(grp net.IP) {
-       sa := (*sysSockaddrInet)(unsafe.Pointer(&gr.Pad_cgo_0[0]))
-       sa.Len = sysSizeofSockaddrInet
+func (gr *groupReq) setGroup(grp net.IP) {
+       sa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
+       sa.Len = sizeofSockaddrInet
        sa.Family = syscall.AF_INET
        copy(sa.Addr[:], grp)
 }
 
-func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
-       sa := (*sysSockaddrInet)(unsafe.Pointer(&gsr.Pad_cgo_0[0]))
-       sa.Len = sysSizeofSockaddrInet
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+       sa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
+       sa.Len = sizeofSockaddrInet
        sa.Family = syscall.AF_INET
        copy(sa.Addr[:], grp)
-       sa = (*sysSockaddrInet)(unsafe.Pointer(&gsr.Pad_cgo_1[0]))
-       sa.Len = sysSizeofSockaddrInet
+       sa = (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))
+       sa.Len = sizeofSockaddrInet
        sa.Family = syscall.AF_INET
        copy(sa.Addr[:], src)
 }
index 09ef491075caca099c7c72aff0310d51beed010e..b80032454a5d504088ee348573bee35ab0aa46e8 100644 (file)
@@ -10,9 +10,10 @@ import (
        "strings"
        "syscall"
        "unsafe"
-)
 
-type sysSockoptLen int32
+       "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
+)
 
 var (
        ctlOpts = [ctlMax]ctlOpt{
@@ -21,29 +22,29 @@ var (
                ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
        }
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoTOS:                {sysIP_TOS, ssoTypeInt},
-               ssoTTL:                {sysIP_TTL, ssoTypeInt},
-               ssoMulticastTTL:       {sysIP_MULTICAST_TTL, ssoTypeByte},
-               ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastLoopback:  {sysIP_MULTICAST_LOOP, ssoTypeInt},
-               ssoReceiveTTL:         {sysIP_RECVTTL, ssoTypeInt},
-               ssoReceiveDst:         {sysIP_RECVDSTADDR, ssoTypeInt},
-               ssoReceiveInterface:   {sysIP_RECVIF, ssoTypeInt},
-               ssoHeaderPrepend:      {sysIP_HDRINCL, ssoTypeInt},
-               ssoJoinGroup:          {sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
-               ssoLeaveGroup:         {sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
-               ssoJoinSourceGroup:    {sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
-               ssoLeaveSourceGroup:   {sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
-               ssoBlockSourceGroup:   {sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
-               ssoUnblockSourceGroup: {sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
+       sockOpts = map[int]*sockOpt{
+               ssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+               ssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+               ssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
+               ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+               ssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
+               ssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+               ssoReceiveDst:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
+               ssoReceiveInterface:   {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
+               ssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+               ssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+               ssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+               ssoJoinSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoLeaveSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoBlockSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
        }
 )
 
 func init() {
        freebsdVersion, _ = syscall.SysctlUint32("kern.osreldate")
        if freebsdVersion >= 1000000 {
-               sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn
+               sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn}
        }
        if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
                archs, _ := syscall.Sysctl("kern.supported_archs")
@@ -56,20 +57,20 @@ func init() {
        }
 }
 
-func (gr *sysGroupReq) setGroup(grp net.IP) {
-       sa := (*sysSockaddrInet)(unsafe.Pointer(&gr.Group))
-       sa.Len = sysSizeofSockaddrInet
+func (gr *groupReq) setGroup(grp net.IP) {
+       sa := (*sockaddrInet)(unsafe.Pointer(&gr.Group))
+       sa.Len = sizeofSockaddrInet
        sa.Family = syscall.AF_INET
        copy(sa.Addr[:], grp)
 }
 
-func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
-       sa := (*sysSockaddrInet)(unsafe.Pointer(&gsr.Group))
-       sa.Len = sysSizeofSockaddrInet
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+       sa := (*sockaddrInet)(unsafe.Pointer(&gsr.Group))
+       sa.Len = sizeofSockaddrInet
        sa.Family = syscall.AF_INET
        copy(sa.Addr[:], grp)
-       sa = (*sysSockaddrInet)(unsafe.Pointer(&gsr.Source))
-       sa.Len = sysSizeofSockaddrInet
+       sa = (*sockaddrInet)(unsafe.Pointer(&gsr.Source))
+       sa.Len = sizeofSockaddrInet
        sa.Family = syscall.AF_INET
        copy(sa.Addr[:], src)
 }
index b1f3878907d1b4b3989061ec7d87201cd03afc32..60defe13263240729a36f4f365ce9c07dce9dc67 100644 (file)
@@ -8,50 +8,52 @@ import (
        "net"
        "syscall"
        "unsafe"
-)
 
-type sysSockoptLen int32
+       "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
+)
 
 var (
        ctlOpts = [ctlMax]ctlOpt{
                ctlTTL:        {sysIP_TTL, 1, marshalTTL, parseTTL},
-               ctlPacketInfo: {sysIP_PKTINFO, sysSizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
+               ctlPacketInfo: {sysIP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
        }
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoTOS:                {sysIP_TOS, ssoTypeInt},
-               ssoTTL:                {sysIP_TTL, ssoTypeInt},
-               ssoMulticastTTL:       {sysIP_MULTICAST_TTL, ssoTypeInt},
-               ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeIPMreqn},
-               ssoMulticastLoopback:  {sysIP_MULTICAST_LOOP, ssoTypeInt},
-               ssoReceiveTTL:         {sysIP_RECVTTL, ssoTypeInt},
-               ssoPacketInfo:         {sysIP_PKTINFO, ssoTypeInt},
-               ssoHeaderPrepend:      {sysIP_HDRINCL, ssoTypeInt},
-               ssoICMPFilter:         {sysICMP_FILTER, ssoTypeICMPFilter},
-               ssoJoinGroup:          {sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
-               ssoLeaveGroup:         {sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
-               ssoJoinSourceGroup:    {sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
-               ssoLeaveSourceGroup:   {sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
-               ssoBlockSourceGroup:   {sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
-               ssoUnblockSourceGroup: {sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
+       sockOpts = map[int]*sockOpt{
+               ssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+               ssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+               ssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 4}},
+               ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn},
+               ssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
+               ssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+               ssoPacketInfo:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_PKTINFO, Len: 4}},
+               ssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+               ssoICMPFilter:         {Option: socket.Option{Level: iana.ProtocolReserved, Name: sysICMP_FILTER, Len: sizeofICMPFilter}},
+               ssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+               ssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+               ssoJoinSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoLeaveSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoBlockSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoAttachFilter:       {Option: socket.Option{Level: sysSOL_SOCKET, Name: sysSO_ATTACH_FILTER, Len: sizeofSockFprog}},
        }
 )
 
-func (pi *sysInetPktinfo) setIfindex(i int) {
+func (pi *inetPktinfo) setIfindex(i int) {
        pi.Ifindex = int32(i)
 }
 
-func (gr *sysGroupReq) setGroup(grp net.IP) {
-       sa := (*sysSockaddrInet)(unsafe.Pointer(&gr.Group))
+func (gr *groupReq) setGroup(grp net.IP) {
+       sa := (*sockaddrInet)(unsafe.Pointer(&gr.Group))
        sa.Family = syscall.AF_INET
        copy(sa.Addr[:], grp)
 }
 
-func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
-       sa := (*sysSockaddrInet)(unsafe.Pointer(&gsr.Group))
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+       sa := (*sockaddrInet)(unsafe.Pointer(&gsr.Group))
        sa.Family = syscall.AF_INET
        copy(sa.Addr[:], grp)
-       sa = (*sysSockaddrInet)(unsafe.Pointer(&gsr.Source))
+       sa = (*sockaddrInet)(unsafe.Pointer(&gsr.Source))
        sa.Family = syscall.AF_INET
        copy(sa.Addr[:], src)
 }
diff --git a/vendor/golang.org/x/net/ipv4/sys_openbsd.go b/vendor/golang.org/x/net/ipv4/sys_openbsd.go
deleted file mode 100644 (file)
index 550f208..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ipv4
-
-import (
-       "net"
-       "syscall"
-)
-
-type sysSockoptLen int32
-
-var (
-       ctlOpts = [ctlMax]ctlOpt{
-               ctlTTL:       {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
-               ctlDst:       {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
-               ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
-       }
-
-       sockOpts = [ssoMax]sockOpt{
-               ssoTOS:                {sysIP_TOS, ssoTypeInt},
-               ssoTTL:                {sysIP_TTL, ssoTypeInt},
-               ssoMulticastTTL:       {sysIP_MULTICAST_TTL, ssoTypeByte},
-               ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastLoopback:  {sysIP_MULTICAST_LOOP, ssoTypeByte},
-               ssoReceiveTTL:         {sysIP_RECVTTL, ssoTypeInt},
-               ssoReceiveDst:         {sysIP_RECVDSTADDR, ssoTypeInt},
-               ssoReceiveInterface:   {sysIP_RECVIF, ssoTypeInt},
-               ssoHeaderPrepend:      {sysIP_HDRINCL, ssoTypeInt},
-               ssoJoinGroup:          {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq},
-               ssoLeaveGroup:         {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq},
-       }
-)
index efbcc479a74661343b9ff2566f30f7cf74ae5796..4f076473bd1dcd2291a06721bd71fcdc354edbfc 100644 (file)
@@ -2,14 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build nacl plan9 solaris
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv4
 
-type sysSockoptLen int32
-
 var (
        ctlOpts = [ctlMax]ctlOpt{}
 
-       sockOpts = [ssoMax]sockOpt{}
+       sockOpts = map[int]*sockOpt{}
 )
index 466489fe06d32b4f2de952b16a3377f962703657..b0913d539c30757484fcd41bbd938c6671023245 100644 (file)
@@ -4,6 +4,11 @@
 
 package ipv4
 
+import (
+       "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
+)
+
 const (
        // See ws2tcpip.h.
        sysIP_OPTIONS                = 0x1
@@ -20,22 +25,22 @@ const (
        sysIP_DROP_SOURCE_MEMBERSHIP = 0x10
        sysIP_PKTINFO                = 0x13
 
-       sysSizeofInetPktinfo  = 0x8
-       sysSizeofIPMreq       = 0x8
-       sysSizeofIPMreqSource = 0xc
+       sizeofInetPktinfo  = 0x8
+       sizeofIPMreq       = 0x8
+       sizeofIPMreqSource = 0xc
 )
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Addr    [4]byte
        Ifindex int32
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte
        Interface [4]byte
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  [4]byte
        Sourceaddr [4]byte
        Interface  [4]byte
@@ -45,17 +50,18 @@ type sysIPMreqSource struct {
 var (
        ctlOpts = [ctlMax]ctlOpt{}
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoTOS:                {sysIP_TOS, ssoTypeInt},
-               ssoTTL:                {sysIP_TTL, ssoTypeInt},
-               ssoMulticastTTL:       {sysIP_MULTICAST_TTL, ssoTypeInt},
-               ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastLoopback:  {sysIP_MULTICAST_LOOP, ssoTypeInt},
-               ssoJoinGroup:          {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq},
-               ssoLeaveGroup:         {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq},
+       sockOpts = map[int]*sockOpt{
+               ssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+               ssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+               ssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 4}},
+               ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+               ssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
+               ssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+               ssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+               ssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
        }
 )
 
-func (pi *sysInetPktinfo) setIfindex(i int) {
+func (pi *inetPktinfo) setIfindex(i int) {
        pi.Ifindex = int32(i)
 }
diff --git a/vendor/golang.org/x/net/ipv4/syscall_linux_386.go b/vendor/golang.org/x/net/ipv4/syscall_linux_386.go
deleted file mode 100644 (file)
index ab4ad04..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ipv4
-
-import (
-       "syscall"
-       "unsafe"
-)
-
-const (
-       sysGETSOCKOPT = 0xf
-       sysSETSOCKOPT = 0xe
-)
-
-func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
-
-func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error {
-       if _, errno := socketcall(sysGETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
-               return error(errno)
-       }
-       return nil
-}
-
-func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error {
-       if _, errno := socketcall(sysSETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
-               return error(errno)
-       }
-       return nil
-}
diff --git a/vendor/golang.org/x/net/ipv4/syscall_unix.go b/vendor/golang.org/x/net/ipv4/syscall_unix.go
deleted file mode 100644 (file)
index 5fe8e83..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux,!386 netbsd openbsd
-
-package ipv4
-
-import (
-       "syscall"
-       "unsafe"
-)
-
-func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error {
-       if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
-               return error(errno)
-       }
-       return nil
-}
-
-func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error {
-       if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
-               return error(errno)
-       }
-       return nil
-}
diff --git a/vendor/golang.org/x/net/ipv4/thunk_linux_386.s b/vendor/golang.org/x/net/ipv4/thunk_linux_386.s
deleted file mode 100644 (file)
index daa78bc..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.2
-
-TEXT   Â·socketcall(SB),4,$0-36
-       JMP     syscall·socketcall(SB)
index 087c63906393b1c14b3fdfc9642efd72fbc3887c..c07cc883fc34df556e2598cb1b95d1b1c183e1ae 100644 (file)
@@ -37,18 +37,18 @@ const (
        sysMCAST_BLOCK_SOURCE        = 0x54
        sysMCAST_UNBLOCK_SOURCE      = 0x55
 
-       sysSizeofSockaddrStorage = 0x80
-       sysSizeofSockaddrInet    = 0x10
-       sysSizeofInetPktinfo     = 0xc
+       sizeofSockaddrStorage = 0x80
+       sizeofSockaddrInet    = 0x10
+       sizeofInetPktinfo     = 0xc
 
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x84
-       sysSizeofGroupSourceReq = 0x104
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x84
+       sizeofGroupSourceReq = 0x104
 )
 
-type sysSockaddrStorage struct {
+type sockaddrStorage struct {
        Len         uint8
        Family      uint8
        X__ss_pad1  [6]int8
@@ -56,7 +56,7 @@ type sysSockaddrStorage struct {
        X__ss_pad2  [112]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Len    uint8
        Family uint8
        Port   uint16
@@ -64,35 +64,35 @@ type sysSockaddrInet struct {
        Zero   [8]int8
 }
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Ifindex  uint32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  [4]byte /* in_addr */
        Sourceaddr [4]byte /* in_addr */
        Interface  [4]byte /* in_addr */
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [128]byte
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [128]byte
        Pad_cgo_1 [128]byte
index f5c9ccec4fbfc87084170f73aa52cf72b2df9383..c4365e9e7121e91d34487dc1f65dd1c18fc79942 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_dragonfly.go
 
-// +build dragonfly
-
 package ipv4
 
 const (
@@ -24,10 +22,10 @@ const (
        sysIP_ADD_MEMBERSHIP  = 0xc
        sysIP_DROP_MEMBERSHIP = 0xd
 
-       sysSizeofIPMreq = 0x8
+       sizeofIPMreq = 0x8
 )
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
index 6fd67e1e9954058363c04251f82e00bc647225fb..8c4aec94c8a0b872198a15e3db1f07137fb441ad 100644 (file)
@@ -38,17 +38,17 @@ const (
        sysMCAST_BLOCK_SOURCE        = 0x54
        sysMCAST_UNBLOCK_SOURCE      = 0x55
 
-       sysSizeofSockaddrStorage = 0x80
-       sysSizeofSockaddrInet    = 0x10
+       sizeofSockaddrStorage = 0x80
+       sizeofSockaddrInet    = 0x10
 
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x84
-       sysSizeofGroupSourceReq = 0x104
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x84
+       sizeofGroupSourceReq = 0x104
 )
 
-type sysSockaddrStorage struct {
+type sockaddrStorage struct {
        Len         uint8
        Family      uint8
        X__ss_pad1  [6]int8
@@ -56,7 +56,7 @@ type sysSockaddrStorage struct {
        X__ss_pad2  [112]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Len    uint8
        Family uint8
        Port   uint16
@@ -64,30 +64,30 @@ type sysSockaddrInet struct {
        Zero   [8]int8
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  [4]byte /* in_addr */
        Sourceaddr [4]byte /* in_addr */
        Interface  [4]byte /* in_addr */
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
-       Group     sysSockaddrStorage
+       Group     sockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
-       Group     sysSockaddrStorage
-       Source    sysSockaddrStorage
+       Group     sockaddrStorage
+       Source    sockaddrStorage
 }
index ebac6d7926dd2a37530c00823d32ef3ffdffb0fb..4b10b7c575fe5d7bfb429ef10030b509a60f6b04 100644 (file)
@@ -38,17 +38,17 @@ const (
        sysMCAST_BLOCK_SOURCE        = 0x54
        sysMCAST_UNBLOCK_SOURCE      = 0x55
 
-       sysSizeofSockaddrStorage = 0x80
-       sysSizeofSockaddrInet    = 0x10
+       sizeofSockaddrStorage = 0x80
+       sizeofSockaddrInet    = 0x10
 
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 )
 
-type sysSockaddrStorage struct {
+type sockaddrStorage struct {
        Len         uint8
        Family      uint8
        X__ss_pad1  [6]int8
@@ -56,7 +56,7 @@ type sysSockaddrStorage struct {
        X__ss_pad2  [112]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Len    uint8
        Family uint8
        Port   uint16
@@ -64,32 +64,32 @@ type sysSockaddrInet struct {
        Zero   [8]int8
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  [4]byte /* in_addr */
        Sourceaddr [4]byte /* in_addr */
        Interface  [4]byte /* in_addr */
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysSockaddrStorage
+       Group     sockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysSockaddrStorage
-       Source    sysSockaddrStorage
+       Group     sockaddrStorage
+       Source    sockaddrStorage
 }
index ebac6d7926dd2a37530c00823d32ef3ffdffb0fb..4b10b7c575fe5d7bfb429ef10030b509a60f6b04 100644 (file)
@@ -38,17 +38,17 @@ const (
        sysMCAST_BLOCK_SOURCE        = 0x54
        sysMCAST_UNBLOCK_SOURCE      = 0x55
 
-       sysSizeofSockaddrStorage = 0x80
-       sysSizeofSockaddrInet    = 0x10
+       sizeofSockaddrStorage = 0x80
+       sizeofSockaddrInet    = 0x10
 
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 )
 
-type sysSockaddrStorage struct {
+type sockaddrStorage struct {
        Len         uint8
        Family      uint8
        X__ss_pad1  [6]int8
@@ -56,7 +56,7 @@ type sysSockaddrStorage struct {
        X__ss_pad2  [112]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Len    uint8
        Family uint8
        Port   uint16
@@ -64,32 +64,32 @@ type sysSockaddrInet struct {
        Zero   [8]int8
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  [4]byte /* in_addr */
        Sourceaddr [4]byte /* in_addr */
        Interface  [4]byte /* in_addr */
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysSockaddrStorage
+       Group     sockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysSockaddrStorage
-       Source    sysSockaddrStorage
+       Group     sockaddrStorage
+       Source    sockaddrStorage
 }
index fc7a9ebfbf18177040ed99cd7f3fd2eab6490ab2..c0260f0ce34f1f841a4a4c72b6a72600bd7dceb9 100644 (file)
@@ -55,39 +55,44 @@ const (
        sysSO_EE_ORIGIN_TXSTATUS     = 0x4
        sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet          = 0x10
-       sysSizeofInetPktinfo           = 0xc
-       sysSizeofSockExtendedErr       = 0x10
-
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x84
-       sysSizeofGroupSourceReq = 0x104
-
-       sysSizeofICMPFilter = 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
+
+       sizeofSockFprog = 0x8
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Family uint16
        Port   uint16
        Addr   [4]byte /* in_addr */
        X__pad [8]uint8
 }
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Ifindex  int32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysSockExtendedErr struct {
+type sockExtendedErr struct {
        Errno  uint32
        Origin uint8
        Type   uint8
@@ -97,34 +102,47 @@ type sysSockExtendedErr struct {
        Data   uint32
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  uint32
        Interface  uint32
        Sourceaddr uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPFilter struct {
+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
+}
index e324b81b6317301e4140f0b0129f6417cca844cc..9c967eaa642d5d7557abf169fec95b1a389417e2 100644 (file)
@@ -55,39 +55,44 @@ const (
        sysSO_EE_ORIGIN_TXSTATUS     = 0x4
        sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet          = 0x10
-       sysSizeofInetPktinfo           = 0xc
-       sysSizeofSockExtendedErr       = 0x10
-
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
-
-       sysSizeofICMPFilter = 0x4
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet          = 0x10
+       sizeofInetPktinfo           = 0xc
+       sizeofSockExtendedErr       = 0x10
+
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
+
+       sizeofICMPFilter = 0x4
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Family uint16
        Port   uint16
        Addr   [4]byte /* in_addr */
        X__pad [8]uint8
 }
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Ifindex  int32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysSockExtendedErr struct {
+type sockExtendedErr struct {
        Errno  uint32
        Origin uint8
        Type   uint8
@@ -97,36 +102,49 @@ type sysSockExtendedErr struct {
        Data   uint32
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  uint32
        Interface  uint32
        Sourceaddr uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPFilter struct {
+type icmpFilter struct {
        Data uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index fc7a9ebfbf18177040ed99cd7f3fd2eab6490ab2..c0260f0ce34f1f841a4a4c72b6a72600bd7dceb9 100644 (file)
@@ -55,39 +55,44 @@ const (
        sysSO_EE_ORIGIN_TXSTATUS     = 0x4
        sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet          = 0x10
-       sysSizeofInetPktinfo           = 0xc
-       sysSizeofSockExtendedErr       = 0x10
-
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x84
-       sysSizeofGroupSourceReq = 0x104
-
-       sysSizeofICMPFilter = 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
+
+       sizeofSockFprog = 0x8
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Family uint16
        Port   uint16
        Addr   [4]byte /* in_addr */
        X__pad [8]uint8
 }
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Ifindex  int32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysSockExtendedErr struct {
+type sockExtendedErr struct {
        Errno  uint32
        Origin uint8
        Type   uint8
@@ -97,34 +102,47 @@ type sysSockExtendedErr struct {
        Data   uint32
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  uint32
        Interface  uint32
        Sourceaddr uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPFilter struct {
+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
+}
index ce4194a64ac798bf366a180548cef16ac89487a1..9c967eaa642d5d7557abf169fec95b1a389417e2 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,arm64
-
 package ipv4
 
 const (
@@ -57,39 +55,44 @@ const (
        sysSO_EE_ORIGIN_TXSTATUS     = 0x4
        sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet          = 0x10
-       sysSizeofInetPktinfo           = 0xc
-       sysSizeofSockExtendedErr       = 0x10
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet          = 0x10
+       sizeofInetPktinfo           = 0xc
+       sizeofSockExtendedErr       = 0x10
 
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPFilter = 0x4
+       sizeofICMPFilter = 0x4
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Family uint16
        Port   uint16
        Addr   [4]byte /* in_addr */
        X__pad [8]uint8
 }
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Ifindex  int32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysSockExtendedErr struct {
+type sockExtendedErr struct {
        Errno  uint32
        Origin uint8
        Type   uint8
@@ -99,36 +102,49 @@ type sysSockExtendedErr struct {
        Data   uint32
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  uint32
        Interface  uint32
        Sourceaddr uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPFilter struct {
+type icmpFilter struct {
        Data uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index 94116bfa663fadca467987922be90b041bcae613..9c967eaa642d5d7557abf169fec95b1a389417e2 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,mips64
-
 package ipv4
 
 const (
@@ -57,39 +55,44 @@ const (
        sysSO_EE_ORIGIN_TXSTATUS     = 0x4
        sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet          = 0x10
-       sysSizeofInetPktinfo           = 0xc
-       sysSizeofSockExtendedErr       = 0x10
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet          = 0x10
+       sizeofInetPktinfo           = 0xc
+       sizeofSockExtendedErr       = 0x10
 
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPFilter = 0x4
+       sizeofICMPFilter = 0x4
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Family uint16
        Port   uint16
        Addr   [4]byte /* in_addr */
        X__pad [8]uint8
 }
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Ifindex  int32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysSockExtendedErr struct {
+type sockExtendedErr struct {
        Errno  uint32
        Origin uint8
        Type   uint8
@@ -99,36 +102,49 @@ type sysSockExtendedErr struct {
        Data   uint32
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  uint32
        Interface  uint32
        Sourceaddr uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPFilter struct {
+type icmpFilter struct {
        Data uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index 698d7db322f0075c396133024deadfc90469ad18..9c967eaa642d5d7557abf169fec95b1a389417e2 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,mips64le
-
 package ipv4
 
 const (
@@ -57,39 +55,44 @@ const (
        sysSO_EE_ORIGIN_TXSTATUS     = 0x4
        sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet          = 0x10
-       sysSizeofInetPktinfo           = 0xc
-       sysSizeofSockExtendedErr       = 0x10
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet          = 0x10
+       sizeofInetPktinfo           = 0xc
+       sizeofSockExtendedErr       = 0x10
 
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPFilter = 0x4
+       sizeofICMPFilter = 0x4
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Family uint16
        Port   uint16
        Addr   [4]byte /* in_addr */
        X__pad [8]uint8
 }
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Ifindex  int32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysSockExtendedErr struct {
+type sockExtendedErr struct {
        Errno  uint32
        Origin uint8
        Type   uint8
@@ -99,36 +102,49 @@ type sysSockExtendedErr struct {
        Data   uint32
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  uint32
        Interface  uint32
        Sourceaddr uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPFilter struct {
+type icmpFilter struct {
        Data uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index 9fe5ee2b64688e6f8324be5809e9715fab3b3e6b..9c967eaa642d5d7557abf169fec95b1a389417e2 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,ppc64
-
 package ipv4
 
 const (
@@ -57,39 +55,44 @@ const (
        sysSO_EE_ORIGIN_TXSTATUS     = 0x4
        sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet          = 0x10
-       sysSizeofInetPktinfo           = 0xc
-       sysSizeofSockExtendedErr       = 0x10
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet          = 0x10
+       sizeofInetPktinfo           = 0xc
+       sizeofSockExtendedErr       = 0x10
 
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPFilter = 0x4
+       sizeofICMPFilter = 0x4
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Family uint16
        Port   uint16
        Addr   [4]byte /* in_addr */
        X__pad [8]uint8
 }
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Ifindex  int32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysSockExtendedErr struct {
+type sockExtendedErr struct {
        Errno  uint32
        Origin uint8
        Type   uint8
@@ -99,36 +102,49 @@ type sysSockExtendedErr struct {
        Data   uint32
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  uint32
        Interface  uint32
        Sourceaddr uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPFilter struct {
+type icmpFilter struct {
        Data uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index 3891f54efa7b8b259474d0bc412bcbe207ca0014..9c967eaa642d5d7557abf169fec95b1a389417e2 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,ppc64le
-
 package ipv4
 
 const (
@@ -57,39 +55,44 @@ const (
        sysSO_EE_ORIGIN_TXSTATUS     = 0x4
        sysSO_EE_ORIGIN_TIMESTAMPING = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet          = 0x10
-       sysSizeofInetPktinfo           = 0xc
-       sysSizeofSockExtendedErr       = 0x10
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet          = 0x10
+       sizeofInetPktinfo           = 0xc
+       sizeofSockExtendedErr       = 0x10
 
-       sysSizeofIPMreq         = 0x8
-       sysSizeofIPMreqn        = 0xc
-       sysSizeofIPMreqSource   = 0xc
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqn        = 0xc
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPFilter = 0x4
+       sizeofICMPFilter = 0x4
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet struct {
+type sockaddrInet struct {
        Family uint16
        Port   uint16
        Addr   [4]byte /* in_addr */
        X__pad [8]uint8
 }
 
-type sysInetPktinfo struct {
+type inetPktinfo struct {
        Ifindex  int32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysSockExtendedErr struct {
+type sockExtendedErr struct {
        Errno  uint32
        Origin uint8
        Type   uint8
@@ -99,36 +102,49 @@ type sysSockExtendedErr struct {
        Data   uint32
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqn struct {
+type ipMreqn struct {
        Multiaddr [4]byte /* in_addr */
        Address   [4]byte /* in_addr */
        Ifindex   int32
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  uint32
        Interface  uint32
        Sourceaddr uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPFilter struct {
+type icmpFilter struct {
        Data uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index 8a440eb65b844e1c3adfcb14b6c9268b57a4ea4d..fd3624d93c43066c6e423924558fbfd9c60d9ade 100644 (file)
@@ -21,10 +21,10 @@ const (
        sysIP_ADD_MEMBERSHIP  = 0xc
        sysIP_DROP_MEMBERSHIP = 0xd
 
-       sysSizeofIPMreq = 0x8
+       sizeofIPMreq = 0x8
 )
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
index fd522b5738828cf38bd60333739fa70b25d9eda4..12f36be759e001b420724aa5fdfd87f435d25a9b 100644 (file)
@@ -21,10 +21,10 @@ const (
        sysIP_ADD_MEMBERSHIP  = 0xc
        sysIP_DROP_MEMBERSHIP = 0xd
 
-       sysSizeofIPMreq = 0x8
+       sizeofIPMreq = 0x8
 )
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
index d7c23349a340b60dc4738ccc6785ce2fd91774de..0a3875cc41a9e9e42cf082cd6d9734265670d5be 100644 (file)
@@ -1,30 +1,20 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_solaris.go
 
-// +build solaris
-
 package ipv4
 
 const (
-       sysIP_OPTIONS       = 0x1
-       sysIP_HDRINCL       = 0x2
-       sysIP_TOS           = 0x3
-       sysIP_TTL           = 0x4
-       sysIP_RECVOPTS      = 0x5
-       sysIP_RECVRETOPTS   = 0x6
-       sysIP_RECVDSTADDR   = 0x7
-       sysIP_RETOPTS       = 0x8
-       sysIP_RECVIF        = 0x9
-       sysIP_RECVSLLA      = 0xa
-       sysIP_RECVTTL       = 0xb
-       sysIP_NEXTHOP       = 0x19
-       sysIP_PKTINFO       = 0x1a
-       sysIP_RECVPKTINFO   = 0x1a
-       sysIP_DONTFRAG      = 0x1b
-       sysIP_BOUND_IF      = 0x41
-       sysIP_UNSPEC_SRC    = 0x42
-       sysIP_BROADCAST_TTL = 0x43
-       sysIP_DHCPINIT_IF   = 0x45
+       sysIP_OPTIONS     = 0x1
+       sysIP_HDRINCL     = 0x2
+       sysIP_TOS         = 0x3
+       sysIP_TTL         = 0x4
+       sysIP_RECVOPTS    = 0x5
+       sysIP_RECVRETOPTS = 0x6
+       sysIP_RECVDSTADDR = 0x7
+       sysIP_RETOPTS     = 0x8
+       sysIP_RECVIF      = 0x9
+       sysIP_RECVSLLA    = 0xa
+       sysIP_RECVTTL     = 0xb
 
        sysIP_MULTICAST_IF           = 0x10
        sysIP_MULTICAST_TTL          = 0x11
@@ -35,26 +25,76 @@ const (
        sysIP_UNBLOCK_SOURCE         = 0x16
        sysIP_ADD_SOURCE_MEMBERSHIP  = 0x17
        sysIP_DROP_SOURCE_MEMBERSHIP = 0x18
+       sysIP_NEXTHOP                = 0x19
+
+       sysIP_PKTINFO     = 0x1a
+       sysIP_RECVPKTINFO = 0x1a
+       sysIP_DONTFRAG    = 0x1b
+
+       sysIP_BOUND_IF      = 0x41
+       sysIP_UNSPEC_SRC    = 0x42
+       sysIP_BROADCAST_TTL = 0x43
+       sysIP_DHCPINIT_IF   = 0x45
 
-       sysSizeofInetPktinfo = 0xc
+       sysIP_REUSEADDR = 0x104
+       sysIP_DONTROUTE = 0x105
+       sysIP_BROADCAST = 0x106
 
-       sysSizeofIPMreq       = 0x8
-       sysSizeofIPMreqSource = 0xc
+       sysMCAST_JOIN_GROUP         = 0x29
+       sysMCAST_LEAVE_GROUP        = 0x2a
+       sysMCAST_BLOCK_SOURCE       = 0x2b
+       sysMCAST_UNBLOCK_SOURCE     = 0x2c
+       sysMCAST_JOIN_SOURCE_GROUP  = 0x2d
+       sysMCAST_LEAVE_SOURCE_GROUP = 0x2e
+
+       sizeofSockaddrStorage = 0x100
+       sizeofSockaddrInet    = 0x10
+       sizeofInetPktinfo     = 0xc
+
+       sizeofIPMreq         = 0x8
+       sizeofIPMreqSource   = 0xc
+       sizeofGroupReq       = 0x104
+       sizeofGroupSourceReq = 0x204
 )
 
-type sysInetPktinfo struct {
+type sockaddrStorage struct {
+       Family     uint16
+       X_ss_pad1  [6]int8
+       X_ss_align float64
+       X_ss_pad2  [240]int8
+}
+
+type sockaddrInet struct {
+       Family uint16
+       Port   uint16
+       Addr   [4]byte /* in_addr */
+       Zero   [8]int8
+}
+
+type inetPktinfo struct {
        Ifindex  uint32
        Spec_dst [4]byte /* in_addr */
        Addr     [4]byte /* in_addr */
 }
 
-type sysIPMreq struct {
+type ipMreq struct {
        Multiaddr [4]byte /* in_addr */
        Interface [4]byte /* in_addr */
 }
 
-type sysIPMreqSource struct {
+type ipMreqSource struct {
        Multiaddr  [4]byte /* in_addr */
        Sourceaddr [4]byte /* in_addr */
        Interface  [4]byte /* in_addr */
 }
+
+type groupReq struct {
+       Interface uint32
+       Pad_cgo_0 [256]byte
+}
+
+type groupSourceReq struct {
+       Interface uint32
+       Pad_cgo_0 [256]byte
+       Pad_cgo_1 [256]byte
+}
index b7362aae794ccc6f3b7aab9b48e6dca5859964a0..2da644413b4a816ae263a8343434d22e4b4f1a2d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -8,10 +8,13 @@ import (
        "fmt"
        "net"
        "sync"
+
+       "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
 // Note that RFC 3542 obsoletes RFC 2292 but OS X Snow Leopard and the
-// former still support RFC 2292 only.  Please be aware that almost
+// former still support RFC 2292 only. Please be aware that almost
 // all protocol implementations prohibit using a combination of RFC
 // 2292 and RFC 3542 for some practical reasons.
 
@@ -66,6 +69,105 @@ func (cm *ControlMessage) String() string {
        return fmt.Sprintf("tclass=%#x hoplim=%d src=%v dst=%v ifindex=%d nexthop=%v mtu=%d", cm.TrafficClass, cm.HopLimit, cm.Src, cm.Dst, cm.IfIndex, cm.NextHop, cm.MTU)
 }
 
+// Marshal returns the binary encoding of cm.
+func (cm *ControlMessage) Marshal() []byte {
+       if cm == nil {
+               return nil
+       }
+       var l int
+       tclass := false
+       if ctlOpts[ctlTrafficClass].name > 0 && cm.TrafficClass > 0 {
+               tclass = true
+               l += socket.ControlMessageSpace(ctlOpts[ctlTrafficClass].length)
+       }
+       hoplimit := false
+       if ctlOpts[ctlHopLimit].name > 0 && cm.HopLimit > 0 {
+               hoplimit = true
+               l += socket.ControlMessageSpace(ctlOpts[ctlHopLimit].length)
+       }
+       pktinfo := false
+       if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To16() != nil && cm.Src.To4() == nil || cm.IfIndex > 0) {
+               pktinfo = true
+               l += socket.ControlMessageSpace(ctlOpts[ctlPacketInfo].length)
+       }
+       nexthop := false
+       if ctlOpts[ctlNextHop].name > 0 && cm.NextHop.To16() != nil && cm.NextHop.To4() == nil {
+               nexthop = true
+               l += socket.ControlMessageSpace(ctlOpts[ctlNextHop].length)
+       }
+       var b []byte
+       if l > 0 {
+               b = make([]byte, l)
+               bb := b
+               if tclass {
+                       bb = ctlOpts[ctlTrafficClass].marshal(bb, cm)
+               }
+               if hoplimit {
+                       bb = ctlOpts[ctlHopLimit].marshal(bb, cm)
+               }
+               if pktinfo {
+                       bb = ctlOpts[ctlPacketInfo].marshal(bb, cm)
+               }
+               if nexthop {
+                       bb = ctlOpts[ctlNextHop].marshal(bb, cm)
+               }
+       }
+       return b
+}
+
+// Parse parses b as a control message and stores the result in cm.
+func (cm *ControlMessage) Parse(b []byte) error {
+       ms, err := socket.ControlMessage(b).Parse()
+       if err != nil {
+               return err
+       }
+       for _, m := range ms {
+               lvl, typ, l, err := m.ParseHeader()
+               if err != nil {
+                       return err
+               }
+               if lvl != iana.ProtocolIPv6 {
+                       continue
+               }
+               switch {
+               case typ == ctlOpts[ctlTrafficClass].name && l >= ctlOpts[ctlTrafficClass].length:
+                       ctlOpts[ctlTrafficClass].parse(cm, m.Data(l))
+               case typ == ctlOpts[ctlHopLimit].name && l >= ctlOpts[ctlHopLimit].length:
+                       ctlOpts[ctlHopLimit].parse(cm, m.Data(l))
+               case typ == ctlOpts[ctlPacketInfo].name && l >= ctlOpts[ctlPacketInfo].length:
+                       ctlOpts[ctlPacketInfo].parse(cm, m.Data(l))
+               case typ == ctlOpts[ctlPathMTU].name && l >= ctlOpts[ctlPathMTU].length:
+                       ctlOpts[ctlPathMTU].parse(cm, m.Data(l))
+               }
+       }
+       return nil
+}
+
+// NewControlMessage returns a new control message.
+//
+// The returned message is large enough for options specified by cf.
+func NewControlMessage(cf ControlFlags) []byte {
+       opt := rawOpt{cflags: cf}
+       var l int
+       if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 {
+               l += socket.ControlMessageSpace(ctlOpts[ctlTrafficClass].length)
+       }
+       if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 {
+               l += socket.ControlMessageSpace(ctlOpts[ctlHopLimit].length)
+       }
+       if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 {
+               l += socket.ControlMessageSpace(ctlOpts[ctlPacketInfo].length)
+       }
+       if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 {
+               l += socket.ControlMessageSpace(ctlOpts[ctlPathMTU].length)
+       }
+       var b []byte
+       if l > 0 {
+               b = make([]byte, l)
+       }
+       return b
+}
+
 // Ancillary data socket options
 const (
        ctlTrafficClass = iota // header field
index 80ec2e2f0bd2b3610180d0d72d55e4dcfd0cae46..9fd9eb15e3bc4f2d946b6059f5cff3e162fc03ea 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -7,31 +7,26 @@
 package ipv6
 
 import (
-       "syscall"
        "unsafe"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
 func marshal2292HopLimit(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIPv6
-       m.Type = sysIPV6_2292HOPLIMIT
-       m.SetLen(syscall.CmsgLen(4))
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_2292HOPLIMIT, 4)
        if cm != nil {
-               data := b[syscall.CmsgLen(0):]
-               nativeEndian.PutUint32(data[:4], uint32(cm.HopLimit))
+               socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.HopLimit))
        }
-       return b[syscall.CmsgSpace(4):]
+       return m.Next(4)
 }
 
 func marshal2292PacketInfo(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIPv6
-       m.Type = sysIPV6_2292PKTINFO
-       m.SetLen(syscall.CmsgLen(sysSizeofInet6Pktinfo))
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_2292PKTINFO, sizeofInet6Pktinfo)
        if cm != nil {
-               pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
+               pi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))
                if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
                        copy(pi.Addr[:], ip)
                }
@@ -39,17 +34,15 @@ func marshal2292PacketInfo(b []byte, cm *ControlMessage) []byte {
                        pi.setIfindex(cm.IfIndex)
                }
        }
-       return b[syscall.CmsgSpace(sysSizeofInet6Pktinfo):]
+       return m.Next(sizeofInet6Pktinfo)
 }
 
 func marshal2292NextHop(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIPv6
-       m.Type = sysIPV6_2292NEXTHOP
-       m.SetLen(syscall.CmsgLen(sysSizeofSockaddrInet6))
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_2292NEXTHOP, sizeofSockaddrInet6)
        if cm != nil {
-               sa := (*sysSockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
+               sa := (*sockaddrInet6)(unsafe.Pointer(&m.Data(sizeofSockaddrInet6)[0]))
                sa.setSockaddr(cm.NextHop, cm.IfIndex)
        }
-       return b[syscall.CmsgSpace(sysSizeofSockaddrInet6):]
+       return m.Next(sizeofSockaddrInet6)
 }
index f344d16d039f724e814e34d1ec1866e0268ddb55..eec529c205e53fe76797bb491e0e160126a3c12c 100644 (file)
@@ -1,57 +1,50 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv6
 
 import (
-       "syscall"
+       "net"
        "unsafe"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
 func marshalTrafficClass(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIPv6
-       m.Type = sysIPV6_TCLASS
-       m.SetLen(syscall.CmsgLen(4))
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_TCLASS, 4)
        if cm != nil {
-               data := b[syscall.CmsgLen(0):]
-               nativeEndian.PutUint32(data[:4], uint32(cm.TrafficClass))
+               socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.TrafficClass))
        }
-       return b[syscall.CmsgSpace(4):]
+       return m.Next(4)
 }
 
 func parseTrafficClass(cm *ControlMessage, b []byte) {
-       cm.TrafficClass = int(nativeEndian.Uint32(b[:4]))
+       cm.TrafficClass = int(socket.NativeEndian.Uint32(b[:4]))
 }
 
 func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIPv6
-       m.Type = sysIPV6_HOPLIMIT
-       m.SetLen(syscall.CmsgLen(4))
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_HOPLIMIT, 4)
        if cm != nil {
-               data := b[syscall.CmsgLen(0):]
-               nativeEndian.PutUint32(data[:4], uint32(cm.HopLimit))
+               socket.NativeEndian.PutUint32(m.Data(4), uint32(cm.HopLimit))
        }
-       return b[syscall.CmsgSpace(4):]
+       return m.Next(4)
 }
 
 func parseHopLimit(cm *ControlMessage, b []byte) {
-       cm.HopLimit = int(nativeEndian.Uint32(b[:4]))
+       cm.HopLimit = int(socket.NativeEndian.Uint32(b[:4]))
 }
 
 func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIPv6
-       m.Type = sysIPV6_PKTINFO
-       m.SetLen(syscall.CmsgLen(sysSizeofInet6Pktinfo))
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_PKTINFO, sizeofInet6Pktinfo)
        if cm != nil {
-               pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
+               pi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))
                if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
                        copy(pi.Addr[:], ip)
                }
@@ -59,41 +52,43 @@ func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
                        pi.setIfindex(cm.IfIndex)
                }
        }
-       return b[syscall.CmsgSpace(sysSizeofInet6Pktinfo):]
+       return m.Next(sizeofInet6Pktinfo)
 }
 
 func parsePacketInfo(cm *ControlMessage, b []byte) {
-       pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[0]))
-       cm.Dst = pi.Addr[:]
+       pi := (*inet6Pktinfo)(unsafe.Pointer(&b[0]))
+       if len(cm.Dst) < net.IPv6len {
+               cm.Dst = make(net.IP, net.IPv6len)
+       }
+       copy(cm.Dst, pi.Addr[:])
        cm.IfIndex = int(pi.Ifindex)
 }
 
 func marshalNextHop(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIPv6
-       m.Type = sysIPV6_NEXTHOP
-       m.SetLen(syscall.CmsgLen(sysSizeofSockaddrInet6))
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_NEXTHOP, sizeofSockaddrInet6)
        if cm != nil {
-               sa := (*sysSockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
+               sa := (*sockaddrInet6)(unsafe.Pointer(&m.Data(sizeofSockaddrInet6)[0]))
                sa.setSockaddr(cm.NextHop, cm.IfIndex)
        }
-       return b[syscall.CmsgSpace(sysSizeofSockaddrInet6):]
+       return m.Next(sizeofSockaddrInet6)
 }
 
 func parseNextHop(cm *ControlMessage, b []byte) {
 }
 
 func marshalPathMTU(b []byte, cm *ControlMessage) []byte {
-       m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
-       m.Level = iana.ProtocolIPv6
-       m.Type = sysIPV6_PATHMTU
-       m.SetLen(syscall.CmsgLen(sysSizeofIPv6Mtuinfo))
-       return b[syscall.CmsgSpace(sysSizeofIPv6Mtuinfo):]
+       m := socket.ControlMessage(b)
+       m.MarshalHeader(iana.ProtocolIPv6, sysIPV6_PATHMTU, sizeofIPv6Mtuinfo)
+       return m.Next(sizeofIPv6Mtuinfo)
 }
 
 func parsePathMTU(cm *ControlMessage, b []byte) {
-       mi := (*sysIPv6Mtuinfo)(unsafe.Pointer(&b[0]))
-       cm.Dst = mi.Addr.Addr[:]
+       mi := (*ipv6Mtuinfo)(unsafe.Pointer(&b[0]))
+       if len(cm.Dst) < net.IPv6len {
+               cm.Dst = make(net.IP, net.IPv6len)
+       }
+       copy(cm.Dst, mi.Addr.Addr[:])
        cm.IfIndex = int(mi.Addr.Scope_id)
        cm.MTU = int(mi.Mtu)
 }
index 2fecf7e5ce480b9c2106b9192ebd7b10c35c9157..a045f28f74c9d61105a881e2ecfea3b01e054bf2 100644 (file)
@@ -1,23 +1,13 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 nacl plan9 solaris
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv6
 
-func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
-       return errOpNoSupport
-}
-
-func newControlMessage(opt *rawOpt) (oob []byte) {
-       return nil
-}
+import "golang.org/x/net/internal/socket"
 
-func parseControlMessage(b []byte) (*ControlMessage, error) {
-       return nil, errOpNoSupport
-}
-
-func marshalControlMessage(cm *ControlMessage) (oob []byte) {
-       return nil
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
+       return errOpNoSupport
 }
index 2af5beb43e14092e575777bfbe5f412496ba12c5..66515060a88dfe000778d207d724c59c152d57c2 100644 (file)
@@ -1,23 +1,18 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv6
 
-import (
-       "os"
-       "syscall"
+import "golang.org/x/net/internal/socket"
 
-       "golang.org/x/net/internal/iana"
-)
-
-func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
        opt.Lock()
        defer opt.Unlock()
-       if cf&FlagTrafficClass != 0 && sockOpts[ssoReceiveTrafficClass].name > 0 {
-               if err := setInt(fd, &sockOpts[ssoReceiveTrafficClass], boolint(on)); err != nil {
+       if so, ok := sockOpts[ssoReceiveTrafficClass]; ok && cf&FlagTrafficClass != 0 {
+               if err := so.SetInt(c, boolint(on)); err != nil {
                        return err
                }
                if on {
@@ -26,8 +21,8 @@ func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
                        opt.clear(FlagTrafficClass)
                }
        }
-       if cf&FlagHopLimit != 0 && sockOpts[ssoReceiveHopLimit].name > 0 {
-               if err := setInt(fd, &sockOpts[ssoReceiveHopLimit], boolint(on)); err != nil {
+       if so, ok := sockOpts[ssoReceiveHopLimit]; ok && cf&FlagHopLimit != 0 {
+               if err := so.SetInt(c, boolint(on)); err != nil {
                        return err
                }
                if on {
@@ -36,8 +31,8 @@ func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
                        opt.clear(FlagHopLimit)
                }
        }
-       if cf&flagPacketInfo != 0 && sockOpts[ssoReceivePacketInfo].name > 0 {
-               if err := setInt(fd, &sockOpts[ssoReceivePacketInfo], boolint(on)); err != nil {
+       if so, ok := sockOpts[ssoReceivePacketInfo]; ok && cf&flagPacketInfo != 0 {
+               if err := so.SetInt(c, boolint(on)); err != nil {
                        return err
                }
                if on {
@@ -46,8 +41,8 @@ func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
                        opt.clear(cf & flagPacketInfo)
                }
        }
-       if cf&FlagPathMTU != 0 && sockOpts[ssoReceivePathMTU].name > 0 {
-               if err := setInt(fd, &sockOpts[ssoReceivePathMTU], boolint(on)); err != nil {
+       if so, ok := sockOpts[ssoReceivePathMTU]; ok && cf&FlagPathMTU != 0 {
+               if err := so.SetInt(c, boolint(on)); err != nil {
                        return err
                }
                if on {
@@ -58,109 +53,3 @@ func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
        }
        return nil
 }
-
-func newControlMessage(opt *rawOpt) (oob []byte) {
-       opt.RLock()
-       var l int
-       if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 {
-               l += syscall.CmsgSpace(ctlOpts[ctlTrafficClass].length)
-       }
-       if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 {
-               l += syscall.CmsgSpace(ctlOpts[ctlHopLimit].length)
-       }
-       if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 {
-               l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
-       }
-       if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 {
-               l += syscall.CmsgSpace(ctlOpts[ctlPathMTU].length)
-       }
-       if l > 0 {
-               oob = make([]byte, l)
-               b := oob
-               if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 {
-                       b = ctlOpts[ctlTrafficClass].marshal(b, nil)
-               }
-               if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 {
-                       b = ctlOpts[ctlHopLimit].marshal(b, nil)
-               }
-               if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 {
-                       b = ctlOpts[ctlPacketInfo].marshal(b, nil)
-               }
-               if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 {
-                       b = ctlOpts[ctlPathMTU].marshal(b, nil)
-               }
-       }
-       opt.RUnlock()
-       return
-}
-
-func parseControlMessage(b []byte) (*ControlMessage, error) {
-       if len(b) == 0 {
-               return nil, nil
-       }
-       cmsgs, err := syscall.ParseSocketControlMessage(b)
-       if err != nil {
-               return nil, os.NewSyscallError("parse socket control message", err)
-       }
-       cm := &ControlMessage{}
-       for _, m := range cmsgs {
-               if m.Header.Level != iana.ProtocolIPv6 {
-                       continue
-               }
-               switch int(m.Header.Type) {
-               case ctlOpts[ctlTrafficClass].name:
-                       ctlOpts[ctlTrafficClass].parse(cm, m.Data[:])
-               case ctlOpts[ctlHopLimit].name:
-                       ctlOpts[ctlHopLimit].parse(cm, m.Data[:])
-               case ctlOpts[ctlPacketInfo].name:
-                       ctlOpts[ctlPacketInfo].parse(cm, m.Data[:])
-               case ctlOpts[ctlPathMTU].name:
-                       ctlOpts[ctlPathMTU].parse(cm, m.Data[:])
-               }
-       }
-       return cm, nil
-}
-
-func marshalControlMessage(cm *ControlMessage) (oob []byte) {
-       if cm == nil {
-               return
-       }
-       var l int
-       tclass := false
-       if ctlOpts[ctlTrafficClass].name > 0 && cm.TrafficClass > 0 {
-               tclass = true
-               l += syscall.CmsgSpace(ctlOpts[ctlTrafficClass].length)
-       }
-       hoplimit := false
-       if ctlOpts[ctlHopLimit].name > 0 && cm.HopLimit > 0 {
-               hoplimit = true
-               l += syscall.CmsgSpace(ctlOpts[ctlHopLimit].length)
-       }
-       pktinfo := false
-       if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To16() != nil && cm.Src.To4() == nil || cm.IfIndex > 0) {
-               pktinfo = true
-               l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
-       }
-       nexthop := false
-       if ctlOpts[ctlNextHop].name > 0 && cm.NextHop.To16() != nil && cm.NextHop.To4() == nil {
-               nexthop = true
-               l += syscall.CmsgSpace(ctlOpts[ctlNextHop].length)
-       }
-       if l > 0 {
-               oob = make([]byte, l)
-               b := oob
-               if tclass {
-                       b = ctlOpts[ctlTrafficClass].marshal(b, cm)
-               }
-               if hoplimit {
-                       b = ctlOpts[ctlHopLimit].marshal(b, cm)
-               }
-               if pktinfo {
-                       b = ctlOpts[ctlPacketInfo].marshal(b, cm)
-               }
-               if nexthop {
-                       b = ctlOpts[ctlNextHop].marshal(b, cm)
-               }
-       }
-       return
-}
index 72fdc1b0382ea5c6d111c0e6e87b679cbbc41de1..ef2563b3fc6023bb70f97c0e642313b4053b71f8 100644 (file)
@@ -1,27 +1,16 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 ipv6
 
-import "syscall"
+import (
+       "syscall"
 
-func setControlMessage(fd syscall.Handle, opt *rawOpt, cf ControlFlags, on bool) error {
-       // TODO(mikio): implement this
-       return syscall.EWINDOWS
-}
-
-func newControlMessage(opt *rawOpt) (oob []byte) {
-       // TODO(mikio): implement this
-       return nil
-}
+       "golang.org/x/net/internal/socket"
+)
 
-func parseControlMessage(b []byte) (*ControlMessage, error) {
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
        // TODO(mikio): implement this
-       return nil, syscall.EWINDOWS
-}
-
-func marshalControlMessage(cm *ControlMessage) (oob []byte) {
-       // TODO(mikio): implement this
-       return nil
+       return syscall.EWINDOWS
 }
index 4c7f476a8d1380bfec94caa8aee0db1e5c84f383..55ddc116fc0703a6336e34e983a545ab26a7e0b6 100644 (file)
@@ -83,30 +83,30 @@ const (
        sysIPV6_PORTRANGE_HIGH    = C.IPV6_PORTRANGE_HIGH
        sysIPV6_PORTRANGE_LOW     = C.IPV6_PORTRANGE_LOW
 
-       sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
-       sysSizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
-       sysSizeofInet6Pktinfo    = C.sizeof_struct_in6_pktinfo
-       sysSizeofIPv6Mtuinfo     = C.sizeof_struct_ip6_mtuinfo
+       sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
+       sizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
+       sizeofInet6Pktinfo    = C.sizeof_struct_in6_pktinfo
+       sizeofIPv6Mtuinfo     = C.sizeof_struct_ip6_mtuinfo
 
-       sysSizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
-       sysSizeofGroupReq       = C.sizeof_struct_group_req
-       sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
+       sizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
+       sizeofGroupReq       = C.sizeof_struct_group_req
+       sizeofGroupSourceReq = C.sizeof_struct_group_source_req
 
-       sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
+       sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
 )
 
-type sysSockaddrStorage C.struct_sockaddr_storage
+type sockaddrStorage C.struct_sockaddr_storage
 
-type sysSockaddrInet6 C.struct_sockaddr_in6
+type sockaddrInet6 C.struct_sockaddr_in6
 
-type sysInet6Pktinfo C.struct_in6_pktinfo
+type inet6Pktinfo C.struct_in6_pktinfo
 
-type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
+type ipv6Mtuinfo C.struct_ip6_mtuinfo
 
-type sysIPv6Mreq C.struct_ipv6_mreq
+type ipv6Mreq C.struct_ipv6_mreq
 
-type sysICMPv6Filter C.struct_icmp6_filter
+type icmpv6Filter C.struct_icmp6_filter
 
-type sysGroupReq C.struct_group_req
+type groupReq C.struct_group_req
 
-type sysGroupSourceReq C.struct_group_source_req
+type groupSourceReq C.struct_group_source_req
index c72487ceb7aecc740d15a3acc3ddfefcd36b3380..a4c383a5155c45b7aa86a08447101fb74364bee0 100644 (file)
@@ -64,21 +64,21 @@ const (
        sysIPV6_PORTRANGE_HIGH    = C.IPV6_PORTRANGE_HIGH
        sysIPV6_PORTRANGE_LOW     = C.IPV6_PORTRANGE_LOW
 
-       sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
-       sysSizeofInet6Pktinfo  = C.sizeof_struct_in6_pktinfo
-       sysSizeofIPv6Mtuinfo   = C.sizeof_struct_ip6_mtuinfo
+       sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
+       sizeofInet6Pktinfo  = C.sizeof_struct_in6_pktinfo
+       sizeofIPv6Mtuinfo   = C.sizeof_struct_ip6_mtuinfo
 
-       sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
+       sizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
 
-       sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
+       sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
 )
 
-type sysSockaddrInet6 C.struct_sockaddr_in6
+type sockaddrInet6 C.struct_sockaddr_in6
 
-type sysInet6Pktinfo C.struct_in6_pktinfo
+type inet6Pktinfo C.struct_in6_pktinfo
 
-type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
+type ipv6Mtuinfo C.struct_ip6_mtuinfo
 
-type sysIPv6Mreq C.struct_ipv6_mreq
+type ipv6Mreq C.struct_ipv6_mreq
 
-type sysICMPv6Filter C.struct_icmp6_filter
+type icmpv6Filter C.struct_icmp6_filter
index de199ec6a7f10cf7e439ac2da6d73a0a4e0ead91..53e625389aeaa5a4ebfa83f5b2bd1335be0612c0 100644 (file)
@@ -76,30 +76,30 @@ const (
        sysIPV6_PORTRANGE_HIGH    = C.IPV6_PORTRANGE_HIGH
        sysIPV6_PORTRANGE_LOW     = C.IPV6_PORTRANGE_LOW
 
-       sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
-       sysSizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
-       sysSizeofInet6Pktinfo    = C.sizeof_struct_in6_pktinfo
-       sysSizeofIPv6Mtuinfo     = C.sizeof_struct_ip6_mtuinfo
+       sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
+       sizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
+       sizeofInet6Pktinfo    = C.sizeof_struct_in6_pktinfo
+       sizeofIPv6Mtuinfo     = C.sizeof_struct_ip6_mtuinfo
 
-       sysSizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
-       sysSizeofGroupReq       = C.sizeof_struct_group_req
-       sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
+       sizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
+       sizeofGroupReq       = C.sizeof_struct_group_req
+       sizeofGroupSourceReq = C.sizeof_struct_group_source_req
 
-       sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
+       sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
 )
 
-type sysSockaddrStorage C.struct_sockaddr_storage
+type sockaddrStorage C.struct_sockaddr_storage
 
-type sysSockaddrInet6 C.struct_sockaddr_in6
+type sockaddrInet6 C.struct_sockaddr_in6
 
-type sysInet6Pktinfo C.struct_in6_pktinfo
+type inet6Pktinfo C.struct_in6_pktinfo
 
-type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
+type ipv6Mtuinfo C.struct_ip6_mtuinfo
 
-type sysIPv6Mreq C.struct_ipv6_mreq
+type ipv6Mreq C.struct_ipv6_mreq
 
-type sysGroupReq C.struct_group_req
+type groupReq C.struct_group_req
 
-type sysGroupSourceReq C.struct_group_source_req
+type groupSourceReq C.struct_group_source_req
 
-type sysICMPv6Filter C.struct_icmp6_filter
+type icmpv6Filter C.struct_icmp6_filter
index d83abce35f465c10eaa4eb3f8dc30c9c58810345..3308cb2c38642a307ecc835808bdab8dcf97de80 100644 (file)
@@ -13,6 +13,8 @@ package ipv6
 #include <linux/in6.h>
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
+#include <linux/filter.h>
+#include <sys/socket.h>
 */
 import "C"
 
@@ -104,33 +106,42 @@ const (
        sysICMPV6_FILTER_BLOCKOTHERS = C.ICMPV6_FILTER_BLOCKOTHERS
        sysICMPV6_FILTER_PASSONLY    = C.ICMPV6_FILTER_PASSONLY
 
-       sysSizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage
-       sysSizeofSockaddrInet6         = C.sizeof_struct_sockaddr_in6
-       sysSizeofInet6Pktinfo          = C.sizeof_struct_in6_pktinfo
-       sysSizeofIPv6Mtuinfo           = C.sizeof_struct_ip6_mtuinfo
-       sysSizeofIPv6FlowlabelReq      = C.sizeof_struct_in6_flowlabel_req
+       sysSOL_SOCKET       = C.SOL_SOCKET
+       sysSO_ATTACH_FILTER = C.SO_ATTACH_FILTER
 
-       sysSizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
-       sysSizeofGroupReq       = C.sizeof_struct_group_req
-       sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req
+       sizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage
+       sizeofSockaddrInet6         = C.sizeof_struct_sockaddr_in6
+       sizeofInet6Pktinfo          = C.sizeof_struct_in6_pktinfo
+       sizeofIPv6Mtuinfo           = C.sizeof_struct_ip6_mtuinfo
+       sizeofIPv6FlowlabelReq      = C.sizeof_struct_in6_flowlabel_req
 
-       sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
+       sizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
+       sizeofGroupReq       = C.sizeof_struct_group_req
+       sizeofGroupSourceReq = C.sizeof_struct_group_source_req
+
+       sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
+
+       sizeofSockFprog = C.sizeof_struct_sock_fprog
 )
 
-type sysKernelSockaddrStorage C.struct___kernel_sockaddr_storage
+type kernelSockaddrStorage C.struct___kernel_sockaddr_storage
+
+type sockaddrInet6 C.struct_sockaddr_in6
+
+type inet6Pktinfo C.struct_in6_pktinfo
 
-type sysSockaddrInet6 C.struct_sockaddr_in6
+type ipv6Mtuinfo C.struct_ip6_mtuinfo
 
-type sysInet6Pktinfo C.struct_in6_pktinfo
+type ipv6FlowlabelReq C.struct_in6_flowlabel_req
 
-type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
+type ipv6Mreq C.struct_ipv6_mreq
 
-type sysIPv6FlowlabelReq C.struct_in6_flowlabel_req
+type groupReq C.struct_group_req
 
-type sysIPv6Mreq C.struct_ipv6_mreq
+type groupSourceReq C.struct_group_source_req
 
-type sysGroupReq C.struct_group_req
+type icmpv6Filter C.struct_icmp6_filter
 
-type sysGroupSourceReq C.struct_group_source_req
+type sockFProg C.struct_sock_fprog
 
-type sysICMPv6Filter C.struct_icmp6_filter
+type sockFilter C.struct_sock_filter
index 7bd09e8e88399d7e77cffba1d389a54639c262cf..be9ceb9cc0675a2c618f41105daec2bd16ca8e31 100644 (file)
@@ -60,21 +60,21 @@ const (
        sysIPV6_PORTRANGE_HIGH    = C.IPV6_PORTRANGE_HIGH
        sysIPV6_PORTRANGE_LOW     = C.IPV6_PORTRANGE_LOW
 
-       sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
-       sysSizeofInet6Pktinfo  = C.sizeof_struct_in6_pktinfo
-       sysSizeofIPv6Mtuinfo   = C.sizeof_struct_ip6_mtuinfo
+       sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
+       sizeofInet6Pktinfo  = C.sizeof_struct_in6_pktinfo
+       sizeofIPv6Mtuinfo   = C.sizeof_struct_ip6_mtuinfo
 
-       sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
+       sizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
 
-       sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
+       sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
 )
 
-type sysSockaddrInet6 C.struct_sockaddr_in6
+type sockaddrInet6 C.struct_sockaddr_in6
 
-type sysInet6Pktinfo C.struct_in6_pktinfo
+type inet6Pktinfo C.struct_in6_pktinfo
 
-type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
+type ipv6Mtuinfo C.struct_ip6_mtuinfo
 
-type sysIPv6Mreq C.struct_ipv6_mreq
+type ipv6Mreq C.struct_ipv6_mreq
 
-type sysICMPv6Filter C.struct_icmp6_filter
+type icmpv6Filter C.struct_icmp6_filter
index 6796d9b2f52eeb3923c69e4fda2f67f4de6ddde9..177ddf87d2c76e95de200a9d0afc916345d073a2 100644 (file)
@@ -69,21 +69,21 @@ const (
        sysIPV6_PORTRANGE_HIGH    = C.IPV6_PORTRANGE_HIGH
        sysIPV6_PORTRANGE_LOW     = C.IPV6_PORTRANGE_LOW
 
-       sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
-       sysSizeofInet6Pktinfo  = C.sizeof_struct_in6_pktinfo
-       sysSizeofIPv6Mtuinfo   = C.sizeof_struct_ip6_mtuinfo
+       sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
+       sizeofInet6Pktinfo  = C.sizeof_struct_in6_pktinfo
+       sizeofIPv6Mtuinfo   = C.sizeof_struct_ip6_mtuinfo
 
-       sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
+       sizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
 
-       sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
+       sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
 )
 
-type sysSockaddrInet6 C.struct_sockaddr_in6
+type sockaddrInet6 C.struct_sockaddr_in6
 
-type sysInet6Pktinfo C.struct_in6_pktinfo
+type inet6Pktinfo C.struct_in6_pktinfo
 
-type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
+type ipv6Mtuinfo C.struct_ip6_mtuinfo
 
-type sysIPv6Mreq C.struct_ipv6_mreq
+type ipv6Mreq C.struct_ipv6_mreq
 
-type sysICMPv6Filter C.struct_icmp6_filter
+type icmpv6Filter C.struct_icmp6_filter
index 972b171260f7529e8f2ccabd640cfb8c6d379f47..0f8ce2b46ae4605a9d2819ad22e2d11eadfa8bf8 100644 (file)
@@ -9,6 +9,8 @@
 package ipv6
 
 /*
+#include <sys/socket.h>
+
 #include <netinet/in.h>
 #include <netinet/icmp6.h>
 */
@@ -53,6 +55,13 @@ const (
 
        sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS
 
+       sysMCAST_JOIN_GROUP         = C.MCAST_JOIN_GROUP
+       sysMCAST_LEAVE_GROUP        = C.MCAST_LEAVE_GROUP
+       sysMCAST_BLOCK_SOURCE       = C.MCAST_BLOCK_SOURCE
+       sysMCAST_UNBLOCK_SOURCE     = C.MCAST_UNBLOCK_SOURCE
+       sysMCAST_JOIN_SOURCE_GROUP  = C.MCAST_JOIN_SOURCE_GROUP
+       sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP
+
        sysIPV6_PREFER_SRC_HOME   = C.IPV6_PREFER_SRC_HOME
        sysIPV6_PREFER_SRC_COA    = C.IPV6_PREFER_SRC_COA
        sysIPV6_PREFER_SRC_PUBLIC = C.IPV6_PREFER_SRC_PUBLIC
@@ -76,21 +85,30 @@ const (
 
        sysICMP6_FILTER = C.ICMP6_FILTER
 
-       sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
-       sysSizeofInet6Pktinfo  = C.sizeof_struct_in6_pktinfo
-       sysSizeofIPv6Mtuinfo   = C.sizeof_struct_ip6_mtuinfo
+       sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
+       sizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
+       sizeofInet6Pktinfo    = C.sizeof_struct_in6_pktinfo
+       sizeofIPv6Mtuinfo     = C.sizeof_struct_ip6_mtuinfo
 
-       sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
+       sizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
+       sizeofGroupReq       = C.sizeof_struct_group_req
+       sizeofGroupSourceReq = C.sizeof_struct_group_source_req
 
-       sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
+       sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
 )
 
-type sysSockaddrInet6 C.struct_sockaddr_in6
+type sockaddrStorage C.struct_sockaddr_storage
+
+type sockaddrInet6 C.struct_sockaddr_in6
+
+type inet6Pktinfo C.struct_in6_pktinfo
+
+type ipv6Mtuinfo C.struct_ip6_mtuinfo
 
-type sysInet6Pktinfo C.struct_in6_pktinfo
+type ipv6Mreq C.struct_ipv6_mreq
 
-type sysIPv6Mtuinfo C.struct_ip6_mtuinfo
+type groupReq C.struct_group_req
 
-type sysIPv6Mreq C.struct_ipv6_mreq
+type groupSourceReq C.struct_group_source_req
 
-type sysICMPv6Filter C.struct_icmp6_filter
+type icmpv6Filter C.struct_icmp6_filter
diff --git a/vendor/golang.org/x/net/ipv6/dgramopt_posix.go b/vendor/golang.org/x/net/ipv6/dgramopt_posix.go
deleted file mode 100644 (file)
index 93ff2f1..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2013 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 darwin dragonfly freebsd linux netbsd openbsd windows
-
-package ipv6
-
-import (
-       "net"
-       "syscall"
-)
-
-// MulticastHopLimit returns the hop limit field value for outgoing
-// multicast packets.
-func (c *dgramOpt) MulticastHopLimit() (int, error) {
-       if !c.ok() {
-               return 0, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return 0, err
-       }
-       return getInt(fd, &sockOpts[ssoMulticastHopLimit])
-}
-
-// SetMulticastHopLimit sets the hop limit field value for future
-// outgoing multicast packets.
-func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInt(fd, &sockOpts[ssoMulticastHopLimit], hoplim)
-}
-
-// MulticastInterface returns the default interface for multicast
-// packet transmissions.
-func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
-       if !c.ok() {
-               return nil, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return nil, err
-       }
-       return getInterface(fd, &sockOpts[ssoMulticastInterface])
-}
-
-// SetMulticastInterface sets the default interface for future
-// multicast packet transmissions.
-func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInterface(fd, &sockOpts[ssoMulticastInterface], ifi)
-}
-
-// MulticastLoopback reports whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) MulticastLoopback() (bool, error) {
-       if !c.ok() {
-               return false, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return false, err
-       }
-       on, err := getInt(fd, &sockOpts[ssoMulticastLoopback])
-       if err != nil {
-               return false, err
-       }
-       return on == 1, nil
-}
-
-// SetMulticastLoopback sets whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) SetMulticastLoopback(on bool) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInt(fd, &sockOpts[ssoMulticastLoopback], boolint(on))
-}
-
-// JoinGroup joins the group address group on the interface ifi.
-// By default all sources that can cast data to group are accepted.
-// It's possible to mute and unmute data transmission from a specific
-// source by using ExcludeSourceSpecificGroup and
-// IncludeSourceSpecificGroup.
-// JoinGroup uses the system assigned multicast interface when ifi is
-// nil, although this is not recommended because the assignment
-// depends on platforms and sometimes it might require routing
-// configuration.
-func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP16(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       return setGroup(fd, &sockOpts[ssoJoinGroup], ifi, grp)
-}
-
-// LeaveGroup leaves the group address group on the interface ifi
-// regardless of whether the group is any-source group or
-// source-specific group.
-func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP16(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       return setGroup(fd, &sockOpts[ssoLeaveGroup], ifi, grp)
-}
-
-// JoinSourceSpecificGroup joins the source-specific group comprising
-// group and source on the interface ifi.
-// JoinSourceSpecificGroup uses the system assigned multicast
-// interface when ifi is nil, although this is not recommended because
-// the assignment depends on platforms and sometimes it might require
-// routing configuration.
-func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP16(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       src := netAddrToIP16(source)
-       if src == nil {
-               return errMissingAddress
-       }
-       return setSourceGroup(fd, &sockOpts[ssoJoinSourceGroup], ifi, grp, src)
-}
-
-// LeaveSourceSpecificGroup leaves the source-specific group on the
-// interface ifi.
-func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP16(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       src := netAddrToIP16(source)
-       if src == nil {
-               return errMissingAddress
-       }
-       return setSourceGroup(fd, &sockOpts[ssoLeaveSourceGroup], ifi, grp, src)
-}
-
-// ExcludeSourceSpecificGroup excludes the source-specific group from
-// the already joined any-source groups by JoinGroup on the interface
-// ifi.
-func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP16(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       src := netAddrToIP16(source)
-       if src == nil {
-               return errMissingAddress
-       }
-       return setSourceGroup(fd, &sockOpts[ssoBlockSourceGroup], ifi, grp, src)
-}
-
-// IncludeSourceSpecificGroup includes the excluded source-specific
-// group by ExcludeSourceSpecificGroup again on the interface ifi.
-func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       grp := netAddrToIP16(group)
-       if grp == nil {
-               return errMissingAddress
-       }
-       src := netAddrToIP16(source)
-       if src == nil {
-               return errMissingAddress
-       }
-       return setSourceGroup(fd, &sockOpts[ssoUnblockSourceGroup], ifi, grp, src)
-}
-
-// Checksum reports whether the kernel will compute, store or verify a
-// checksum for both incoming and outgoing packets.  If on is true, it
-// returns an offset in bytes into the data of where the checksum
-// field is located.
-func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
-       if !c.ok() {
-               return false, 0, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return false, 0, err
-       }
-       offset, err = getInt(fd, &sockOpts[ssoChecksum])
-       if err != nil {
-               return false, 0, err
-       }
-       if offset < 0 {
-               return false, 0, nil
-       }
-       return true, offset, nil
-}
-
-// SetChecksum enables the kernel checksum processing.  If on is ture,
-// the offset should be an offset in bytes into the data of where the
-// checksum field is located.
-func (c *dgramOpt) SetChecksum(on bool, offset int) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       if !on {
-               offset = -1
-       }
-       return setInt(fd, &sockOpts[ssoChecksum], offset)
-}
-
-// ICMPFilter returns an ICMP filter.
-func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
-       if !c.ok() {
-               return nil, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return nil, err
-       }
-       return getICMPFilter(fd, &sockOpts[ssoICMPFilter])
-}
-
-// SetICMPFilter deploys the ICMP filter.
-func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setICMPFilter(fd, &sockOpts[ssoICMPFilter], f)
-}
diff --git a/vendor/golang.org/x/net/ipv6/dgramopt_stub.go b/vendor/golang.org/x/net/ipv6/dgramopt_stub.go
deleted file mode 100644 (file)
index fb067fb..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2013 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 nacl plan9 solaris
-
-package ipv6
-
-import "net"
-
-// MulticastHopLimit returns the hop limit field value for outgoing
-// multicast packets.
-func (c *dgramOpt) MulticastHopLimit() (int, error) {
-       return 0, errOpNoSupport
-}
-
-// SetMulticastHopLimit sets the hop limit field value for future
-// outgoing multicast packets.
-func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
-       return errOpNoSupport
-}
-
-// MulticastInterface returns the default interface for multicast
-// packet transmissions.
-func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
-       return nil, errOpNoSupport
-}
-
-// SetMulticastInterface sets the default interface for future
-// multicast packet transmissions.
-func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
-       return errOpNoSupport
-}
-
-// MulticastLoopback reports whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) MulticastLoopback() (bool, error) {
-       return false, errOpNoSupport
-}
-
-// SetMulticastLoopback sets whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) SetMulticastLoopback(on bool) error {
-       return errOpNoSupport
-}
-
-// JoinGroup joins the group address group on the interface ifi.
-// By default all sources that can cast data to group are accepted.
-// It's possible to mute and unmute data transmission from a specific
-// source by using ExcludeSourceSpecificGroup and
-// IncludeSourceSpecificGroup.
-// JoinGroup uses the system assigned multicast interface when ifi is
-// nil, although this is not recommended because the assignment
-// depends on platforms and sometimes it might require routing
-// configuration.
-func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
-       return errOpNoSupport
-}
-
-// LeaveGroup leaves the group address group on the interface ifi
-// regardless of whether the group is any-source group or
-// source-specific group.
-func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
-       return errOpNoSupport
-}
-
-// JoinSourceSpecificGroup joins the source-specific group comprising
-// group and source on the interface ifi.
-// JoinSourceSpecificGroup uses the system assigned multicast
-// interface when ifi is nil, although this is not recommended because
-// the assignment depends on platforms and sometimes it might require
-// routing configuration.
-func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       return errOpNoSupport
-}
-
-// LeaveSourceSpecificGroup leaves the source-specific group on the
-// interface ifi.
-func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       return errOpNoSupport
-}
-
-// ExcludeSourceSpecificGroup excludes the source-specific group from
-// the already joined any-source groups by JoinGroup on the interface
-// ifi.
-func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       return errOpNoSupport
-}
-
-// IncludeSourceSpecificGroup includes the excluded source-specific
-// group by ExcludeSourceSpecificGroup again on the interface ifi.
-func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
-       return errOpNoSupport
-}
-
-// Checksum reports whether the kernel will compute, store or verify a
-// checksum for both incoming and outgoing packets.  If on is true, it
-// returns an offset in bytes into the data of where the checksum
-// field is located.
-func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
-       return false, 0, errOpNoSupport
-}
-
-// SetChecksum enables the kernel checksum processing.  If on is ture,
-// the offset should be an offset in bytes into the data of where the
-// checksum field is located.
-func (c *dgramOpt) SetChecksum(on bool, offset int) error {
-       return errOpNoSupport
-}
-
-// ICMPFilter returns an ICMP filter.
-func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
-       return nil, errOpNoSupport
-}
-
-// SetICMPFilter deploys the ICMP filter.
-func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
-       return errOpNoSupport
-}
index dd13aa21f86b729bf9dcd5e49d5c38a2a0b8b485..664a97dea17bc9caa57b41f8d0b2ece0174e9835 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -8,23 +8,24 @@
 // The package provides IP-level socket options that allow
 // manipulation of IPv6 facilities.
 //
-// The IPv6 protocol is defined in RFC 2460.
-// Basic and advanced socket interface extensions are defined in RFC
-// 3493 and RFC 3542.
-// Socket interface extensions for multicast source filters are
-// defined in RFC 3678.
+// The IPv6 protocol is defined in RFC 8200.
+// Socket interface extensions are defined in RFC 3493, RFC 3542 and
+// RFC 3678.
 // MLDv1 and MLDv2 are defined in RFC 2710 and RFC 3810.
 // Source-specific multicast is defined in RFC 4607.
 //
+// On Darwin, this package requires OS X Mavericks version 10.9 or
+// above, or equivalent.
+//
 //
 // Unicasting
 //
 // The options for unicasting are available for net.TCPConn,
 // net.UDPConn and net.IPConn which are created as network connections
-// that use the IPv6 transport.  When a single TCP connection carrying
+// 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 {
@@ -56,7 +57,7 @@
 //
 // The options for multicasting are available for net.UDPConn and
 // net.IPconn which are created as network connections that use the
-// IPv6 transport.  A few network facilities must be prepared before
+// IPv6 transport. A few network facilities must be prepared before
 // you begin multicasting, at a minimum joining network interfaces and
 // multicast groups.
 //
@@ -80,7 +81,7 @@
 //     defer c.Close()
 //
 // Second, the application joins multicast groups, starts listening to
-// the groups on the specified network interfaces.  Note that the
+// the groups on the specified network interfaces. Note that the
 // service port for transport layer protocol does not matter with this
 // operation as joining groups affects only network and link layer
 // protocols, such as IPv6 and Ethernet.
 //     }
 //
 // The application might set per packet control message transmissions
-// between the protocol stack within the kernel.  When the application
+// 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 transmissons.
+// SetControlMessage of PacketConn is used to enable control message
+// transmissions.
 //
 //     if err := p.SetControlMessage(ipv6.FlagDst, true); err != nil {
 //             // error handling
 // More multicasting
 //
 // An application that uses PacketConn may join multiple multicast
-// groups.  For example, a UDP listener with port 1024 might join two
+// groups. For example, a UDP listener with port 1024 might join two
 // different groups across over two different network interfaces by
 // using:
 //
 //     }
 //
 // It is possible for multiple UDP listeners that listen on the same
-// UDP port to join the same multicast group.  The net package will
+// UDP port to join the same multicast group. The net package will
 // provide a socket that listens to a wildcard address with reusable
 // UDP port when an appropriate multicast address prefix is passed to
 // the net.ListenPacket or net.ListenUDP.
 // 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.
index 966eaa8920dc59adbc9ec067b47cfc4f4055383b..0624c174048e74fc51a1570ccdb46cc9bd3287a1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -8,8 +8,15 @@ import (
        "net"
        "syscall"
        "time"
+
+       "golang.org/x/net/internal/socket"
 )
 
+// 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.
@@ -18,7 +25,7 @@ type Conn struct {
 }
 
 type genericOpt struct {
-       net.Conn
+       *socket.Conn
 }
 
 func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
@@ -26,14 +33,14 @@ func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
 // PathMTU returns a path MTU value for the destination associated
 // with the endpoint.
 func (c *Conn) PathMTU() (int, error) {
-       if !c.genericOpt.ok() {
+       if !c.ok() {
                return 0, syscall.EINVAL
        }
-       fd, err := c.genericOpt.sysfd()
-       if err != nil {
-               return 0, err
+       so, ok := sockOpts[ssoPathMTU]
+       if !ok {
+               return 0, errOpNoSupport
        }
-       _, mtu, err := getMTUInfo(fd, &sockOpts[ssoPathMTU])
+       _, mtu, err := so.getMTUInfo(c.Conn)
        if err != nil {
                return 0, err
        }
@@ -42,14 +49,15 @@ func (c *Conn) PathMTU() (int, error) {
 
 // NewConn returns a new Conn.
 func NewConn(c net.Conn) *Conn {
+       cc, _ := socket.NewConn(c)
        return &Conn{
-               genericOpt: genericOpt{Conn: c},
+               genericOpt: genericOpt{Conn: cc},
        }
 }
 
 // A PacketConn represents a packet network endpoint that uses IPv6
-// transport.  It is used to control several IP-level socket options
-// including IPv6 header manipulation.  It also provides datagram
+// transport. It is used to control several IP-level socket options
+// including IPv6 header manipulation. It also provides datagram
 // based network I/O methods specific to the IPv6 and higher layer
 // protocols such as OSPF, GRE, and UDP.
 type PacketConn struct {
@@ -59,10 +67,10 @@ type PacketConn struct {
 }
 
 type dgramOpt struct {
-       net.PacketConn
+       *socket.Conn
 }
 
-func (c *dgramOpt) ok() bool { return c != nil && c.PacketConn != nil }
+func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
 
 // SetControlMessage allows to receive the per packet basis IP-level
 // socket options.
@@ -70,11 +78,7 @@ func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
        if !c.payloadHandler.ok() {
                return syscall.EINVAL
        }
-       fd, err := c.payloadHandler.sysfd()
-       if err != nil {
-               return err
-       }
-       return setControlMessage(fd, &c.payloadHandler.rawOpt, cf, on)
+       return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
 }
 
 // SetDeadline sets the read and write deadlines associated with the
@@ -115,9 +119,10 @@ func (c *PacketConn) Close() error {
 // NewPacketConn returns a new PacketConn using c as its underlying
 // transport.
 func NewPacketConn(c net.PacketConn) *PacketConn {
+       cc, _ := socket.NewConn(c.(net.Conn))
        return &PacketConn{
-               genericOpt:     genericOpt{Conn: c.(net.Conn)},
-               dgramOpt:       dgramOpt{PacketConn: c},
-               payloadHandler: payloadHandler{PacketConn: c},
+               genericOpt:     genericOpt{Conn: cc},
+               dgramOpt:       dgramOpt{Conn: cc},
+               payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
        }
 }
index b1e0ea37836dd01a75034fc83e8255b0012df3fe..41886ec72189f3dff6f583bf7f817bdc0d6cfdc0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -52,15 +52,6 @@ func genzsys() error {
        if err != nil {
                return err
        }
-       // The ipv6 pacakge still supports go1.2, and so we need to
-       // take care of additional platforms in go1.3 and above for
-       // working with go1.2.
-       switch {
-       case runtime.GOOS == "dragonfly" || runtime.GOOS == "solaris":
-               b = bytes.Replace(b, []byte("package ipv6\n"), []byte("// +build "+runtime.GOOS+"\n\npackage ipv6\n"), 1)
-       case runtime.GOOS == "linux" && (runtime.GOARCH == "arm64" || runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"):
-               b = bytes.Replace(b, []byte("package ipv6\n"), []byte("// +build "+runtime.GOOS+","+runtime.GOARCH+"\n\npackage ipv6\n"), 1)
-       }
        b, err = format.Source(b)
        if err != nil {
                return err
diff --git a/vendor/golang.org/x/net/ipv6/genericopt_posix.go b/vendor/golang.org/x/net/ipv6/genericopt_posix.go
deleted file mode 100644 (file)
index dd77a01..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2013 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 darwin dragonfly freebsd linux netbsd openbsd windows
-
-package ipv6
-
-import "syscall"
-
-// TrafficClass returns the traffic class field value for outgoing
-// packets.
-func (c *genericOpt) TrafficClass() (int, error) {
-       if !c.ok() {
-               return 0, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return 0, err
-       }
-       return getInt(fd, &sockOpts[ssoTrafficClass])
-}
-
-// SetTrafficClass sets the traffic class field value for future
-// outgoing packets.
-func (c *genericOpt) SetTrafficClass(tclass int) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInt(fd, &sockOpts[ssoTrafficClass], tclass)
-}
-
-// HopLimit returns the hop limit field value for outgoing packets.
-func (c *genericOpt) HopLimit() (int, error) {
-       if !c.ok() {
-               return 0, syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return 0, err
-       }
-       return getInt(fd, &sockOpts[ssoHopLimit])
-}
-
-// SetHopLimit sets the hop limit field value for future outgoing
-// packets.
-func (c *genericOpt) SetHopLimit(hoplim int) error {
-       if !c.ok() {
-               return syscall.EINVAL
-       }
-       fd, err := c.sysfd()
-       if err != nil {
-               return err
-       }
-       return setInt(fd, &sockOpts[ssoHopLimit], hoplim)
-}
diff --git a/vendor/golang.org/x/net/ipv6/genericopt_stub.go b/vendor/golang.org/x/net/ipv6/genericopt_stub.go
deleted file mode 100644 (file)
index f5c3722..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2013 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 nacl plan9 solaris
-
-package ipv6
-
-// TrafficClass returns the traffic class field value for outgoing
-// packets.
-func (c *genericOpt) TrafficClass() (int, error) {
-       return 0, errOpNoSupport
-}
-
-// SetTrafficClass sets the traffic class field value for future
-// outgoing packets.
-func (c *genericOpt) SetTrafficClass(tclass int) error {
-       return errOpNoSupport
-}
-
-// HopLimit returns the hop limit field value for outgoing packets.
-func (c *genericOpt) HopLimit() (int, error) {
-       return 0, errOpNoSupport
-}
-
-// SetHopLimit sets the hop limit field value for future outgoing
-// packets.
-func (c *genericOpt) SetHopLimit(hoplim int) error {
-       return errOpNoSupport
-}
index 53b99990587f6f934489a9939da7e769a8c985f6..259740132cb111a2a70ace3d5e3c9ab6b96c76af 100644 (file)
@@ -1,14 +1,12 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 ipv6
 
 import (
-       "encoding/binary"
        "errors"
        "net"
-       "unsafe"
 )
 
 var (
@@ -17,20 +15,8 @@ var (
        errInvalidConnType = errors.New("invalid conn type")
        errOpNoSupport     = errors.New("operation not supported")
        errNoSuchInterface = errors.New("no such interface")
-
-       nativeEndian binary.ByteOrder
 )
 
-func init() {
-       i := uint32(1)
-       b := (*[4]byte)(unsafe.Pointer(&i))
-       if b[0] == 1 {
-               nativeEndian = binary.LittleEndian
-       } else {
-               nativeEndian = binary.BigEndian
-       }
-}
-
 func boolint(b bool) int {
        if b {
                return 1
@@ -51,3 +37,21 @@ func netAddrToIP16(a net.Addr) net.IP {
        }
        return nil
 }
+
+func opAddr(a net.Addr) net.Addr {
+       switch a.(type) {
+       case *net.TCPAddr:
+               if a == nil {
+                       return nil
+               }
+       case *net.UDPAddr:
+               if a == nil {
+                       return nil
+               }
+       case *net.IPAddr:
+               if a == nil {
+                       return nil
+               }
+       }
+       return a
+}
diff --git a/vendor/golang.org/x/net/ipv6/helper_stub.go b/vendor/golang.org/x/net/ipv6/helper_stub.go
deleted file mode 100644 (file)
index 20354ab..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2013 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 nacl plan9 solaris
-
-package ipv6
-
-func (c *genericOpt) sysfd() (int, error) {
-       return 0, errOpNoSupport
-}
-
-func (c *dgramOpt) sysfd() (int, error) {
-       return 0, errOpNoSupport
-}
-
-func (c *payloadHandler) sysfd() (int, error) {
-       return 0, errOpNoSupport
-}
diff --git a/vendor/golang.org/x/net/ipv6/helper_unix.go b/vendor/golang.org/x/net/ipv6/helper_unix.go
deleted file mode 100644 (file)
index 92868ed..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 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 darwin dragonfly freebsd linux netbsd openbsd
-
-package ipv6
-
-import (
-       "net"
-       "reflect"
-)
-
-func (c *genericOpt) sysfd() (int, error) {
-       switch p := c.Conn.(type) {
-       case *net.TCPConn, *net.UDPConn, *net.IPConn:
-               return sysfd(p)
-       }
-       return 0, errInvalidConnType
-}
-
-func (c *dgramOpt) sysfd() (int, error) {
-       switch p := c.PacketConn.(type) {
-       case *net.UDPConn, *net.IPConn:
-               return sysfd(p.(net.Conn))
-       }
-       return 0, errInvalidConnType
-}
-
-func (c *payloadHandler) sysfd() (int, error) {
-       return sysfd(c.PacketConn.(net.Conn))
-}
-
-func sysfd(c net.Conn) (int, error) {
-       cv := reflect.ValueOf(c)
-       switch ce := cv.Elem(); ce.Kind() {
-       case reflect.Struct:
-               nfd := ce.FieldByName("conn").FieldByName("fd")
-               switch fe := nfd.Elem(); fe.Kind() {
-               case reflect.Struct:
-                       fd := fe.FieldByName("sysfd")
-                       return int(fd.Int()), nil
-               }
-       }
-       return 0, errInvalidConnType
-}
diff --git a/vendor/golang.org/x/net/ipv6/helper_windows.go b/vendor/golang.org/x/net/ipv6/helper_windows.go
deleted file mode 100644 (file)
index 28c401b..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 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 ipv6
-
-import (
-       "net"
-       "reflect"
-       "syscall"
-)
-
-func (c *genericOpt) sysfd() (syscall.Handle, error) {
-       switch p := c.Conn.(type) {
-       case *net.TCPConn, *net.UDPConn, *net.IPConn:
-               return sysfd(p)
-       }
-       return syscall.InvalidHandle, errInvalidConnType
-}
-
-func (c *dgramOpt) sysfd() (syscall.Handle, error) {
-       switch p := c.PacketConn.(type) {
-       case *net.UDPConn, *net.IPConn:
-               return sysfd(p.(net.Conn))
-       }
-       return syscall.InvalidHandle, errInvalidConnType
-}
-
-func (c *payloadHandler) sysfd() (syscall.Handle, error) {
-       return sysfd(c.PacketConn.(net.Conn))
-}
-
-func sysfd(c net.Conn) (syscall.Handle, error) {
-       cv := reflect.ValueOf(c)
-       switch ce := cv.Elem(); ce.Kind() {
-       case reflect.Struct:
-               netfd := ce.FieldByName("conn").FieldByName("fd")
-               switch fe := netfd.Elem(); fe.Kind() {
-               case reflect.Struct:
-                       fd := fe.FieldByName("sysfd")
-                       return syscall.Handle(fd.Uint()), nil
-               }
-       }
-       return syscall.InvalidHandle, errInvalidConnType
-}
index a2de65a08c1eaf2230517a3145e586b412d64291..b7f48e27b837ff8c9cbf7d4b576a4056e0c79dd6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -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
 
@@ -26,12 +29,12 @@ func (typ ICMPType) Protocol() int {
 // packets. The filter belongs to a packet delivery path on a host and
 // it cannot interact with forwarding packets or tunnel-outer packets.
 //
-// Note: RFC 2460 defines a reasonable role model. A node means a
+// Note: RFC 8200 defines a reasonable role model. A node means a
 // device that implements IP. A router means a node that forwards IP
 // packets not explicitly addressed to itself, and a host means a node
 // that is not a router.
 type ICMPFilter struct {
-       sysICMPv6Filter
+       icmpv6Filter
 }
 
 // Accept accepts incoming ICMP packets including the type field value
index 30e3ce424d0b191d0244e31244e548f8a773e1a5..e1a791de46ed342ded423cde640e777635eca402 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -6,15 +6,15 @@
 
 package ipv6
 
-func (f *sysICMPv6Filter) accept(typ ICMPType) {
+func (f *icmpv6Filter) accept(typ ICMPType) {
        f.Filt[typ>>5] |= 1 << (uint32(typ) & 31)
 }
 
-func (f *sysICMPv6Filter) block(typ ICMPType) {
+func (f *icmpv6Filter) block(typ ICMPType) {
        f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
 }
 
-func (f *sysICMPv6Filter) setAll(block bool) {
+func (f *icmpv6Filter) setAll(block bool) {
        for i := range f.Filt {
                if block {
                        f.Filt[i] = 0
@@ -24,6 +24,6 @@ func (f *sysICMPv6Filter) setAll(block bool) {
        }
 }
 
-func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
        return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
 }
index a67ecf690cd3f18e438e980921e5373bf8548ff9..647f6b44fff1a5b5fe988b79ee8fd7595e4f8c5f 100644 (file)
@@ -1,18 +1,18 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 ipv6
 
-func (f *sysICMPv6Filter) accept(typ ICMPType) {
+func (f *icmpv6Filter) accept(typ ICMPType) {
        f.Data[typ>>5] &^= 1 << (uint32(typ) & 31)
 }
 
-func (f *sysICMPv6Filter) block(typ ICMPType) {
+func (f *icmpv6Filter) block(typ ICMPType) {
        f.Data[typ>>5] |= 1 << (uint32(typ) & 31)
 }
 
-func (f *sysICMPv6Filter) setAll(block bool) {
+func (f *icmpv6Filter) setAll(block bool) {
        for i := range f.Data {
                if block {
                        f.Data[i] = 1<<32 - 1
@@ -22,6 +22,6 @@ func (f *sysICMPv6Filter) setAll(block bool) {
        }
 }
 
-func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
        return f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0
 }
index a942f354ca53dc25cdd3795b7f4408a7732e7715..7c23bb1cf6fdcdd99b07f01cded889531e773f9c 100644 (file)
@@ -1,24 +1,27 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 solaris
-
 package ipv6
 
-func (f *sysICMPv6Filter) accept(typ ICMPType) {
-       // TODO(mikio): implement this
+func (f *icmpv6Filter) accept(typ ICMPType) {
+       f.X__icmp6_filt[typ>>5] |= 1 << (uint32(typ) & 31)
 }
 
-func (f *sysICMPv6Filter) block(typ ICMPType) {
-       // TODO(mikio): implement this
+func (f *icmpv6Filter) block(typ ICMPType) {
+       f.X__icmp6_filt[typ>>5] &^= 1 << (uint32(typ) & 31)
 }
 
-func (f *sysICMPv6Filter) setAll(block bool) {
-       // TODO(mikio): implement this
+func (f *icmpv6Filter) setAll(block bool) {
+       for i := range f.X__icmp6_filt {
+               if block {
+                       f.X__icmp6_filt[i] = 0
+               } else {
+                       f.X__icmp6_filt[i] = 1<<32 - 1
+               }
+       }
 }
 
-func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
-       // TODO(mikio): implement this
-       return false
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
+       return f.X__icmp6_filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
 }
index c1263ecac4944d5bd1bbe1b0bbab1639d94d1238..c4b9be6dbffb75a00f998dc1447875772c3a6fe3 100644 (file)
@@ -1,23 +1,23 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 nacl plan9
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv6
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
 }
 
-func (f *sysICMPv6Filter) accept(typ ICMPType) {
+func (f *icmpv6Filter) accept(typ ICMPType) {
 }
 
-func (f *sysICMPv6Filter) block(typ ICMPType) {
+func (f *icmpv6Filter) block(typ ICMPType) {
 }
 
-func (f *sysICMPv6Filter) setAll(block bool) {
+func (f *icmpv6Filter) setAll(block bool) {
 }
 
-func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
        return false
 }
index 9dcfb8106b58ab727877be8dbdf8288668ee8d2d..443cd0736762d9cfbf8b8068dc5bd8590643046e 100644 (file)
@@ -1,26 +1,22 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 ipv6
 
-type sysICMPv6Filter struct {
+func (f *icmpv6Filter) accept(typ ICMPType) {
        // TODO(mikio): implement this
 }
 
-func (f *sysICMPv6Filter) accept(typ ICMPType) {
+func (f *icmpv6Filter) block(typ ICMPType) {
        // TODO(mikio): implement this
 }
 
-func (f *sysICMPv6Filter) block(typ ICMPType) {
+func (f *icmpv6Filter) setAll(block bool) {
        // TODO(mikio): implement this
 }
 
-func (f *sysICMPv6Filter) setAll(block bool) {
-       // TODO(mikio): implement this
-}
-
-func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool {
+func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
        // TODO(mikio): implement this
        return false
 }
index 529b20bcaf5084fe224192efdc0805d421defa77..a8197f16958a3749efed4c5eff103efd46b2b6be 100644 (file)
@@ -1,15 +1,23 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 ipv6
 
-import "net"
+import (
+       "net"
+
+       "golang.org/x/net/internal/socket"
+)
+
+// 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
+       *socket.Conn
        rawOpt
 }
 
-func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil }
+func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil && c.Conn != nil }
index 8e90d324d2d37534935805e093b44145e776d58e..4ee4b062ca38a50580b794e29bde0afc52a70135 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -12,59 +12,24 @@ import (
 )
 
 // ReadFrom reads a payload of the received IPv6 datagram, from the
-// endpoint c, copying the payload into b.  It returns the number of
+// endpoint c, copying the payload into b. It returns the number of
 // bytes copied into b, the control message cm and the source address
 // src of the received datagram.
 func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
        if !c.ok() {
                return 0, nil, nil, syscall.EINVAL
        }
-       oob := newControlMessage(&c.rawOpt)
-       var oobn int
-       switch c := c.PacketConn.(type) {
-       case *net.UDPConn:
-               if n, oobn, _, src, err = c.ReadMsgUDP(b, oob); err != nil {
-                       return 0, nil, nil, err
-               }
-       case *net.IPConn:
-               if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil {
-                       return 0, nil, nil, err
-               }
-       default:
-               return 0, nil, nil, errInvalidConnType
-       }
-       if cm, err = parseControlMessage(oob[:oobn]); err != nil {
-               return 0, nil, nil, err
-       }
-       if cm != nil {
-               cm.Src = netAddrToIP16(src)
-       }
-       return
+       return c.readFrom(b)
 }
 
 // WriteTo writes a payload of the IPv6 datagram, to the destination
-// address dst through the endpoint c, copying the payload from b.  It
-// returns the number of bytes written.  The control message cm allows
-// the IPv6 header fields and the datagram path to be specified.  The
+// address dst through the endpoint c, copying the payload from b. It
+// returns the number of bytes written. The control message cm allows
+// the IPv6 header fields and the datagram path to be specified. The
 // cm may be nil if control of the outgoing datagram is not required.
 func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
        if !c.ok() {
                return 0, syscall.EINVAL
        }
-       oob := marshalControlMessage(cm)
-       if dst == nil {
-               return 0, errMissingAddress
-       }
-       switch c := c.PacketConn.(type) {
-       case *net.UDPConn:
-               n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr))
-       case *net.IPConn:
-               n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr))
-       default:
-               return 0, errInvalidConnType
-       }
-       if err != nil {
-               return 0, err
-       }
-       return
+       return c.writeTo(b, cm, dst)
 }
index 499204d0c78f969ffbe40afaf7a9f330d2c8c438..99a43542b43d0e96b8ad0245b15f95cdfa76b43f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -12,7 +12,7 @@ import (
 )
 
 // ReadFrom reads a payload of the received IPv6 datagram, from the
-// endpoint c, copying the payload into b.  It returns the number of
+// endpoint c, copying the payload into b. It returns the number of
 // bytes copied into b, the control message cm and the source address
 // src of the received datagram.
 func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
@@ -26,9 +26,9 @@ func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.
 }
 
 // WriteTo writes a payload of the IPv6 datagram, to the destination
-// address dst through the endpoint c, copying the payload from b.  It
-// returns the number of bytes written.  The control message cm allows
-// the IPv6 header fields and the datagram path to be specified.  The
+// address dst through the endpoint c, copying the payload from b. It
+// returns the number of bytes written. The control message cm allows
+// the IPv6 header fields and the datagram path to be specified. The
 // cm may be nil if control of the outgoing datagram is not required.
 func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
        if !c.ok() {
index f0cfc2f94a113f7b96f138ab42f9a7b85d0697fc..cc3907df385cac707cccb4489da5a04e5c80bac9 100644 (file)
@@ -4,6 +4,8 @@
 
 package ipv6
 
+import "golang.org/x/net/internal/socket"
+
 // Sticky socket options
 const (
        ssoTrafficClass        = iota // header field for unicast packet, RFC 3542
@@ -24,23 +26,18 @@ const (
        ssoLeaveSourceGroup           // source-specific multicast
        ssoBlockSourceGroup           // any-source or source-specific multicast
        ssoUnblockSourceGroup         // any-source or source-specific multicast
-       ssoMax
+       ssoAttachFilter               // attach BPF for filtering inbound traffic
 )
 
 // Sticky socket option value types
 const (
-       ssoTypeInt = iota + 1
-       ssoTypeInterface
-       ssoTypeICMPFilter
-       ssoTypeMTUInfo
-       ssoTypeIPMreq
+       ssoTypeIPMreq = iota + 1
        ssoTypeGroupReq
        ssoTypeGroupSourceReq
 )
 
 // A sockOpt represents a binding for sticky socket option.
 type sockOpt struct {
-       level int // option level
-       name  int // option name, must be equal or greater than 1
-       typ   int // option value type, must be equal or greater than 1
+       socket.Option
+       typ int // hint for option value type; optional
 }
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_asmreq_unix.go b/vendor/golang.org/x/net/ipv6/sockopt_asmreq_unix.go
deleted file mode 100644 (file)
index b7fd4fe..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2013 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 darwin dragonfly freebsd linux netbsd openbsd
-
-package ipv6
-
-import (
-       "net"
-       "os"
-       "unsafe"
-)
-
-func setsockoptIPMreq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
-       var mreq sysIPv6Mreq
-       copy(mreq.Multiaddr[:], grp)
-       if ifi != nil {
-               mreq.setIfindex(ifi.Index)
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&mreq), sysSizeofIPv6Mreq))
-}
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_asmreq_windows.go b/vendor/golang.org/x/net/ipv6/sockopt_asmreq_windows.go
deleted file mode 100644 (file)
index c03c731..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2013 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 ipv6
-
-import (
-       "net"
-       "os"
-       "syscall"
-       "unsafe"
-)
-
-func setsockoptIPMreq(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
-       var mreq sysIPv6Mreq
-       copy(mreq.Multiaddr[:], grp)
-       if ifi != nil {
-               mreq.setIfindex(ifi.Index)
-       }
-       return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&mreq)), sysSizeofIPv6Mreq))
-}
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_ssmreq_stub.go b/vendor/golang.org/x/net/ipv6/sockopt_ssmreq_stub.go
deleted file mode 100644 (file)
index 7732e49..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !darwin,!freebsd,!linux
-
-package ipv6
-
-import "net"
-
-func setsockoptGroupReq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
-       return errOpNoSupport
-}
-
-func setsockoptGroupSourceReq(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
-       return errOpNoSupport
-}
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_ssmreq_unix.go b/vendor/golang.org/x/net/ipv6/sockopt_ssmreq_unix.go
deleted file mode 100644 (file)
index c64d6d5..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin freebsd linux
-
-package ipv6
-
-import (
-       "net"
-       "os"
-       "unsafe"
-)
-
-var freebsd32o64 bool
-
-func setsockoptGroupReq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
-       var gr sysGroupReq
-       if ifi != nil {
-               gr.Interface = uint32(ifi.Index)
-       }
-       gr.setGroup(grp)
-       var p unsafe.Pointer
-       var l sysSockoptLen
-       if freebsd32o64 {
-               var d [sysSizeofGroupReq + 4]byte
-               s := (*[sysSizeofGroupReq]byte)(unsafe.Pointer(&gr))
-               copy(d[:4], s[:4])
-               copy(d[8:], s[4:])
-               p = unsafe.Pointer(&d[0])
-               l = sysSizeofGroupReq + 4
-       } else {
-               p = unsafe.Pointer(&gr)
-               l = sysSizeofGroupReq
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, p, l))
-}
-
-func setsockoptGroupSourceReq(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
-       var gsr sysGroupSourceReq
-       if ifi != nil {
-               gsr.Interface = uint32(ifi.Index)
-       }
-       gsr.setSourceGroup(grp, src)
-       var p unsafe.Pointer
-       var l sysSockoptLen
-       if freebsd32o64 {
-               var d [sysSizeofGroupSourceReq + 4]byte
-               s := (*[sysSizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))
-               copy(d[:4], s[:4])
-               copy(d[8:], s[4:])
-               p = unsafe.Pointer(&d[0])
-               l = sysSizeofGroupSourceReq + 4
-       } else {
-               p = unsafe.Pointer(&gsr)
-               l = sysSizeofGroupSourceReq
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, p, l))
-}
index b8dacfde9e4b231cbc8b77e52f5d4a5b89d974fe..1f4a273e44529ae97dcfb1de7272a8cf44edfddc 100644 (file)
@@ -1,13 +1,46 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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 nacl plan9 solaris
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv6
 
-import "net"
+import (
+       "net"
 
-func getMTUInfo(fd int, opt *sockOpt) (*net.Interface, int, error) {
+       "golang.org/x/net/bpf"
+       "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
+       return nil, errOpNoSupport
+}
+
+func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
+       return errOpNoSupport
+}
+
+func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
+       return nil, errOpNoSupport
+}
+
+func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
+       return errOpNoSupport
+}
+
+func (so *sockOpt) getMTUInfo(c *socket.Conn) (*net.Interface, int, error) {
        return nil, 0, errOpNoSupport
 }
+
+func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+       return errOpNoSupport
+}
+
+func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+       return errOpNoSupport
+}
+
+func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
+       return errOpNoSupport
+}
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_unix.go b/vendor/golang.org/x/net/ipv6/sockopt_unix.go
deleted file mode 100644 (file)
index 25ea545..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2013 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 darwin dragonfly freebsd linux netbsd openbsd
-
-package ipv6
-
-import (
-       "net"
-       "os"
-       "unsafe"
-)
-
-func getInt(fd int, opt *sockOpt) (int, error) {
-       if opt.name < 1 || opt.typ != ssoTypeInt {
-               return 0, errOpNoSupport
-       }
-       var i int32
-       l := sysSockoptLen(4)
-       if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), &l); err != nil {
-               return 0, os.NewSyscallError("getsockopt", err)
-       }
-       return int(i), nil
-}
-
-func setInt(fd int, opt *sockOpt, v int) error {
-       if opt.name < 1 || opt.typ != ssoTypeInt {
-               return errOpNoSupport
-       }
-       i := int32(v)
-       return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), sysSockoptLen(4)))
-}
-
-func getInterface(fd int, opt *sockOpt) (*net.Interface, error) {
-       if opt.name < 1 || opt.typ != ssoTypeInterface {
-               return nil, errOpNoSupport
-       }
-       var i int32
-       l := sysSockoptLen(4)
-       if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), &l); err != nil {
-               return nil, os.NewSyscallError("getsockopt", err)
-       }
-       if i == 0 {
-               return nil, nil
-       }
-       ifi, err := net.InterfaceByIndex(int(i))
-       if err != nil {
-               return nil, err
-       }
-       return ifi, nil
-}
-
-func setInterface(fd int, opt *sockOpt, ifi *net.Interface) error {
-       if opt.name < 1 || opt.typ != ssoTypeInterface {
-               return errOpNoSupport
-       }
-       var i int32
-       if ifi != nil {
-               i = int32(ifi.Index)
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), sysSockoptLen(4)))
-}
-
-func getICMPFilter(fd int, opt *sockOpt) (*ICMPFilter, error) {
-       if opt.name < 1 || opt.typ != ssoTypeICMPFilter {
-               return nil, errOpNoSupport
-       }
-       var f ICMPFilter
-       l := sysSockoptLen(sysSizeofICMPv6Filter)
-       if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&f.sysICMPv6Filter), &l); err != nil {
-               return nil, os.NewSyscallError("getsockopt", err)
-       }
-       return &f, nil
-}
-
-func setICMPFilter(fd int, opt *sockOpt, f *ICMPFilter) error {
-       if opt.name < 1 || opt.typ != ssoTypeICMPFilter {
-               return errOpNoSupport
-       }
-       return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&f.sysICMPv6Filter), sysSizeofICMPv6Filter))
-}
-
-func getMTUInfo(fd int, opt *sockOpt) (*net.Interface, int, error) {
-       if opt.name < 1 || opt.typ != ssoTypeMTUInfo {
-               return nil, 0, errOpNoSupport
-       }
-       var mi sysIPv6Mtuinfo
-       l := sysSockoptLen(sysSizeofIPv6Mtuinfo)
-       if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&mi), &l); err != nil {
-               return nil, 0, os.NewSyscallError("getsockopt", err)
-       }
-       if mi.Addr.Scope_id == 0 {
-               return nil, int(mi.Mtu), nil
-       }
-       ifi, err := net.InterfaceByIndex(int(mi.Addr.Scope_id))
-       if err != nil {
-               return nil, 0, err
-       }
-       return ifi, int(mi.Mtu), nil
-}
-
-func setGroup(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
-       if opt.name < 1 {
-               return errOpNoSupport
-       }
-       switch opt.typ {
-       case ssoTypeIPMreq:
-               return setsockoptIPMreq(fd, opt, ifi, grp)
-       case ssoTypeGroupReq:
-               return setsockoptGroupReq(fd, opt, ifi, grp)
-       default:
-               return errOpNoSupport
-       }
-}
-
-func setSourceGroup(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
-       if opt.name < 1 || opt.typ != ssoTypeGroupSourceReq {
-               return errOpNoSupport
-       }
-       return setsockoptGroupSourceReq(fd, opt, ifi, grp, src)
-}
diff --git a/vendor/golang.org/x/net/ipv6/sockopt_windows.go b/vendor/golang.org/x/net/ipv6/sockopt_windows.go
deleted file mode 100644 (file)
index 32c73b7..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2013 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 ipv6
-
-import (
-       "net"
-       "os"
-       "syscall"
-       "unsafe"
-)
-
-func getInt(fd syscall.Handle, opt *sockOpt) (int, error) {
-       if opt.name < 1 || opt.typ != ssoTypeInt {
-               return 0, errOpNoSupport
-       }
-       var i int32
-       l := int32(4)
-       if err := syscall.Getsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil {
-               return 0, os.NewSyscallError("getsockopt", err)
-       }
-       return int(i), nil
-}
-
-func setInt(fd syscall.Handle, opt *sockOpt, v int) error {
-       if opt.name < 1 || opt.typ != ssoTypeInt {
-               return errOpNoSupport
-       }
-       i := int32(v)
-       return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4))
-}
-
-func getInterface(fd syscall.Handle, opt *sockOpt) (*net.Interface, error) {
-       if opt.name < 1 || opt.typ != ssoTypeInterface {
-               return nil, errOpNoSupport
-       }
-       var i int32
-       l := int32(4)
-       if err := syscall.Getsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil {
-               return nil, os.NewSyscallError("getsockopt", err)
-       }
-       if i == 0 {
-               return nil, nil
-       }
-       ifi, err := net.InterfaceByIndex(int(i))
-       if err != nil {
-               return nil, err
-       }
-       return ifi, nil
-}
-
-func setInterface(fd syscall.Handle, opt *sockOpt, ifi *net.Interface) error {
-       if opt.name < 1 || opt.typ != ssoTypeInterface {
-               return errOpNoSupport
-       }
-       var i int32
-       if ifi != nil {
-               i = int32(ifi.Index)
-       }
-       return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4))
-}
-
-func getICMPFilter(fd syscall.Handle, opt *sockOpt) (*ICMPFilter, error) {
-       return nil, errOpNoSupport
-}
-
-func setICMPFilter(fd syscall.Handle, opt *sockOpt, f *ICMPFilter) error {
-       return errOpNoSupport
-}
-
-func getMTUInfo(fd syscall.Handle, opt *sockOpt) (*net.Interface, int, error) {
-       return nil, 0, errOpNoSupport
-}
-
-func setGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
-       if opt.name < 1 || opt.typ != ssoTypeIPMreq {
-               return errOpNoSupport
-       }
-       return setsockoptIPMreq(fd, opt, ifi, grp)
-}
-
-func setSourceGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
-       // TODO(mikio): implement this
-       return errOpNoSupport
-}
index 75a8863b3ed7c5a6b32c34a9eaf820d805a9dfbc..e416eaa1fe4a12d89810c981c4d0b95410ac2dca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -11,48 +11,47 @@ import (
        "syscall"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
-type sysSockoptLen int32
-
 var (
        ctlOpts = [ctlMax]ctlOpt{
                ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
                ctlHopLimit:     {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
-               ctlPacketInfo:   {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
-               ctlNextHop:      {sysIPV6_NEXTHOP, sysSizeofSockaddrInet6, marshalNextHop, parseNextHop},
-               ctlPathMTU:      {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+               ctlPacketInfo:   {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+               ctlNextHop:      {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+               ctlPathMTU:      {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
        }
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoTrafficClass:        {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
-               ssoHopLimit:            {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
-               ssoMulticastInterface:  {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastHopLimit:   {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
-               ssoMulticastLoopback:   {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
-               ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt},
-               ssoReceiveHopLimit:     {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt},
-               ssoReceivePacketInfo:   {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt},
-               ssoReceivePathMTU:      {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt},
-               ssoPathMTU:             {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo},
-               ssoChecksum:            {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
-               ssoICMPFilter:          {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
-               ssoJoinGroup:           {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
-               ssoLeaveGroup:          {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
+       sockOpts = map[int]*sockOpt{
+               ssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
+               ssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
+               ssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
+               ssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
+               ssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
+               ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
+               ssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
+               ssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
+               ssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
+               ssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+               ssoChecksum:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
+               ssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
+               ssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+               ssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
        }
 )
 
-func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
-       sa.Len = sysSizeofSockaddrInet6
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+       sa.Len = sizeofSockaddrInet6
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], ip)
        sa.Scope_id = uint32(i)
 }
 
-func (pi *sysInet6Pktinfo) setIfindex(i int) {
+func (pi *inet6Pktinfo) setIfindex(i int) {
        pi.Ifindex = uint32(i)
 }
 
-func (mreq *sysIPv6Mreq) setIfindex(i int) {
+func (mreq *ipv6Mreq) setIfindex(i int) {
        mreq.Interface = uint32(i)
 }
index 411fb498c8e67487c4c90ee615c41799a4a3cf36..e3d04439275d614a2bb21d1fd3c8d1ac256052bf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -6,130 +6,101 @@ package ipv6
 
 import (
        "net"
+       "strconv"
+       "strings"
        "syscall"
        "unsafe"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
-type sysSockoptLen int32
-
 var (
        ctlOpts = [ctlMax]ctlOpt{
                ctlHopLimit:   {sysIPV6_2292HOPLIMIT, 4, marshal2292HopLimit, parseHopLimit},
-               ctlPacketInfo: {sysIPV6_2292PKTINFO, sysSizeofInet6Pktinfo, marshal2292PacketInfo, parsePacketInfo},
+               ctlPacketInfo: {sysIPV6_2292PKTINFO, sizeofInet6Pktinfo, marshal2292PacketInfo, parsePacketInfo},
        }
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoHopLimit:           {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
-               ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastHopLimit:  {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
-               ssoMulticastLoopback:  {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
-               ssoReceiveHopLimit:    {iana.ProtocolIPv6, sysIPV6_2292HOPLIMIT, ssoTypeInt},
-               ssoReceivePacketInfo:  {iana.ProtocolIPv6, sysIPV6_2292PKTINFO, ssoTypeInt},
-               ssoChecksum:           {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
-               ssoICMPFilter:         {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
-               ssoJoinGroup:          {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
-               ssoLeaveGroup:         {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
+       sockOpts = map[int]*sockOpt{
+               ssoHopLimit:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
+               ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
+               ssoMulticastHopLimit:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
+               ssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
+               ssoReceiveHopLimit:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_2292HOPLIMIT, Len: 4}},
+               ssoReceivePacketInfo:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_2292PKTINFO, Len: 4}},
+               ssoChecksum:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
+               ssoICMPFilter:         {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
+               ssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+               ssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
        }
 )
 
 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[ctlTrafficClass].name = sysIPV6_TCLASS
-               ctlOpts[ctlTrafficClass].length = 4
-               ctlOpts[ctlTrafficClass].marshal = marshalTrafficClass
-               ctlOpts[ctlTrafficClass].parse = parseTrafficClass
-               ctlOpts[ctlHopLimit].name = sysIPV6_HOPLIMIT
-               ctlOpts[ctlHopLimit].marshal = marshalHopLimit
-               ctlOpts[ctlPacketInfo].name = sysIPV6_PKTINFO
-               ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo
-               ctlOpts[ctlNextHop].name = sysIPV6_NEXTHOP
-               ctlOpts[ctlNextHop].length = sysSizeofSockaddrInet6
-               ctlOpts[ctlNextHop].marshal = marshalNextHop
-               ctlOpts[ctlNextHop].parse = parseNextHop
-               ctlOpts[ctlPathMTU].name = sysIPV6_PATHMTU
-               ctlOpts[ctlPathMTU].length = sysSizeofIPv6Mtuinfo
-               ctlOpts[ctlPathMTU].marshal = marshalPathMTU
-               ctlOpts[ctlPathMTU].parse = parsePathMTU
-               sockOpts[ssoTrafficClass].level = iana.ProtocolIPv6
-               sockOpts[ssoTrafficClass].name = sysIPV6_TCLASS
-               sockOpts[ssoTrafficClass].typ = ssoTypeInt
-               sockOpts[ssoReceiveTrafficClass].level = iana.ProtocolIPv6
-               sockOpts[ssoReceiveTrafficClass].name = sysIPV6_RECVTCLASS
-               sockOpts[ssoReceiveTrafficClass].typ = ssoTypeInt
-               sockOpts[ssoReceiveHopLimit].name = sysIPV6_RECVHOPLIMIT
-               sockOpts[ssoReceivePacketInfo].name = sysIPV6_RECVPKTINFO
-               sockOpts[ssoReceivePathMTU].level = iana.ProtocolIPv6
-               sockOpts[ssoReceivePathMTU].name = sysIPV6_RECVPATHMTU
-               sockOpts[ssoReceivePathMTU].typ = ssoTypeInt
-               sockOpts[ssoPathMTU].level = iana.ProtocolIPv6
-               sockOpts[ssoPathMTU].name = sysIPV6_PATHMTU
-               sockOpts[ssoPathMTU].typ = ssoTypeMTUInfo
-               sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP
-               sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq
-               sockOpts[ssoLeaveGroup].name = sysMCAST_LEAVE_GROUP
-               sockOpts[ssoLeaveGroup].typ = ssoTypeGroupReq
-               sockOpts[ssoJoinSourceGroup].level = iana.ProtocolIPv6
-               sockOpts[ssoJoinSourceGroup].name = sysMCAST_JOIN_SOURCE_GROUP
-               sockOpts[ssoJoinSourceGroup].typ = ssoTypeGroupSourceReq
-               sockOpts[ssoLeaveSourceGroup].level = iana.ProtocolIPv6
-               sockOpts[ssoLeaveSourceGroup].name = sysMCAST_LEAVE_SOURCE_GROUP
-               sockOpts[ssoLeaveSourceGroup].typ = ssoTypeGroupSourceReq
-               sockOpts[ssoBlockSourceGroup].level = iana.ProtocolIPv6
-               sockOpts[ssoBlockSourceGroup].name = sysMCAST_BLOCK_SOURCE
-               sockOpts[ssoBlockSourceGroup].typ = ssoTypeGroupSourceReq
-               sockOpts[ssoUnblockSourceGroup].level = iana.ProtocolIPv6
-               sockOpts[ssoUnblockSourceGroup].name = sysMCAST_UNBLOCK_SOURCE
-               sockOpts[ssoUnblockSourceGroup].typ = ssoTypeGroupSourceReq
+       if mjver, err := strconv.Atoi(ss[0]); err != nil || mjver < 12 {
+               return
        }
+       ctlOpts[ctlTrafficClass] = ctlOpt{sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass}
+       ctlOpts[ctlHopLimit] = ctlOpt{sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit}
+       ctlOpts[ctlPacketInfo] = ctlOpt{sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo}
+       ctlOpts[ctlNextHop] = ctlOpt{sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop}
+       ctlOpts[ctlPathMTU] = ctlOpt{sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU}
+       sockOpts[ssoTrafficClass] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}}
+       sockOpts[ssoReceiveTrafficClass] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}}
+       sockOpts[ssoReceiveHopLimit] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}}
+       sockOpts[ssoReceivePacketInfo] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}}
+       sockOpts[ssoReceivePathMTU] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}}
+       sockOpts[ssoPathMTU] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}}
+       sockOpts[ssoJoinGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
+       sockOpts[ssoLeaveGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
+       sockOpts[ssoJoinSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
+       sockOpts[ssoLeaveSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
+       sockOpts[ssoBlockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
+       sockOpts[ssoUnblockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
 }
 
-func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
-       sa.Len = sysSizeofSockaddrInet6
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+       sa.Len = sizeofSockaddrInet6
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], ip)
        sa.Scope_id = uint32(i)
 }
 
-func (pi *sysInet6Pktinfo) setIfindex(i int) {
+func (pi *inet6Pktinfo) setIfindex(i int) {
        pi.Ifindex = uint32(i)
 }
 
-func (mreq *sysIPv6Mreq) setIfindex(i int) {
+func (mreq *ipv6Mreq) setIfindex(i int) {
        mreq.Interface = uint32(i)
 }
 
-func (gr *sysGroupReq) setGroup(grp net.IP) {
-       sa := (*sysSockaddrInet6)(unsafe.Pointer(&gr.Pad_cgo_0[0]))
-       sa.Len = sysSizeofSockaddrInet6
+func (gr *groupReq) setGroup(grp net.IP) {
+       sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
+       sa.Len = sizeofSockaddrInet6
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], grp)
 }
 
-func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
-       sa := (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Pad_cgo_0[0]))
-       sa.Len = sysSizeofSockaddrInet6
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+       sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
+       sa.Len = sizeofSockaddrInet6
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], grp)
-       sa = (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Pad_cgo_1[0]))
-       sa.Len = sysSizeofSockaddrInet6
+       sa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))
+       sa.Len = sizeofSockaddrInet6
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], src)
 }
index b68725cba6ec337f1234e33937783476e47bac96..e9349dc2cc20d023c76a68609c9380959a2bc33f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -12,38 +12,37 @@ import (
        "unsafe"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
-type sysSockoptLen int32
-
 var (
        ctlOpts = [ctlMax]ctlOpt{
                ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
                ctlHopLimit:     {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
-               ctlPacketInfo:   {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
-               ctlNextHop:      {sysIPV6_NEXTHOP, sysSizeofSockaddrInet6, marshalNextHop, parseNextHop},
-               ctlPathMTU:      {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+               ctlPacketInfo:   {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+               ctlNextHop:      {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
+               ctlPathMTU:      {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
        }
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoTrafficClass:        {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
-               ssoHopLimit:            {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
-               ssoMulticastInterface:  {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastHopLimit:   {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
-               ssoMulticastLoopback:   {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
-               ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt},
-               ssoReceiveHopLimit:     {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt},
-               ssoReceivePacketInfo:   {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt},
-               ssoReceivePathMTU:      {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt},
-               ssoPathMTU:             {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo},
-               ssoChecksum:            {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt},
-               ssoICMPFilter:          {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter},
-               ssoJoinGroup:           {iana.ProtocolIPv6, sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
-               ssoLeaveGroup:          {iana.ProtocolIPv6, sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
-               ssoJoinSourceGroup:     {iana.ProtocolIPv6, sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
-               ssoLeaveSourceGroup:    {iana.ProtocolIPv6, sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
-               ssoBlockSourceGroup:    {iana.ProtocolIPv6, sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
-               ssoUnblockSourceGroup:  {iana.ProtocolIPv6, sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
+       sockOpts = map[int]sockOpt{
+               ssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
+               ssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
+               ssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
+               ssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
+               ssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
+               ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
+               ssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
+               ssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
+               ssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
+               ssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+               ssoChecksum:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
+               ssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
+               ssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+               ssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+               ssoJoinSourceGroup:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoLeaveSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoBlockSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoUnblockSourceGroup:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
        }
 )
 
@@ -59,35 +58,35 @@ func init() {
        }
 }
 
-func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
-       sa.Len = sysSizeofSockaddrInet6
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
+       sa.Len = sizeofSockaddrInet6
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], ip)
        sa.Scope_id = uint32(i)
 }
 
-func (pi *sysInet6Pktinfo) setIfindex(i int) {
+func (pi *inet6Pktinfo) setIfindex(i int) {
        pi.Ifindex = uint32(i)
 }
 
-func (mreq *sysIPv6Mreq) setIfindex(i int) {
+func (mreq *ipv6Mreq) setIfindex(i int) {
        mreq.Interface = uint32(i)
 }
 
-func (gr *sysGroupReq) setGroup(grp net.IP) {
-       sa := (*sysSockaddrInet6)(unsafe.Pointer(&gr.Group))
-       sa.Len = sysSizeofSockaddrInet6
+func (gr *groupReq) setGroup(grp net.IP) {
+       sa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))
+       sa.Len = sizeofSockaddrInet6
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], grp)
 }
 
-func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
-       sa := (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Group))
-       sa.Len = sysSizeofSockaddrInet6
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+       sa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))
+       sa.Len = sizeofSockaddrInet6
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], grp)
-       sa = (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Source))
-       sa.Len = sysSizeofSockaddrInet6
+       sa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))
+       sa.Len = sizeofSockaddrInet6
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], src)
 }
index 2fa6088d0f761075b8d1b8a599508dee8f48683e..bc218103c11ddeca930e3b231f3b9cae09422120 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -10,65 +10,65 @@ import (
        "unsafe"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
-type sysSockoptLen int32
-
 var (
        ctlOpts = [ctlMax]ctlOpt{
                ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
                ctlHopLimit:     {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
-               ctlPacketInfo:   {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
-               ctlPathMTU:      {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
+               ctlPacketInfo:   {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
+               ctlPathMTU:      {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
        }
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoTrafficClass:        {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt},
-               ssoHopLimit:            {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
-               ssoMulticastInterface:  {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastHopLimit:   {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
-               ssoMulticastLoopback:   {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
-               ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt},
-               ssoReceiveHopLimit:     {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt},
-               ssoReceivePacketInfo:   {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt},
-               ssoReceivePathMTU:      {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt},
-               ssoPathMTU:             {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo},
-               ssoChecksum:            {iana.ProtocolReserved, sysIPV6_CHECKSUM, ssoTypeInt},
-               ssoICMPFilter:          {iana.ProtocolIPv6ICMP, sysICMPV6_FILTER, ssoTypeICMPFilter},
-               ssoJoinGroup:           {iana.ProtocolIPv6, sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
-               ssoLeaveGroup:          {iana.ProtocolIPv6, sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
-               ssoJoinSourceGroup:     {iana.ProtocolIPv6, sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
-               ssoLeaveSourceGroup:    {iana.ProtocolIPv6, sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
-               ssoBlockSourceGroup:    {iana.ProtocolIPv6, sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
-               ssoUnblockSourceGroup:  {iana.ProtocolIPv6, sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
+       sockOpts = map[int]*sockOpt{
+               ssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
+               ssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
+               ssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
+               ssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
+               ssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
+               ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
+               ssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
+               ssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
+               ssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
+               ssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
+               ssoChecksum:            {Option: socket.Option{Level: iana.ProtocolReserved, Name: sysIPV6_CHECKSUM, Len: 4}},
+               ssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMPV6_FILTER, Len: sizeofICMPv6Filter}},
+               ssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+               ssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+               ssoJoinSourceGroup:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoLeaveSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoBlockSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoUnblockSourceGroup:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+               ssoAttachFilter:        {Option: socket.Option{Level: sysSOL_SOCKET, Name: sysSO_ATTACH_FILTER, Len: sizeofSockFprog}},
        }
 )
 
-func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], ip)
        sa.Scope_id = uint32(i)
 }
 
-func (pi *sysInet6Pktinfo) setIfindex(i int) {
+func (pi *inet6Pktinfo) setIfindex(i int) {
        pi.Ifindex = int32(i)
 }
 
-func (mreq *sysIPv6Mreq) setIfindex(i int) {
+func (mreq *ipv6Mreq) setIfindex(i int) {
        mreq.Ifindex = int32(i)
 }
 
-func (gr *sysGroupReq) setGroup(grp net.IP) {
-       sa := (*sysSockaddrInet6)(unsafe.Pointer(&gr.Group))
+func (gr *groupReq) setGroup(grp net.IP) {
+       sa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], grp)
 }
 
-func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) {
-       sa := (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Group))
+func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
+       sa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], grp)
-       sa = (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Source))
+       sa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], src)
 }
index 6c9a14304a636dca7e752ed43302692f7f737a1c..b845388ea4a3e60a6f298c996b6f10c79bd7c547 100644 (file)
@@ -2,14 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build nacl plan9 solaris
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv6
 
-type sysSockoptLen int32
-
 var (
        ctlOpts = [ctlMax]ctlOpt{}
 
-       sockOpts = [ssoMax]sockOpt{}
+       sockOpts = map[int]*sockOpt{}
 )
index fda875736fed9af06fef497a93d2546870ebae2d..fc36b018bd2faecc803460741800d7e362187f97 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
+// Copyright 2013 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.
 
@@ -9,6 +9,7 @@ import (
        "syscall"
 
        "golang.org/x/net/internal/iana"
+       "golang.org/x/net/internal/socket"
 )
 
 const (
@@ -21,12 +22,14 @@ const (
        sysIPV6_LEAVE_GROUP    = 0xd
        sysIPV6_PKTINFO        = 0x13
 
-       sysSizeofSockaddrInet6 = 0x1c
+       sizeofSockaddrInet6 = 0x1c
 
-       sysSizeofIPv6Mreq = 0x14
+       sizeofIPv6Mreq     = 0x14
+       sizeofIPv6Mtuinfo  = 0x20
+       sizeofICMPv6Filter = 0
 )
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Family   uint16
        Port     uint16
        Flowinfo uint32
@@ -34,30 +37,39 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Interface uint32
 }
 
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
+       Mtu  uint32
+}
+
+type icmpv6Filter struct {
+       // TODO(mikio): implement this
+}
+
 var (
        ctlOpts = [ctlMax]ctlOpt{}
 
-       sockOpts = [ssoMax]sockOpt{
-               ssoHopLimit:           {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt},
-               ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface},
-               ssoMulticastHopLimit:  {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt},
-               ssoMulticastLoopback:  {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt},
-               ssoJoinGroup:          {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq},
-               ssoLeaveGroup:         {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq},
+       sockOpts = map[int]*sockOpt{
+               ssoHopLimit:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
+               ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
+               ssoMulticastHopLimit:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
+               ssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
+               ssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
+               ssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
        }
 )
 
-func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
+func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
        sa.Family = syscall.AF_INET6
        copy(sa.Addr[:], ip)
        sa.Scope_id = uint32(i)
 }
 
-func (mreq *sysIPv6Mreq) setIfindex(i int) {
+func (mreq *ipv6Mreq) setIfindex(i int) {
        mreq.Interface = uint32(i)
 }
diff --git a/vendor/golang.org/x/net/ipv6/syscall_linux_386.go b/vendor/golang.org/x/net/ipv6/syscall_linux_386.go
deleted file mode 100644 (file)
index 82633a5..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2009 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 ipv6
-
-import (
-       "syscall"
-       "unsafe"
-)
-
-const (
-       sysGETSOCKOPT = 0xf
-       sysSETSOCKOPT = 0xe
-)
-
-func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
-
-func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error {
-       if _, errno := socketcall(sysGETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
-               return error(errno)
-       }
-       return nil
-}
-
-func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error {
-       if _, errno := socketcall(sysSETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
-               return error(errno)
-       }
-       return nil
-}
diff --git a/vendor/golang.org/x/net/ipv6/syscall_unix.go b/vendor/golang.org/x/net/ipv6/syscall_unix.go
deleted file mode 100644 (file)
index a2bd836..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013 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 darwin dragonfly freebsd linux,!386 netbsd openbsd
-
-package ipv6
-
-import (
-       "syscall"
-       "unsafe"
-)
-
-func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error {
-       if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
-               return error(errno)
-       }
-       return nil
-}
-
-func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error {
-       if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
-               return error(errno)
-       }
-       return nil
-}
diff --git a/vendor/golang.org/x/net/ipv6/thunk_linux_386.s b/vendor/golang.org/x/net/ipv6/thunk_linux_386.s
deleted file mode 100644 (file)
index daa78bc..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build go1.2
-
-TEXT   Â·socketcall(SB),4,$0-36
-       JMP     syscall·socketcall(SB)
index cb044b0336aac7415768ab8c6ea8cbf09c195950..6aab1dfab7cb4ce60256fa843e8c8709f839fb33 100644 (file)
@@ -71,19 +71,19 @@ const (
        sysIPV6_PORTRANGE_HIGH    = 0x1
        sysIPV6_PORTRANGE_LOW     = 0x2
 
-       sysSizeofSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6   = 0x1c
-       sysSizeofInet6Pktinfo    = 0x14
-       sysSizeofIPv6Mtuinfo     = 0x20
+       sizeofSockaddrStorage = 0x80
+       sizeofSockaddrInet6   = 0x1c
+       sizeofInet6Pktinfo    = 0x14
+       sizeofIPv6Mtuinfo     = 0x20
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x84
-       sysSizeofGroupSourceReq = 0x104
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x84
+       sizeofGroupSourceReq = 0x104
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
 )
 
-type sysSockaddrStorage struct {
+type sockaddrStorage struct {
        Len         uint8
        Family      uint8
        X__ss_pad1  [6]int8
@@ -91,7 +91,7 @@ type sysSockaddrStorage struct {
        X__ss_pad2  [112]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Len      uint8
        Family   uint8
        Port     uint16
@@ -100,31 +100,31 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex uint32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Interface uint32
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Filt [8]uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [128]byte
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [128]byte
        Pad_cgo_1 [128]byte
index 5a03ab7340a5417ec37302a10b9c14d16db30dab..d2de804d88c3b7bdb547b14a446fb4aab53d6f2f 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_dragonfly.go
 
-// +build dragonfly
-
 package ipv6
 
 const (
@@ -52,16 +50,16 @@ const (
        sysIPV6_PORTRANGE_HIGH    = 0x1
        sysIPV6_PORTRANGE_LOW     = 0x2
 
-       sysSizeofSockaddrInet6 = 0x1c
-       sysSizeofInet6Pktinfo  = 0x14
-       sysSizeofIPv6Mtuinfo   = 0x20
+       sizeofSockaddrInet6 = 0x1c
+       sizeofInet6Pktinfo  = 0x14
+       sizeofIPv6Mtuinfo   = 0x20
 
-       sysSizeofIPv6Mreq = 0x14
+       sizeofIPv6Mreq = 0x14
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
 )
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Len      uint8
        Family   uint8
        Port     uint16
@@ -70,21 +68,21 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex uint32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Interface uint32
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Filt [8]uint32
 }
index 4ace96f0c5be4e4d72686c34d2f46dc57d187b47..919e572d4a1016a380871efecf2e2778c1070555 100644 (file)
@@ -62,19 +62,19 @@ const (
        sysIPV6_PORTRANGE_HIGH    = 0x1
        sysIPV6_PORTRANGE_LOW     = 0x2
 
-       sysSizeofSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6   = 0x1c
-       sysSizeofInet6Pktinfo    = 0x14
-       sysSizeofIPv6Mtuinfo     = 0x20
+       sizeofSockaddrStorage = 0x80
+       sizeofSockaddrInet6   = 0x1c
+       sizeofInet6Pktinfo    = 0x14
+       sizeofIPv6Mtuinfo     = 0x20
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x84
-       sysSizeofGroupSourceReq = 0x104
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x84
+       sizeofGroupSourceReq = 0x104
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
 )
 
-type sysSockaddrStorage struct {
+type sockaddrStorage struct {
        Len         uint8
        Family      uint8
        X__ss_pad1  [6]int8
@@ -82,7 +82,7 @@ type sysSockaddrStorage struct {
        X__ss_pad2  [112]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Len      uint8
        Family   uint8
        Port     uint16
@@ -91,32 +91,32 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex uint32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Interface uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
-       Group     sysSockaddrStorage
+       Group     sockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
-       Group     sysSockaddrStorage
-       Source    sysSockaddrStorage
+       Group     sockaddrStorage
+       Source    sockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Filt [8]uint32
 }
index 4a62c2d5c0c2c27ea20d2ff78dbe0adad5b3a7cb..cb8141f9c65e310db12b9f7a6558f616fa0b1e76 100644 (file)
@@ -62,19 +62,19 @@ const (
        sysIPV6_PORTRANGE_HIGH    = 0x1
        sysIPV6_PORTRANGE_LOW     = 0x2
 
-       sysSizeofSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6   = 0x1c
-       sysSizeofInet6Pktinfo    = 0x14
-       sysSizeofIPv6Mtuinfo     = 0x20
+       sizeofSockaddrStorage = 0x80
+       sizeofSockaddrInet6   = 0x1c
+       sizeofInet6Pktinfo    = 0x14
+       sizeofIPv6Mtuinfo     = 0x20
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
 )
 
-type sysSockaddrStorage struct {
+type sockaddrStorage struct {
        Len         uint8
        Family      uint8
        X__ss_pad1  [6]int8
@@ -82,7 +82,7 @@ type sysSockaddrStorage struct {
        X__ss_pad2  [112]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Len      uint8
        Family   uint8
        Port     uint16
@@ -91,34 +91,34 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex uint32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Interface uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysSockaddrStorage
+       Group     sockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysSockaddrStorage
-       Source    sysSockaddrStorage
+       Group     sockaddrStorage
+       Source    sockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Filt [8]uint32
 }
index 4a62c2d5c0c2c27ea20d2ff78dbe0adad5b3a7cb..cb8141f9c65e310db12b9f7a6558f616fa0b1e76 100644 (file)
@@ -62,19 +62,19 @@ const (
        sysIPV6_PORTRANGE_HIGH    = 0x1
        sysIPV6_PORTRANGE_LOW     = 0x2
 
-       sysSizeofSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6   = 0x1c
-       sysSizeofInet6Pktinfo    = 0x14
-       sysSizeofIPv6Mtuinfo     = 0x20
+       sizeofSockaddrStorage = 0x80
+       sizeofSockaddrInet6   = 0x1c
+       sizeofInet6Pktinfo    = 0x14
+       sizeofIPv6Mtuinfo     = 0x20
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
 )
 
-type sysSockaddrStorage struct {
+type sockaddrStorage struct {
        Len         uint8
        Family      uint8
        X__ss_pad1  [6]int8
@@ -82,7 +82,7 @@ type sysSockaddrStorage struct {
        X__ss_pad2  [112]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Len      uint8
        Family   uint8
        Port     uint16
@@ -91,34 +91,34 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex uint32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Interface uint32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysSockaddrStorage
+       Group     sockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysSockaddrStorage
-       Source    sysSockaddrStorage
+       Group     sockaddrStorage
+       Source    sockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Filt [8]uint32
 }
index 272792929d413ad59ae9a51e077c711477719c82..73aa8c6dfce037b278782660490dbbe32cd0c485 100644 (file)
@@ -84,25 +84,30 @@ const (
        sysICMPV6_FILTER_BLOCKOTHERS = 0x3
        sysICMPV6_FILTER_PASSONLY    = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6         = 0x1c
-       sysSizeofInet6Pktinfo          = 0x14
-       sysSizeofIPv6Mtuinfo           = 0x20
-       sysSizeofIPv6FlowlabelReq      = 0x20
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x84
-       sysSizeofGroupSourceReq = 0x104
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet6         = 0x1c
+       sizeofInet6Pktinfo          = 0x14
+       sizeofIPv6Mtuinfo           = 0x20
+       sizeofIPv6FlowlabelReq      = 0x20
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x84
+       sizeofGroupSourceReq = 0x104
+
+       sizeofICMPv6Filter = 0x20
+
+       sizeofSockFprog = 0x8
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Family   uint16
        Port     uint16
        Flowinfo uint32
@@ -110,17 +115,17 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex int32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6FlowlabelReq struct {
+type ipv6FlowlabelReq struct {
        Dst        [16]byte /* in6_addr */
        Label      uint32
        Action     uint8
@@ -131,22 +136,35 @@ type sysIPv6FlowlabelReq struct {
        X__flr_pad uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Ifindex   int32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+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
+}
index 2f742e9560c96af14e116b9bf9f488139512e4f6..b64f0157d7a45ada2145c55b5a0a6cf38e9bfda0 100644 (file)
@@ -84,25 +84,30 @@ const (
        sysICMPV6_FILTER_BLOCKOTHERS = 0x3
        sysICMPV6_FILTER_PASSONLY    = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6         = 0x1c
-       sysSizeofInet6Pktinfo          = 0x14
-       sysSizeofIPv6Mtuinfo           = 0x20
-       sysSizeofIPv6FlowlabelReq      = 0x20
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet6         = 0x1c
+       sizeofInet6Pktinfo          = 0x14
+       sizeofIPv6Mtuinfo           = 0x20
+       sizeofIPv6FlowlabelReq      = 0x20
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
+
+       sizeofICMPv6Filter = 0x20
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Family   uint16
        Port     uint16
        Flowinfo uint32
@@ -110,17 +115,17 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex int32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6FlowlabelReq struct {
+type ipv6FlowlabelReq struct {
        Dst        [16]byte /* in6_addr */
        Label      uint32
        Action     uint8
@@ -131,24 +136,37 @@ type sysIPv6FlowlabelReq struct {
        X__flr_pad uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Ifindex   int32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Data [8]uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index 272792929d413ad59ae9a51e077c711477719c82..73aa8c6dfce037b278782660490dbbe32cd0c485 100644 (file)
@@ -84,25 +84,30 @@ const (
        sysICMPV6_FILTER_BLOCKOTHERS = 0x3
        sysICMPV6_FILTER_PASSONLY    = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6         = 0x1c
-       sysSizeofInet6Pktinfo          = 0x14
-       sysSizeofIPv6Mtuinfo           = 0x20
-       sysSizeofIPv6FlowlabelReq      = 0x20
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x84
-       sysSizeofGroupSourceReq = 0x104
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet6         = 0x1c
+       sizeofInet6Pktinfo          = 0x14
+       sizeofIPv6Mtuinfo           = 0x20
+       sizeofIPv6FlowlabelReq      = 0x20
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x84
+       sizeofGroupSourceReq = 0x104
+
+       sizeofICMPv6Filter = 0x20
+
+       sizeofSockFprog = 0x8
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Family   uint16
        Port     uint16
        Flowinfo uint32
@@ -110,17 +115,17 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex int32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6FlowlabelReq struct {
+type ipv6FlowlabelReq struct {
        Dst        [16]byte /* in6_addr */
        Label      uint32
        Action     uint8
@@ -131,22 +136,35 @@ type sysIPv6FlowlabelReq struct {
        X__flr_pad uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Ifindex   int32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+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
+}
index ab10464533b493fcacbed42e3c4ef34ff911cd09..b64f0157d7a45ada2145c55b5a0a6cf38e9bfda0 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,arm64
-
 package ipv6
 
 const (
@@ -86,25 +84,30 @@ const (
        sysICMPV6_FILTER_BLOCKOTHERS = 0x3
        sysICMPV6_FILTER_PASSONLY    = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6         = 0x1c
-       sysSizeofInet6Pktinfo          = 0x14
-       sysSizeofIPv6Mtuinfo           = 0x20
-       sysSizeofIPv6FlowlabelReq      = 0x20
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet6         = 0x1c
+       sizeofInet6Pktinfo          = 0x14
+       sizeofIPv6Mtuinfo           = 0x20
+       sizeofIPv6FlowlabelReq      = 0x20
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Family   uint16
        Port     uint16
        Flowinfo uint32
@@ -112,17 +115,17 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex int32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6FlowlabelReq struct {
+type ipv6FlowlabelReq struct {
        Dst        [16]byte /* in6_addr */
        Label      uint32
        Action     uint8
@@ -133,24 +136,37 @@ type sysIPv6FlowlabelReq struct {
        X__flr_pad uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Ifindex   int32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Data [8]uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index ec8ce1579de8d50d5b15eba736608a61691ec021..b64f0157d7a45ada2145c55b5a0a6cf38e9bfda0 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,mips64
-
 package ipv6
 
 const (
@@ -86,25 +84,30 @@ const (
        sysICMPV6_FILTER_BLOCKOTHERS = 0x3
        sysICMPV6_FILTER_PASSONLY    = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6         = 0x1c
-       sysSizeofInet6Pktinfo          = 0x14
-       sysSizeofIPv6Mtuinfo           = 0x20
-       sysSizeofIPv6FlowlabelReq      = 0x20
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet6         = 0x1c
+       sizeofInet6Pktinfo          = 0x14
+       sizeofIPv6Mtuinfo           = 0x20
+       sizeofIPv6FlowlabelReq      = 0x20
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Family   uint16
        Port     uint16
        Flowinfo uint32
@@ -112,17 +115,17 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex int32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6FlowlabelReq struct {
+type ipv6FlowlabelReq struct {
        Dst        [16]byte /* in6_addr */
        Label      uint32
        Action     uint8
@@ -133,24 +136,37 @@ type sysIPv6FlowlabelReq struct {
        X__flr_pad uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Ifindex   int32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Data [8]uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index 2341ae67742b58a0669452b235a959b25c817936..b64f0157d7a45ada2145c55b5a0a6cf38e9bfda0 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,mips64le
-
 package ipv6
 
 const (
@@ -86,25 +84,30 @@ const (
        sysICMPV6_FILTER_BLOCKOTHERS = 0x3
        sysICMPV6_FILTER_PASSONLY    = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6         = 0x1c
-       sysSizeofInet6Pktinfo          = 0x14
-       sysSizeofIPv6Mtuinfo           = 0x20
-       sysSizeofIPv6FlowlabelReq      = 0x20
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet6         = 0x1c
+       sizeofInet6Pktinfo          = 0x14
+       sizeofIPv6Mtuinfo           = 0x20
+       sizeofIPv6FlowlabelReq      = 0x20
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Family   uint16
        Port     uint16
        Flowinfo uint32
@@ -112,17 +115,17 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex int32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6FlowlabelReq struct {
+type ipv6FlowlabelReq struct {
        Dst        [16]byte /* in6_addr */
        Label      uint32
        Action     uint8
@@ -133,24 +136,37 @@ type sysIPv6FlowlabelReq struct {
        X__flr_pad uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Ifindex   int32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Data [8]uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index b99b8a51504c8e327801e40e64b4e1b6000a1971..b64f0157d7a45ada2145c55b5a0a6cf38e9bfda0 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,ppc64
-
 package ipv6
 
 const (
@@ -86,25 +84,30 @@ const (
        sysICMPV6_FILTER_BLOCKOTHERS = 0x3
        sysICMPV6_FILTER_PASSONLY    = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6         = 0x1c
-       sysSizeofInet6Pktinfo          = 0x14
-       sysSizeofIPv6Mtuinfo           = 0x20
-       sysSizeofIPv6FlowlabelReq      = 0x20
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet6         = 0x1c
+       sizeofInet6Pktinfo          = 0x14
+       sizeofIPv6Mtuinfo           = 0x20
+       sizeofIPv6FlowlabelReq      = 0x20
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Family   uint16
        Port     uint16
        Flowinfo uint32
@@ -112,17 +115,17 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex int32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6FlowlabelReq struct {
+type ipv6FlowlabelReq struct {
        Dst        [16]byte /* in6_addr */
        Label      uint32
        Action     uint8
@@ -133,24 +136,37 @@ type sysIPv6FlowlabelReq struct {
        X__flr_pad uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Ifindex   int32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Data [8]uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index 992b56e2ed799d6fe125298a07c86d7bde601c5a..b64f0157d7a45ada2145c55b5a0a6cf38e9bfda0 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_linux.go
 
-// +build linux,ppc64le
-
 package ipv6
 
 const (
@@ -86,25 +84,30 @@ const (
        sysICMPV6_FILTER_BLOCKOTHERS = 0x3
        sysICMPV6_FILTER_PASSONLY    = 0x4
 
-       sysSizeofKernelSockaddrStorage = 0x80
-       sysSizeofSockaddrInet6         = 0x1c
-       sysSizeofInet6Pktinfo          = 0x14
-       sysSizeofIPv6Mtuinfo           = 0x20
-       sysSizeofIPv6FlowlabelReq      = 0x20
+       sysSOL_SOCKET       = 0x1
+       sysSO_ATTACH_FILTER = 0x1a
+
+       sizeofKernelSockaddrStorage = 0x80
+       sizeofSockaddrInet6         = 0x1c
+       sizeofInet6Pktinfo          = 0x14
+       sizeofIPv6Mtuinfo           = 0x20
+       sizeofIPv6FlowlabelReq      = 0x20
 
-       sysSizeofIPv6Mreq       = 0x14
-       sysSizeofGroupReq       = 0x88
-       sysSizeofGroupSourceReq = 0x108
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x88
+       sizeofGroupSourceReq = 0x108
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
+
+       sizeofSockFprog = 0x10
 )
 
-type sysKernelSockaddrStorage struct {
+type kernelSockaddrStorage struct {
        Family  uint16
        X__data [126]int8
 }
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Family   uint16
        Port     uint16
        Flowinfo uint32
@@ -112,17 +115,17 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex int32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6FlowlabelReq struct {
+type ipv6FlowlabelReq struct {
        Dst        [16]byte /* in6_addr */
        Label      uint32
        Action     uint8
@@ -133,24 +136,37 @@ type sysIPv6FlowlabelReq struct {
        X__flr_pad uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Ifindex   int32
 }
 
-type sysGroupReq struct {
+type groupReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
 }
 
-type sysGroupSourceReq struct {
+type groupSourceReq struct {
        Interface uint32
        Pad_cgo_0 [4]byte
-       Group     sysKernelSockaddrStorage
-       Source    sysKernelSockaddrStorage
+       Group     kernelSockaddrStorage
+       Source    kernelSockaddrStorage
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Data [8]uint32
 }
+
+type sockFProg struct {
+       Len       uint16
+       Pad_cgo_0 [6]byte
+       Filter    *sockFilter
+}
+
+type sockFilter struct {
+       Code uint16
+       Jt   uint8
+       Jf   uint8
+       K    uint32
+}
index d6ec88e39b7577af6499a443a52cbc433775f938..bcada13b7a7fc809b25693168758e6d7aa28a756 100644 (file)
@@ -46,16 +46,16 @@ const (
        sysIPV6_PORTRANGE_HIGH    = 0x1
        sysIPV6_PORTRANGE_LOW     = 0x2
 
-       sysSizeofSockaddrInet6 = 0x1c
-       sysSizeofInet6Pktinfo  = 0x14
-       sysSizeofIPv6Mtuinfo   = 0x20
+       sizeofSockaddrInet6 = 0x1c
+       sizeofInet6Pktinfo  = 0x14
+       sizeofIPv6Mtuinfo   = 0x20
 
-       sysSizeofIPv6Mreq = 0x14
+       sizeofIPv6Mreq = 0x14
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
 )
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Len      uint8
        Family   uint8
        Port     uint16
@@ -64,21 +64,21 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex uint32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Interface uint32
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Filt [8]uint32
 }
index 3e080b78aad15ce634da0bf3580ce7d9fbd8a50f..86cf3c63799e626ba8a7601d0f7b14203e70ab56 100644 (file)
@@ -55,16 +55,16 @@ const (
        sysIPV6_PORTRANGE_HIGH    = 0x1
        sysIPV6_PORTRANGE_LOW     = 0x2
 
-       sysSizeofSockaddrInet6 = 0x1c
-       sysSizeofInet6Pktinfo  = 0x14
-       sysSizeofIPv6Mtuinfo   = 0x20
+       sizeofSockaddrInet6 = 0x1c
+       sizeofInet6Pktinfo  = 0x14
+       sizeofIPv6Mtuinfo   = 0x20
 
-       sysSizeofIPv6Mreq = 0x14
+       sizeofIPv6Mreq = 0x14
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
 )
 
-type sysSockaddrInet6 struct {
+type sockaddrInet6 struct {
        Len      uint8
        Family   uint8
        Port     uint16
@@ -73,21 +73,21 @@ type sysSockaddrInet6 struct {
        Scope_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex uint32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Interface uint32
 }
 
-type sysICMPv6Filter struct {
+type icmpv6Filter struct {
        Filt [8]uint32
 }
index cdf00c25d911035d7ad2249e84bb0ab4794d70a3..cf1837dd2af638a0a40526d3a0b175af8e13ebbe 100644 (file)
@@ -1,8 +1,6 @@
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs defs_solaris.go
 
-// +build solaris
-
 package ipv6
 
 const (
@@ -44,6 +42,13 @@ const (
 
        sysIPV6_RECVDSTOPTS = 0x28
 
+       sysMCAST_JOIN_GROUP         = 0x29
+       sysMCAST_LEAVE_GROUP        = 0x2a
+       sysMCAST_BLOCK_SOURCE       = 0x2b
+       sysMCAST_UNBLOCK_SOURCE     = 0x2c
+       sysMCAST_JOIN_SOURCE_GROUP  = 0x2d
+       sysMCAST_LEAVE_SOURCE_GROUP = 0x2e
+
        sysIPV6_PREFER_SRC_HOME   = 0x1
        sysIPV6_PREFER_SRC_COA    = 0x2
        sysIPV6_PREFER_SRC_PUBLIC = 0x4
@@ -67,16 +72,26 @@ const (
 
        sysICMP6_FILTER = 0x1
 
-       sysSizeofSockaddrInet6 = 0x20
-       sysSizeofInet6Pktinfo  = 0x14
-       sysSizeofIPv6Mtuinfo   = 0x24
+       sizeofSockaddrStorage = 0x100
+       sizeofSockaddrInet6   = 0x20
+       sizeofInet6Pktinfo    = 0x14
+       sizeofIPv6Mtuinfo     = 0x24
 
-       sysSizeofIPv6Mreq = 0x14
+       sizeofIPv6Mreq       = 0x14
+       sizeofGroupReq       = 0x104
+       sizeofGroupSourceReq = 0x204
 
-       sysSizeofICMPv6Filter = 0x20
+       sizeofICMPv6Filter = 0x20
 )
 
-type sysSockaddrInet6 struct {
+type sockaddrStorage struct {
+       Family     uint16
+       X_ss_pad1  [6]int8
+       X_ss_align float64
+       X_ss_pad2  [240]int8
+}
+
+type sockaddrInet6 struct {
        Family         uint16
        Port           uint16
        Flowinfo       uint32
@@ -85,21 +100,32 @@ type sysSockaddrInet6 struct {
        X__sin6_src_id uint32
 }
 
-type sysInet6Pktinfo struct {
+type inet6Pktinfo struct {
        Addr    [16]byte /* in6_addr */
        Ifindex uint32
 }
 
-type sysIPv6Mtuinfo struct {
-       Addr sysSockaddrInet6
+type ipv6Mtuinfo struct {
+       Addr sockaddrInet6
        Mtu  uint32
 }
 
-type sysIPv6Mreq struct {
+type ipv6Mreq struct {
        Multiaddr [16]byte /* in6_addr */
        Interface uint32
 }
 
-type sysICMPv6Filter struct {
+type groupReq struct {
+       Interface uint32
+       Pad_cgo_0 [256]byte
+}
+
+type groupSourceReq struct {
+       Interface uint32
+       Pad_cgo_0 [256]byte
+       Pad_cgo_1 [256]byte
+}
+
+type icmpv6Filter struct {
        X__icmp6_filt [8]uint32
 }
index 49542d316196642303ae01cac4c0684799c6cd41..cd4edeb6ba3b71504c6e3467ad7bf7ce0fbafa88 100644 (file)
@@ -581,7 +581,7 @@ Consider the case that you needed to read a local database or a file to
 provide suggestions. You can dynamically generate the options
 
 ```
-func listHosts(args []string) []string {
+func listHosts() []string {
   // Provide a dynamic list of hosts from a hosts file or otherwise
   // for bash completion. In this example we simply return static slice.
 
index 80e1f0bff19dd0faba4be3331070caa9884e4319..efa198af7d82d52c62c76b40511401c7ec935f83 100644 (file)
@@ -216,11 +216,9 @@ func (p *ParseContext) Next() *Token {
                        return &Token{p.argi, TokenError, err.Error()}
                }
                if len(p.args) == 0 {
-                       p.args = append(p.args, expanded...)
-               } else if p.argi >= len(p.args) {
-                       p.args = append(p.args[:p.argi-1], expanded...)
+                       p.args = expanded
                } else {
-                       p.args = append(p.args[:p.argi-1], append(expanded, p.args[p.argi+1:]...)...)
+                       p.args = append(expanded, p.args...)
                }
                return p.Next()
        }
index 602cfc9ba969dc6766e58fe68763d5b3e448a369..8d492bf9ceb913cd1ad5022a8a3029daa7e3e1a5 100644 (file)
@@ -28,7 +28,7 @@ func (f *boolValue) Set(s string) error {
 
 func (f *boolValue) Get() interface{} { return (bool)(*f.v) }
 
-func (f *boolValue) String() string { return fmt.Sprintf("%v", *f) }
+func (f *boolValue) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Bool parses the next command-line value as bool.
 func (p *parserMixin) Bool() (target *bool) {
@@ -114,7 +114,7 @@ func (f *uintValue) Set(s string) error {
 
 func (f *uintValue) Get() interface{} { return (uint)(*f.v) }
 
-func (f *uintValue) String() string { return fmt.Sprintf("%v", *f) }
+func (f *uintValue) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Uint parses the next command-line value as uint.
 func (p *parserMixin) Uint() (target *uint) {
@@ -157,7 +157,7 @@ func (f *uint8Value) Set(s string) error {
 
 func (f *uint8Value) Get() interface{} { return (uint8)(*f.v) }
 
-func (f *uint8Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *uint8Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Uint8 parses the next command-line value as uint8.
 func (p *parserMixin) Uint8() (target *uint8) {
@@ -200,7 +200,7 @@ func (f *uint16Value) Set(s string) error {
 
 func (f *uint16Value) Get() interface{} { return (uint16)(*f.v) }
 
-func (f *uint16Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *uint16Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Uint16 parses the next command-line value as uint16.
 func (p *parserMixin) Uint16() (target *uint16) {
@@ -243,7 +243,7 @@ func (f *uint32Value) Set(s string) error {
 
 func (f *uint32Value) Get() interface{} { return (uint32)(*f.v) }
 
-func (f *uint32Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *uint32Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Uint32 parses the next command-line value as uint32.
 func (p *parserMixin) Uint32() (target *uint32) {
@@ -286,7 +286,7 @@ func (f *uint64Value) Set(s string) error {
 
 func (f *uint64Value) Get() interface{} { return (uint64)(*f.v) }
 
-func (f *uint64Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *uint64Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Uint64 parses the next command-line value as uint64.
 func (p *parserMixin) Uint64() (target *uint64) {
@@ -329,7 +329,7 @@ func (f *intValue) Set(s string) error {
 
 func (f *intValue) Get() interface{} { return (int)(*f.v) }
 
-func (f *intValue) String() string { return fmt.Sprintf("%v", *f) }
+func (f *intValue) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Int parses the next command-line value as int.
 func (p *parserMixin) Int() (target *int) {
@@ -372,7 +372,7 @@ func (f *int8Value) Set(s string) error {
 
 func (f *int8Value) Get() interface{} { return (int8)(*f.v) }
 
-func (f *int8Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *int8Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Int8 parses the next command-line value as int8.
 func (p *parserMixin) Int8() (target *int8) {
@@ -415,7 +415,7 @@ func (f *int16Value) Set(s string) error {
 
 func (f *int16Value) Get() interface{} { return (int16)(*f.v) }
 
-func (f *int16Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *int16Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Int16 parses the next command-line value as int16.
 func (p *parserMixin) Int16() (target *int16) {
@@ -458,7 +458,7 @@ func (f *int32Value) Set(s string) error {
 
 func (f *int32Value) Get() interface{} { return (int32)(*f.v) }
 
-func (f *int32Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *int32Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Int32 parses the next command-line value as int32.
 func (p *parserMixin) Int32() (target *int32) {
@@ -501,7 +501,7 @@ func (f *int64Value) Set(s string) error {
 
 func (f *int64Value) Get() interface{} { return (int64)(*f.v) }
 
-func (f *int64Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *int64Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Int64 parses the next command-line value as int64.
 func (p *parserMixin) Int64() (target *int64) {
@@ -544,7 +544,7 @@ func (f *float64Value) Set(s string) error {
 
 func (f *float64Value) Get() interface{} { return (float64)(*f.v) }
 
-func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *float64Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Float64 parses the next command-line value as float64.
 func (p *parserMixin) Float64() (target *float64) {
@@ -587,7 +587,7 @@ func (f *float32Value) Set(s string) error {
 
 func (f *float32Value) Get() interface{} { return (float32)(*f.v) }
 
-func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) }
+func (f *float32Value) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Float32 parses the next command-line value as float32.
 func (p *parserMixin) Float32() (target *float32) {
@@ -708,7 +708,7 @@ func (f *regexpValue) Set(s string) error {
 
 func (f *regexpValue) Get() interface{} { return (*regexp.Regexp)(*f.v) }
 
-func (f *regexpValue) String() string { return fmt.Sprintf("%v", *f) }
+func (f *regexpValue) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Regexp parses the next command-line value as *regexp.Regexp.
 func (p *parserMixin) Regexp() (target **regexp.Regexp) {
@@ -751,7 +751,7 @@ func (f *resolvedIPValue) Set(s string) error {
 
 func (f *resolvedIPValue) Get() interface{} { return (net.IP)(*f.v) }
 
-func (f *resolvedIPValue) String() string { return fmt.Sprintf("%v", *f) }
+func (f *resolvedIPValue) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Resolve a hostname or IP to an IP.
 func (p *parserMixin) ResolvedIP() (target *net.IP) {
@@ -794,7 +794,7 @@ func (f *hexBytesValue) Set(s string) error {
 
 func (f *hexBytesValue) Get() interface{} { return ([]byte)(*f.v) }
 
-func (f *hexBytesValue) String() string { return fmt.Sprintf("%v", *f) }
+func (f *hexBytesValue) String() string { return fmt.Sprintf("%v", *f.v) }
 
 // Bytes as a hex string.
 func (p *parserMixin) HexBytes() (target *[]byte) {
index a68e67f01b0cbbebb44224df30471217ee6ecdd1..8dada3edaf50dbc082c9a125058f25def75e625a 100644 (file)
-
-Copyright (c) 2011-2014 - Canonical Inc.
-
-This software is licensed under the LGPLv3, included below.
-
-As a special exception to the GNU Lesser General Public License version 3
-("LGPL3"), the copyright holders of this Library give you permission to
-convey to a third party a Combined Work that links statically or dynamically
-to this Library without providing any Minimal Corresponding Source or
-Minimal Application Code as set out in 4d or providing the installation
-information set out in section 4e, provided that you comply with the other
-provisions of LGPL3 and provided that you meet, for the Application the
-terms and conditions of the license(s) which apply to the Application.
-
-Except as stated in this special exception, the provisions of LGPL3 will
-continue to comply in full to this Library. If you modify this Library, you
-may apply this exception to your version of this Library, but you are not
-obliged to do so. If you do not wish to do so, delete this exception
-statement from your version. This exception does not (and cannot) modify any
-license terms which apply to the Application, with which you must still
-comply.
-
-
-                   GNU LESSER GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
-  This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
-  0. Additional Definitions.
-
-  As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
-  "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
-  An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
-  A "Combined Work" is a work produced by combining or linking an
-Application with the Library.  The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
-  The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
-  The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
-  1. Exception to Section 3 of the GNU GPL.
-
-  You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
-  2. Conveying Modified Versions.
-
-  If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
-   a) under this License, provided that you make a good faith effort to
-   ensure that, in the event an Application does not supply the
-   function or data, the facility still operates, and performs
-   whatever part of its purpose remains meaningful, or
-
-   b) under the GNU GPL, with none of the additional permissions of
-   this License applicable to that copy.
-
-  3. Object Code Incorporating Material from Library Header Files.
-
-  The object code form of an Application may incorporate material from
-a header file that is part of the Library.  You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
-   a) Give prominent notice with each copy of the object code that the
-   Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the object code with a copy of the GNU GPL and this license
-   document.
-
-  4. Combined Works.
-
-  You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
-   a) Give prominent notice with each copy of the Combined Work that
-   the Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the Combined Work with a copy of the GNU GPL and this license
-   document.
-
-   c) For a Combined Work that displays copyright notices during
-   execution, include the copyright notice for the Library among
-   these notices, as well as a reference directing the user to the
-   copies of the GNU GPL and this license document.
-
-   d) Do one of the following:
-
-       0) Convey the Minimal Corresponding Source under the terms of this
-       License, and the Corresponding Application Code in a form
-       suitable for, and under terms that permit, the user to
-       recombine or relink the Application with a modified version of
-       the Linked Version to produce a modified Combined Work, in the
-       manner specified by section 6 of the GNU GPL for conveying
-       Corresponding Source.
-
-       1) Use a suitable shared library mechanism for linking with the
-       Library.  A suitable mechanism is one that (a) uses at run time
-       a copy of the Library already present on the user's computer
-       system, and (b) will operate properly with a modified version
-       of the Library that is interface-compatible with the Linked
-       Version.
-
-   e) Provide Installation Information, but only if you would otherwise
-   be required to provide such information under section 6 of the
-   GNU GPL, and only to the extent that such information is
-   necessary to install and execute a modified version of the
-   Combined Work produced by recombining or relinking the
-   Application with a modified version of the Linked Version. (If
-   you use option 4d0, the Installation Information must accompany
-   the Minimal Corresponding Source and Corresponding Application
-   Code. If you use option 4d1, you must provide the Installation
-   Information in the manner specified by section 6 of the GNU GPL
-   for conveying Corresponding Source.)
-
-  5. Combined Libraries.
-
-  You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
-   a) Accompany the combined library with a copy of the same work based
-   on the Library, uncombined with any other library facilities,
-   conveyed under the terms of this License.
-
-   b) Give prominent notice with the combined library that part of it
-   is a work based on the Library, and explaining where to find the
-   accompanying uncombined form of the same work.
-
-  6. Revised Versions of the GNU Lesser General Public License.
-
-  The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
-  Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
-  If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
index 7b8bd86701e3279d3a924ce3371acb3dcfd35b3b..7a512d67c2b92474831c563a4d48ce06506936f2 100644 (file)
@@ -42,12 +42,14 @@ The package API for yaml v2 will remain stable as described in [gopkg.in](https:
 License
 -------
 
-The yaml package is licensed under the LGPL with an exception that allows it to be linked statically. Please see the LICENSE file for details.
+The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.
 
 
 Example
 -------
 
+Some more examples can be found in the "examples" folder.
+
 ```Go
 package main
 
index 085cddc44beb962ede8bcf965cd99ab3110916cd..db1f5f20686f21c533109bb772d9394f61d2ba56 100644 (file)
@@ -120,7 +120,6 @@ func (p *parser) parse() *node {
        default:
                panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
        }
-       panic("unreachable")
 }
 
 func (p *parser) node(kind int) *node {
@@ -191,6 +190,7 @@ type decoder struct {
        aliases map[string]bool
        mapType reflect.Type
        terrors []string
+       strict  bool
 }
 
 var (
@@ -200,8 +200,8 @@ var (
        ifaceType      = defaultMapType.Elem()
 )
 
-func newDecoder() *decoder {
-       d := &decoder{mapType: defaultMapType}
+func newDecoder(strict bool) *decoder {
+       d := &decoder{mapType: defaultMapType, strict: strict}
        d.aliases = make(map[string]bool)
        return d
 }
@@ -251,7 +251,7 @@ func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
 //
 // If n holds a null value, prepare returns before doing anything.
 func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
-       if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "") {
+       if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "" && n.implicit) {
                return out, false, false
        }
        again := true
@@ -640,6 +640,8 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
                        value := reflect.New(elemType).Elem()
                        d.unmarshal(n.children[i+1], value)
                        inlineMap.SetMapIndex(name, value)
+               } else if d.strict {
+                       d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in struct %s", n.line+1, name.String(), out.Type()))
                }
        }
        return true
index 2befd553ed0263a2bb85819e344e244014dfadc9..41de8b856c2fef5982a8a3e94b2f8c79411501ae 100644 (file)
@@ -666,7 +666,6 @@ func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
                return yaml_emitter_set_emitter_error(emitter,
                        "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
        }
-       return false
 }
 
 // Expect ALIAS.
@@ -995,7 +994,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
                break_space    = false
                space_break    = false
 
-               preceeded_by_whitespace = false
+               preceded_by_whitespace = false
                followed_by_whitespace  = false
                previous_space          = false
                previous_break          = false
@@ -1017,7 +1016,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
                flow_indicators = true
        }
 
-       preceeded_by_whitespace = true
+       preceded_by_whitespace = true
        for i, w := 0, 0; i < len(value); i += w {
                w = width(value[i])
                followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
@@ -1048,7 +1047,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
                                        block_indicators = true
                                }
                        case '#':
-                               if preceeded_by_whitespace {
+                               if preceded_by_whitespace {
                                        flow_indicators = true
                                        block_indicators = true
                                }
@@ -1089,7 +1088,7 @@ func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
                }
 
                // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
-               preceeded_by_whitespace = is_blankz(value, i)
+               preceded_by_whitespace = is_blankz(value, i)
        }
 
        emitter.scalar_data.multiline = line_breaks
index 0a7037ad1b2a6c352b7250278daf2feb9bb23a42..81d05dfe573f920d4687ddfd2a9ccb371da7ba81 100644 (file)
@@ -166,7 +166,6 @@ func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool
        default:
                panic("invalid parser state")
        }
-       return false
 }
 
 // Parse the production:
index 93a86327434b94e457b3871f7dc6ab6bccdb4630..232313cc084556256505313a1c4eafae1fbd719b 100644 (file)
@@ -3,6 +3,7 @@ package yaml
 import (
        "encoding/base64"
        "math"
+       "regexp"
        "strconv"
        "strings"
        "unicode/utf8"
@@ -80,6 +81,8 @@ func resolvableTag(tag string) bool {
        return false
 }
 
+var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`)
+
 func resolve(tag string, in string) (rtag string, out interface{}) {
        if !resolvableTag(tag) {
                return tag, in
@@ -135,9 +138,11 @@ func resolve(tag string, in string) (rtag string, out interface{}) {
                        if err == nil {
                                return yaml_INT_TAG, uintv
                        }
-                       floatv, err := strconv.ParseFloat(plain, 64)
-                       if err == nil {
-                               return yaml_FLOAT_TAG, floatv
+                       if yamlStyleFloat.MatchString(plain) {
+                               floatv, err := strconv.ParseFloat(plain, 64)
+                               if err == nil {
+                                       return yaml_FLOAT_TAG, floatv
+                               }
                        }
                        if strings.HasPrefix(plain, "0b") {
                                intv, err := strconv.ParseInt(plain[2:], 2, 64)
index 25808000f28f7971a7bef97530fa5eec5181abed..074484455827e62b9e9352ed25a7a14ba69e907e 100644 (file)
@@ -9,7 +9,7 @@ import (
 // ************
 //
 // The following notes assume that you are familiar with the YAML specification
-// (http://yaml.org/spec/cvs/current.html).  We mostly follow it, although in
+// (http://yaml.org/spec/1.2/spec.html).  We mostly follow it, although in
 // some cases we are less restrictive that it requires.
 //
 // The process of transforming a YAML stream into a sequence of events is
@@ -611,7 +611,7 @@ func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, co
        if directive {
                context = "while parsing a %TAG directive"
        }
-       return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
+       return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
 }
 
 func trace(args ...interface{}) func() {
@@ -1944,7 +1944,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
        } else {
                // It's either the '!' tag or not really a tag handle.  If it's a %TAG
                // directive, it's an error.  If it's a tag token, it must be a part of URI.
-               if directive && !(s[0] == '!' && s[1] == 0) {
+               if directive && string(s) != "!" {
                        yaml_parser_set_scanner_tag_error(parser, directive,
                                start_mark, "did not find expected '!'")
                        return false
@@ -1959,6 +1959,7 @@ func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_ma
 func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
        //size_t length = head ? strlen((char *)head) : 0
        var s []byte
+       hasTag := len(head) > 0
 
        // Copy the head if needed.
        //
@@ -2000,10 +2001,10 @@ func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte
                if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
                        return false
                }
+               hasTag = true
        }
 
-       // Check if the tag is non-empty.
-       if len(s) == 0 {
+       if !hasTag {
                yaml_parser_set_scanner_tag_error(parser, directive,
                        start_mark, "did not find expected tag URI")
                return false
index 36d6b883a6c0ba97ce3f7fe5d1c5c50ed345d390..bf18884e0e3ae3921a6ebc2ca1c20056a90de603 100644 (file)
@@ -77,8 +77,19 @@ type Marshaler interface {
 // supported tag options.
 //
 func Unmarshal(in []byte, out interface{}) (err error) {
+       return unmarshal(in, out, false)
+}
+
+// UnmarshalStrict is like Unmarshal except that any fields that are found
+// in the data that do not have corresponding struct members will result in
+// an error.
+func UnmarshalStrict(in []byte, out interface{}) (err error) {
+       return unmarshal(in, out, true)
+}
+
+func unmarshal(in []byte, out interface{}, strict bool) (err error) {
        defer handleErr(&err)
-       d := newDecoder()
+       d := newDecoder(strict)
        p := newParser(in)
        defer p.destroy()
        node := p.parse()
index d60a6b6b0035bec3773f023680b38cd3dbec93d0..3caeca0491b59ac53bf2b48f76256a9bc3e412eb 100644 (file)
@@ -508,7 +508,7 @@ type yaml_parser_t struct {
 
        problem string // Error description.
 
-       // The byte about which the problem occured.
+       // The byte about which the problem occurred.
        problem_offset int
        problem_value  int
        problem_mark   yaml_mark_t
index 4503bb8c65e9ba04d77af516f8a68848ae1dfd43..486166d7f9ebb298f457f293b13ac861015521db 100644 (file)
                        "revisionTime": "2015-10-22T06:55:26Z"
                },
                {
-                       "checksumSHA1": "4QnLdmB1kG3N+KlDd1N+G9TWAGQ=",
+                       "checksumSHA1": "spyv5/YFBjYyZLZa1U2LBfDR8PM=",
                        "path": "github.com/beorn7/perks/quantile",
-                       "revision": "3ac7bf7a47d159a033b107610db8a1b6575507a4",
-                       "revisionTime": "2016-02-29T22:34:45+01:00"
+                       "revision": "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9",
+                       "revisionTime": "2016-08-04T10:47:26Z"
                },
                {
-                       "checksumSHA1": "bzCBeQrZ+LxbYyJbp7uDILX6t7c=",
+                       "checksumSHA1": "KrIRJ4p3nRze4NcxfgX5+N9+D1M=",
                        "path": "github.com/go-kit/kit/log",
-                       "revision": "bc4df5b6d8156c977195a8b9637ecea5f1187a0d",
-                       "revisionTime": "2017-04-20T00:59:06Z"
+                       "revision": "0d313fb5fb3a94d87d61e6434785264e87a5d740",
+                       "revisionTime": "2017-09-17T20:27:34Z"
                },
                {
                        "checksumSHA1": "t7aTpDH0h4BZcGU0KkUr14QQG2w=",
                        "path": "github.com/go-kit/kit/log/level",
-                       "revision": "bc4df5b6d8156c977195a8b9637ecea5f1187a0d",
-                       "revisionTime": "2017-04-20T00:59:06Z"
+                       "revision": "0d313fb5fb3a94d87d61e6434785264e87a5d740",
+                       "revisionTime": "2017-09-17T20:27:34Z"
                },
                {
                        "checksumSHA1": "KxX/Drph+byPXBFIXaCZaCOAnrU=",
                        "revisionTime": "2016-11-15T14:25:13Z"
                },
                {
-                       "checksumSHA1": "2sj/DbXoXdnPAfjAEyhS0Jj5QL0=",
+                       "checksumSHA1": "j6vhe49MX+dyHR9rU91P6vMx55o=",
                        "path": "github.com/go-stack/stack",
-                       "revision": "100eb0c0a9c5b306ca2fb4f165df21d80ada4b82",
-                       "revisionTime": "2016-05-14T03:44:11Z"
+                       "revision": "817915b46b97fd7bb80e8ab6b69f01a53ac3eebf",
+                       "revisionTime": "2017-07-24T01:23:01Z"
                },
                {
-                       "checksumSHA1": "UQtJP2n/HEBhHaq6a9R2hCHgy+8=",
+                       "checksumSHA1": "yqF125xVSkmfLpIVGrLlfE05IUk=",
                        "path": "github.com/golang/protobuf/proto",
-                       "revision": "8d92cf5fc15a4382f8964b08e1f42a75c0591aa3",
-                       "revisionTime": "2016-03-19T05:57:00+11:00"
+                       "revision": "ae59567b9aab61b50b2590679a62c3c044030b61",
+                       "revisionTime": "2017-09-19T00:21:09Z"
                },
                {
                        "checksumSHA1": "abKzFXAn0KDr5U+JON1ZgJ2lUtU=",
                        "revisionTime": "2016-04-24T11:30:07Z"
                },
                {
-                       "checksumSHA1": "Y89CHl2URaBbobeyCOr4kzbLwYE=",
+                       "checksumSHA1": "Ewgc6lPiuDZVOf1407rxzSgAOag=",
                        "path": "github.com/miekg/dns",
-                       "revision": "5d001d020961ae1c184f9f8152fdc73810481677",
-                       "revisionTime": "2016-06-14T16:21:01Z"
+                       "revision": "e4205768578dc90c2669e75a2f8a8bf77e3083a4",
+                       "revisionTime": "2017-08-18T13:14:42Z"
                },
                {
-                       "checksumSHA1": "ynJSWoF6v+3zMnh9R0QmmG6iGV8=",
+                       "checksumSHA1": "rJab1YdNhQooDiBWNnt7TLWPyBU=",
                        "path": "github.com/pkg/errors",
-                       "revision": "ff09b135c25aae272398c51a07235b90a75aa4f0",
-                       "revisionTime": "2017-03-16T20:15:38Z"
+                       "revision": "2b3a18b5f0fb6b4f9190549597d3f962c02bc5eb",
+                       "revisionTime": "2017-09-10T13:46:14Z"
                },
                {
-                       "checksumSHA1": "X5E2qzbDix710dxoN9Qu0qeHGqU=",
+                       "checksumSHA1": "ty3Y0hPtRphsqcykY9ihV6F02Fk=",
                        "path": "github.com/prometheus/client_golang/prometheus",
-                       "revision": "7d9484283ebefa862b5b7727d4344cfdf9a0d138",
-                       "revisionTime": "2017-04-25T21:35:58Z"
+                       "revision": "50b3332fd63be43e38472600ec187ceec39d26d6",
+                       "revisionTime": "2017-09-13T10:48:29Z"
                },
                {
-                       "checksumSHA1": "tqpiUpHWFso3wcHDAPXoEhT2CoM=",
+                       "checksumSHA1": "wsAkYlRRUNx+OAuUOIqdjO7dICM=",
                        "path": "github.com/prometheus/client_golang/prometheus/promhttp",
-                       "revision": "7d9484283ebefa862b5b7727d4344cfdf9a0d138",
-                       "revisionTime": "2017-04-25T21:35:58Z"
+                       "revision": "50b3332fd63be43e38472600ec187ceec39d26d6",
+                       "revisionTime": "2017-09-13T10:48:29Z"
                },
                {
                        "checksumSHA1": "DvwvOlPNAgRntBzt3b3OSRMS2N4=",
                        "path": "github.com/prometheus/client_model/go",
-                       "revision": "fa8ad6fec33561be4280a8f0514318c79d7f6cb6",
-                       "revisionTime": "2015-02-12T10:17:44Z"
+                       "revision": "6f3806018612930941127f2a7c6c453ba2c527d2",
+                       "revisionTime": "2017-02-16T18:52:47Z"
                },
                {
                        "checksumSHA1": "4TLgSCgJZuS5gtytxNvcVk4h8/g=",
                        "path": "github.com/prometheus/common/config",
-                       "revision": "bc8b88226a1210b016e9993b1d75f858c9c8f778",
-                       "revisionTime": "2017-08-30T19:05:55Z"
+                       "revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
+                       "revisionTime": "2017-09-08T16:18:22Z"
                },
                {
                        "checksumSHA1": "xfnn0THnqNwjwimeTClsxahYrIo=",
                        "path": "github.com/prometheus/common/expfmt",
-                       "revision": "bc8b88226a1210b016e9993b1d75f858c9c8f778",
-                       "revisionTime": "2017-08-30T19:05:55Z"
+                       "revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
+                       "revisionTime": "2017-09-08T16:18:22Z"
                },
                {
                        "checksumSHA1": "GWlM3d2vPYyNATtTFgftS10/A9w=",
                        "path": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
-                       "revision": "bc8b88226a1210b016e9993b1d75f858c9c8f778",
-                       "revisionTime": "2017-08-30T19:05:55Z"
+                       "revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
+                       "revisionTime": "2017-09-08T16:18:22Z"
                },
                {
                        "checksumSHA1": "3VoqH7TFfzA6Ds0zFzIbKCUvBmw=",
                        "path": "github.com/prometheus/common/model",
-                       "revision": "bc8b88226a1210b016e9993b1d75f858c9c8f778",
-                       "revisionTime": "2017-08-30T19:05:55Z"
+                       "revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
+                       "revisionTime": "2017-09-08T16:18:22Z"
                },
                {
-                       "checksumSHA1": "Nj8QI/QKAWEY8F5d0h/kdxzh4SM=",
+                       "checksumSHA1": "Yseprf8kAFr/s7wztkQnrFuFN+8=",
                        "path": "github.com/prometheus/common/promlog",
-                       "revision": "bc8b88226a1210b016e9993b1d75f858c9c8f778",
-                       "revisionTime": "2017-08-30T19:05:55Z"
+                       "revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
+                       "revisionTime": "2017-09-08T16:18:22Z"
                },
                {
                        "checksumSHA1": "1H28FCxsaAIm6kvue+Wfdd8Lq6M=",
                        "path": "github.com/prometheus/common/promlog/flag",
-                       "revision": "bc8b88226a1210b016e9993b1d75f858c9c8f778",
-                       "revisionTime": "2017-08-30T19:05:55Z"
+                       "revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
+                       "revisionTime": "2017-09-08T16:18:22Z"
                },
                {
                        "checksumSHA1": "91KYK0SpvkaMJJA2+BcxbVnyRO0=",
                        "path": "github.com/prometheus/common/version",
-                       "revision": "bc8b88226a1210b016e9993b1d75f858c9c8f778",
-                       "revisionTime": "2017-08-30T19:05:55Z"
+                       "revision": "2f17f4a9d485bf34b4bfaccc273805040e4f86c8",
+                       "revisionTime": "2017-09-08T16:18:22Z"
                },
                {
-                       "checksumSHA1": "kO2MAzPuortudABaRd7fY+7EaoM=",
+                       "checksumSHA1": "ihxJIjxtbEYdQKwA0D0nRipj95I=",
                        "path": "github.com/prometheus/procfs",
-                       "revision": "406e5b7bfd8201a36e2bb5f7bdae0b03380c2ce8",
-                       "revisionTime": "2015-10-29T15:50:50-04:00"
+                       "revision": "e645f4e5aaa8506fc71d6edbc5c4ff02c04c46f2",
+                       "revisionTime": "2017-07-03T10:12:42Z"
                },
                {
-                       "checksumSHA1": "11zFB6NFMfY7R7pwOhDCurgIjJY=",
+                       "checksumSHA1": "xCiFAAwVTrjsfZT1BIJQ3DgeNCY=",
+                       "path": "github.com/prometheus/procfs/xfs",
+                       "revision": "e645f4e5aaa8506fc71d6edbc5c4ff02c04c46f2",
+                       "revisionTime": "2017-07-03T10:12:42Z"
+               },
+               {
+                       "checksumSHA1": "uX2McdP4VcQ6zkAF0Q4oyd0rFtU=",
+                       "path": "golang.org/x/net/bpf",
+                       "revision": "8351a756f30f1297fe94bbf4b767ec589c6ea6d0",
+                       "revisionTime": "2017-09-15T01:39:56Z"
+               },
+               {
+                       "checksumSHA1": "DqdFGWbLLyVFeDvzvXyf1Y678uA=",
                        "path": "golang.org/x/net/icmp",
-                       "revision": "31df19d69da8728e9220def59b80ee577c3e48bf",
-                       "revisionTime": "2016-03-29T10:16:23+11:00"
+                       "revision": "8351a756f30f1297fe94bbf4b767ec589c6ea6d0",
+                       "revisionTime": "2017-09-15T01:39:56Z"
                },
                {
-                       "checksumSHA1": "yRuyntx9a59ugMi5NlN4ST0XRcI=",
+                       "checksumSHA1": "YoSf+PgTWvHmFVaF3MrtZz3kX38=",
                        "path": "golang.org/x/net/internal/iana",
-                       "revision": "31df19d69da8728e9220def59b80ee577c3e48bf",
-                       "revisionTime": "2016-03-29T10:16:23+11:00"
+                       "revision": "8351a756f30f1297fe94bbf4b767ec589c6ea6d0",
+                       "revisionTime": "2017-09-15T01:39:56Z"
+               },
+               {
+                       "checksumSHA1": "5eWwtQVHJ0Lp2/538Kve2KuE8gQ=",
+                       "path": "golang.org/x/net/internal/socket",
+                       "revision": "8351a756f30f1297fe94bbf4b767ec589c6ea6d0",
+                       "revisionTime": "2017-09-15T01:39:56Z"
                },
                {
-                       "checksumSHA1": "5Um0EwFCpweaWXfaslYqSfoWhV8=",
+                       "checksumSHA1": "ZGMENpNTj2hojdJMcrUO+UPKVgE=",
                        "path": "golang.org/x/net/ipv4",
-                       "revision": "31df19d69da8728e9220def59b80ee577c3e48bf",
-                       "revisionTime": "2016-03-29T10:16:23+11:00"
+                       "revision": "8351a756f30f1297fe94bbf4b767ec589c6ea6d0",
+                       "revisionTime": "2017-09-15T01:39:56Z"
                },
                {
-                       "checksumSHA1": "8iCMTIfuxZ2KU2dyb6hJmzm4CeA=",
+                       "checksumSHA1": "QUvByKIVmIy9c+8+O1XGyh9ynoY=",
                        "path": "golang.org/x/net/ipv6",
-                       "revision": "31df19d69da8728e9220def59b80ee577c3e48bf",
-                       "revisionTime": "2016-03-29T10:16:23+11:00"
+                       "revision": "8351a756f30f1297fe94bbf4b767ec589c6ea6d0",
+                       "revisionTime": "2017-09-15T01:39:56Z"
                },
                {
-                       "checksumSHA1": "ZvPW/nSYs/UeoZejaV2ZSm9+2Do=",
+                       "checksumSHA1": "3SZTatHIy9OTKc95YlVfXKnoySg=",
                        "path": "gopkg.in/alecthomas/kingpin.v2",
-                       "revision": "7f0871f2e17818990e4eed73f9b5c2f429501228",
-                       "revisionTime": "2017-03-28T23:38:35Z"
+                       "revision": "1087e65c9441605df944fb12c33f0fe7072d18ca",
+                       "revisionTime": "2017-07-27T04:22:29Z"
                },
                {
-                       "checksumSHA1": "+OgOXBoiQ+X+C2dsAeiOHwBIEH0=",
+                       "checksumSHA1": "RDJpJQwkF012L6m/2BJizyOksNw=",
                        "path": "gopkg.in/yaml.v2",
-                       "revision": "a83829b6f1293c91addabc89d0571c246397bbf4",
-                       "revisionTime": "2016-03-01T17:40:22-03:00"
+                       "revision": "eb3733d160e74a9c7e442f435eb3bea458e1d19f",
+                       "revisionTime": "2017-08-12T16:00:11Z"
                }
        ],
        "rootPath": "github.com/prometheus/blackbox_exporter"